UI: removed nuklear ui

Martin Gerhardy 2019-12-19 07:28:13 +01:00
parent 768c057ad4
commit 1fb662810e
24 changed files with 1 additions and 29994 deletions

View File

@ -273,6 +273,4 @@ macro(engine_update_git_lib)
endmacro()
engine_update_git_lib(LIB simplecpp URL "https://github.com/danmar/simplecpp.git" COPY simplecpp.cpp simplecpp.h)
engine_update_git_lib(LIB nuklear URL "https://github.com/danmar/simplecpp.git" COPY simplecpp.cpp simplecpp.h TARGETDIR ${ROOT_DIR}/src/modules/ui/nuklear/private)
# TODO cp $(UPDATEDIR)/nuklear.sync/demo/overview.c src/tests/testnuklear
engine_update_git_lib(LIB json URL "https://github.com/nlohmann/json.git" COPY single_include/nlohmann/json.hpp TARGETDIR ${ROOT_DIR}/src/modules/core)

View File

@ -144,11 +144,6 @@ update-glslang:
rm -rf src/tools/glslang/StandAlone
cp -r $(UPDATEDIR)/glslang.sync/StandAlone src/tools/glslang/
update-nuklear:
$(call UPDATE_GIT,nuklear,https://github.com/vurtun/nuklear.git)
cp $(UPDATEDIR)/nuklear.sync/nuklear.h src/modules/ui/nuklear/private
cp $(UPDATEDIR)/nuklear.sync/demo/overview.c src/tests/testnuklear
# currently not part of updatelibs - intentional - we adopted the original code.
update-simplexnoise:
$(call UPDATE_GIT,simplexnoise,https://github.com/simongeilfus/SimplexNoise.git)
@ -167,7 +162,7 @@ update-curl:
# TODO native file dialog support
# TODO simpleai support
# TODO lua support
updatelibs: update-nuklear update-restclient-cpp update-libuv update-stb update-googletest update-benchmark update-backward update-dearimgui update-flatbuffers update-enet update-glm update-sdl2 update-curl update-glslang
updatelibs: update-restclient-cpp update-libuv update-stb update-googletest update-benchmark update-backward update-dearimgui update-flatbuffers update-enet update-glm update-sdl2 update-curl update-glslang
$(MAKE) -C $(BUILDDIR) update-libs
windows:

View File

@ -1,3 +1,2 @@
add_subdirectory(imgui)
add_subdirectory(turbobadger)
add_subdirectory(nuklear)

View File

@ -1,15 +0,0 @@
set(SRCS
NuklearApp.cpp NuklearApp.h
Nuklear.h
Console.cpp Console.h
LUAUIApp.cpp LUAUIApp.h
LUAFunctions.cpp LUAFunctions.h
private/nuklear.h
)
set(FILES
shared/font.ttf
)
engine_add_module(TARGET nuklear SRCS ${SRCS} FILES ${FILES} DEPENDENCIES render commonlua)

View File

@ -1,46 +0,0 @@
/**
* @file
*/
#include "Console.h"
#include "Nuklear.h"
#include "NuklearApp.h"
namespace ui {
namespace nuklear {
Console::Console(struct nk_context* ctx) :
Super(), _ctx(ctx) {
}
void Console::drawString(int x, int y, const glm::ivec4& color, const char* str, int len) {
const struct nk_user_font *font = _ctx->style.font;
struct nk_command_buffer* cmdBuf = nk_window_get_canvas(_ctx);
const int width = font->width(font->userdata, font->height, str, len);
const struct nk_rect& rect = nk_rect(x, y, width, font->height);
nk_draw_text(cmdBuf, rect, str,
strlen(str), font, nk_rgba(0, 0, 0, 255), nk_rgba(color.r, color.g, color.b, color.a));
}
void Console::afterRender(const math::Rect<int> &rect) {
nk_end(_ctx);
}
void Console::beforeRender(const math::Rect<int> &rect) {
const struct nk_rect nkrect{(float)rect.getMinX(), (float)rect.getMinZ(), (float)rect.getMaxX(), (float)rect.getMaxZ()};
nk_begin(_ctx, "in-game-console", nkrect, NK_WINDOW_NO_SCROLLBAR);
}
int Console::lineHeight() {
const struct nk_user_font *styleFont = _ctx->style.font;
const int lineHeight = styleFont->height;
return lineHeight;
}
glm::ivec2 Console::stringSize(const char* s, int length) {
const struct nk_user_font *styleFont = _ctx->style.font;
return glm::ivec2(styleFont->width(styleFont->userdata, styleFont->height, s, length), lineHeight());
}
}
}

View File

@ -1,34 +0,0 @@
/**
* @file
*/
#pragma once
#include "util/Console.h"
#include "Nuklear.h"
namespace ui {
namespace nuklear {
class NuklearApp;
/**
* @ingroup UI
*/
class Console : public util::Console {
private:
using Super = util::Console;
struct nk_context* _ctx = nullptr;
void drawString(int x, int y, const glm::ivec4& color, const char* str, int len) override;
int lineHeight() override;
glm::ivec2 stringSize(const char* s, int length) override;
void afterRender(const math::Rect<int> &rect) override;
void beforeRender(const math::Rect<int> &rect) override;
public:
Console(struct nk_context* ctx);
};
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,149 +0,0 @@
/**
* @file
* @brief LUA bindings for nuklear ui.
* @note Most of this stuff is shamelessly copied over from nuklear-love lua bindings
* @ingroup UI
*
* LOVE-Nuklear - MIT licensed; no warranty implied; use at your own risk.
* authored from 2015-2016 by Micha Mettke
* adapted to LOVE in 2016 by Kevin Harrison
*/
#pragma once
#include "commonlua/LUAFunctions.h"
#include "Nuklear.h"
#include "core/Assert.h"
#include <vector>
namespace ui {
namespace nuklear {
/**
* @brief Extended window start with separated title and identifier to allow multiple windows with same name but not title
* @param[in] name (optional) The name of the window - if not given, the name will be the title. Needs to be persistent over
* frames to identify the window
* @param[in] title The title of the window displayed inside header if flag @c title or either @c closable or @c minimized was set
* @param[in] x Position of the window
* @param[in] y Position of the window
* @param[in] w Size of the window
* @param[in] h Size of the window
* @param[in] flags Window flags (scrollbar, scroll auto hide, minimizable, background, scalable, closable, movable, border, title)
* with a number of different window behaviors
* @note If you do not define @c scalable or @c moveable you can set window position and size every frame
* @return @c true if the window can be filled up with widgets from this point until @c windowEnd or @c false otherwise
*/
extern int uilua_window_begin(lua_State *s);
/**
* @brief Needs to be called at the end of the window building process to process scaling,
* scrollbars and general cleanup. All widget calls after this functions will result in
* asserts or no state changes
*/
extern int uilua_window_end(lua_State *s);
/**
* @return A rectangle with screen position and size of the currently processed window.
* @note IMPORTANT: only call this function between calls `windowBegin` and `windowEnd`
*/
extern int uilua_window_get_bounds(lua_State *s);
/**
* @return The position of the currently processed window.
* @note IMPORTANT: only call this function between calls `windowBegin` and `windowEnd`
*/
extern int uilua_window_get_position(lua_State *s);
/**
* @return The size with width and height of the currently processed window.
* @note IMPORTANT: only call this function between calls `windowBegin` and `windowEnd`
*/
extern int uilua_window_get_size(lua_State *s);
/**
* @return The position and size of the currently visible and non-clipped space inside the currently processed window.
* @note IMPORTANT: only call this function between calls `windowBegin` and `windowEnd`
*/
extern int uilua_window_get_content_region(lua_State *s);
extern int uilua_edit(lua_State *s);
extern int uilua_text(lua_State *s);
extern int uilua_push_scissor(lua_State *s);
extern int uilua_label(lua_State *s);
extern int uilua_image(lua_State *s);
extern int uilua_button(lua_State *s);
extern int uilua_window_has_focus(lua_State *s);
extern int uilua_window_is_collapsed(lua_State *s);
extern int uilua_window_is_hidden(lua_State *s);
extern int uilua_window_is_active(lua_State *s);
extern int uilua_window_is_hovered(lua_State *s);
extern int uilua_window_is_any_hovered(lua_State *s);
extern int uilua_item_is_any_active(lua_State *s);
extern int uilua_window_set_bounds(lua_State *s);
extern int uilua_window_set_position(lua_State *s);
extern int uilua_window_set_size(lua_State *s);
extern int uilua_window_set_focus(lua_State *s);
extern int uilua_window_close(lua_State *s);
extern int uilua_window_collapse(lua_State *s);
extern int uilua_window_expand(lua_State *s);
extern int uilua_window_show(lua_State *s);
extern int uilua_window_hide(lua_State *s);
extern int uilua_layout_row(lua_State *s);
extern int uilua_layout_row_begin(lua_State *s);
extern int uilua_layout_row_push(lua_State *s);
extern int uilua_layout_row_end(lua_State *s);
extern int uilua_layout_space_begin(lua_State *s);
extern int uilua_layout_space_push(lua_State *s);
extern int uilua_layout_space_end(lua_State *s);
extern int uilua_layout_space_bounds(lua_State *s);
extern int uilua_layout_space_to_screen(lua_State *s);
extern int uilua_layout_space_to_local(lua_State *s);
extern int uilua_layout_space_rect_to_screen(lua_State *s);
extern int uilua_layout_space_rect_to_local(lua_State *s);
extern int uilua_layout_ratio_from_pixel(lua_State *s);
extern int uilua_group_begin(lua_State *s);
extern int uilua_group_end(lua_State *s);
extern int uilua_tree_push(lua_State *s);
extern int uilua_tree_pop(lua_State *s);
extern int uilua_button_set_behavior(lua_State *s);
extern int uilua_button_push_behavior(lua_State *s);
extern int uilua_button_pop_behavior(lua_State *s);
extern int uilua_checkbox(lua_State *s);
extern int uilua_radio(lua_State *s);
extern int uilua_selectable(lua_State *s);
extern int uilua_slider(lua_State *s);
extern int uilua_progress(lua_State *s);
extern int uilua_color_picker(lua_State *s);
extern int uilua_property(lua_State *s);
extern int uilua_popup_begin(lua_State *s);
extern int uilua_popup_close(lua_State *s);
extern int uilua_popup_end(lua_State *s);
extern int uilua_combobox(lua_State *s);
extern int uilua_combobox_begin(lua_State *s);
extern int uilua_combobox_item(lua_State *s);
extern int uilua_combobox_close(lua_State *s);
extern int uilua_combobox_end(lua_State *s);
extern int uilua_contextual_begin(lua_State *s);
extern int uilua_contextual_item(lua_State *s);
extern int uilua_contextual_close(lua_State *s);
extern int uilua_contextual_end(lua_State *s);
extern int uilua_tooltip(lua_State *s);
extern int uilua_tooltip_begin(lua_State *s);
extern int uilua_tooltip_end(lua_State *s);
extern int uilua_menubar_begin(lua_State *s);
extern int uilua_menubar_end(lua_State *s);
extern int uilua_menu_begin(lua_State *s);
extern int uilua_menu_item(lua_State *s);
extern int uilua_menu_close(lua_State *s);
extern int uilua_menu_end(lua_State *s);
extern int uilua_spacing(lua_State *s);
extern int uilua_widget_bounds(lua_State *s);
extern int uilua_widget_position(lua_State *s);
extern int uilua_widget_size(lua_State *s);
extern int uilua_widget_width(lua_State *s);
extern int uilua_widget_height(lua_State *s);
extern int uilua_widget_is_hovered(lua_State *s);
}
}

View File

@ -1,203 +0,0 @@
/**
* @file
*/
#include "LUAUIApp.h"
#include "LUAFunctions.h"
#include "core/io/Filesystem.h"
#include "core/Log.h"
#include "core/command/Command.h"
#include "core/Trace.h"
#include "Nuklear.h"
namespace ui {
namespace nuklear {
LUAUIApp::LUAUIApp(const metric::MetricPtr& metric,
const io::FilesystemPtr& filesystem,
const core::EventBusPtr& eventBus,
const core::TimeProviderPtr& timeProvider,
const video::TexturePoolPtr& texturePool) :
Super(metric, filesystem, eventBus, timeProvider), _lua(false), _texturePool(texturePool) {
}
LUAUIApp::~LUAUIApp() {
}
core::AppState LUAUIApp::onInit() {
const core::AppState state = Super::onInit();
if (!_texturePool->init()) {
return core::AppState::InitFailure;
}
if (!reload()) {
return core::AppState::InitFailure;
}
const std::string uiScriptPath = "ui/" + appname() + ".lua";
const io::FilesystemPtr& fs = filesystem();
if (!fs->watch(uiScriptPath, [] (const char *name) {
Log::info("Reload ui script: '%s'", name);
LUAUIApp* app = (LUAUIApp*)core::App::getInstance();
app->reload();
})) {
Log::warn("Failed to install file watcher");
} else {
Log::info("Installed file watcher for '%s'", uiScriptPath.c_str());
}
core::Command::registerCommand("uireload", [this] (const core::CmdArgs&) {reload();});
return state;
}
core::AppState LUAUIApp::onCleanup() {
_texturePool->shutdown();
return Super::onCleanup();
}
bool LUAUIApp::onRenderUI() {
if (_skipUntilReload) {
return true;
}
core_trace_scoped(LUAAIAppOnRenderUI);
if (!_lua.executeUpdate(_deltaFrameMillis)) {
Log::error("LUA UI: %s", _lua.error().c_str());
_skipUntilReload = true;
return false;
}
return true;
}
bool LUAUIApp::reload() {
const bool console = _console.isActive();
if (console) {
_console.toggle();
}
_skipUntilReload = true;
core_assert_always(_lua.resetState());
const std::vector<luaL_Reg> funcs = {
{"windowBegin", uilua_window_begin},
{"windowEnd", uilua_window_end},
{"getWindowBounds", uilua_window_get_bounds},
{"getWindowPos", uilua_window_get_position},
{"getWindowSize", uilua_window_get_size},
{"getWindowContentRegion", uilua_window_get_content_region},
{"edit", uilua_edit},
{"text", uilua_text},
{"label", uilua_label},
{"image", uilua_image},
{"checkbox", uilua_checkbox},
{"radio", uilua_radio},
{"selectable", uilua_selectable},
{"slider", uilua_slider},
{"progress", uilua_progress},
{"colorpicker", uilua_color_picker},
{"property", uilua_property},
{"button", uilua_button},
{"buttonSetBehaviour", uilua_button_set_behavior},
{"buttonPushBehaviour", uilua_button_push_behavior},
{"buttonPopBehaviour", uilua_button_pop_behavior},
{"hasWindowFocus", uilua_window_has_focus},
{"isWindowCollapsed", uilua_window_is_collapsed},
{"isWindowHidden", uilua_window_is_hidden},
{"isWindowActive", uilua_window_is_active},
{"isWindowHovered", uilua_window_is_hovered},
{"isAnyWindowHovered", uilua_window_is_any_hovered},
{"isAnythingActive", uilua_item_is_any_active},
{"setWindowBounds", uilua_window_set_bounds},
{"setWindowPosition", uilua_window_set_position},
{"setWindowSize", uilua_window_set_size},
{"setWindowFocus", uilua_window_set_focus},
{"windowClose", uilua_window_close},
{"windowCollapse", uilua_window_collapse},
{"windowExpand", uilua_window_expand},
{"windowShow", uilua_window_show},
{"windowHide", uilua_window_hide},
{"layoutRow", uilua_layout_row},
{"layoutRowBegin", uilua_layout_row_begin},
{"layoutRowPush", uilua_layout_row_push},
{"layoutRowEnd", uilua_layout_row_end},
{"layoutSpaceBegin", uilua_layout_space_begin},
{"layoutSpacePush", uilua_layout_space_push},
{"layoutSpaceEnd", uilua_layout_space_end},
{"getLayoutSpaceBounds", uilua_layout_space_bounds},
{"layoutSpaceToScreen", uilua_layout_space_to_screen},
{"layoutSpaceToLocal", uilua_layout_space_to_local},
{"layoutSpaceRectToScreen", uilua_layout_space_rect_to_screen},
{"layoutSpaceRectToLocal", uilua_layout_space_rect_to_local},
{"layoutSpaceRatioFromPixel", uilua_layout_ratio_from_pixel},
{"groupBegin", uilua_group_begin},
{"groupEnd", uilua_group_end},
{"treePush", uilua_tree_push},
{"treePop", uilua_tree_pop},
{"popupBegin", uilua_popup_begin},
{"popupClose", uilua_popup_close},
{"popupEnd", uilua_popup_end},
{"combobox", uilua_combobox},
{"comboboxBegin", uilua_combobox_begin},
{"comboboxItem", uilua_combobox_item},
{"comboboxClose", uilua_combobox_close},
{"comboboxEnd", uilua_combobox_end},
{"contextualBegin", uilua_contextual_begin},
{"contextualItem", uilua_contextual_item},
{"contextualClose", uilua_contextual_close},
{"contextualEnd", uilua_contextual_end},
{"tooltip", uilua_tooltip},
{"tooltipBegin", uilua_tooltip_begin},
{"tooltipEnd", uilua_tooltip_end},
{"menubarBegin", uilua_menubar_begin},
{"menubarEnd", uilua_menubar_end},
{"menuBegin", uilua_menu_begin},
{"menuItem", uilua_menu_item},
{"menuClose", uilua_menu_close},
{"menuEnd", uilua_menu_end},
{"getWidgetBounds", uilua_widget_bounds},
{"getWidgetPosition", uilua_widget_position},
{"getWidgetSize", uilua_widget_size},
{"getWidgetWidth", uilua_widget_width},
{"getWidgetHeight", uilua_widget_height},
{"isWidgetHovered", uilua_widget_is_hovered},
{"spacing", uilua_spacing},
{"scissor", uilua_push_scissor},
{nullptr, nullptr}
};
_lua.newGlobalData<struct nk_context>("context", &_ctx);
_lua.newGlobalData<video::TexturePool>("texturepool", _texturePool.get());
_lua.reg("ui", &funcs.front());
const io::FilesystemPtr& fs = filesystem();
const std::string uiScriptPath = "ui/" + appname() + ".lua";
const std::string& luaScript = fs->load(uiScriptPath);
if (luaScript.empty()) {
Log::error("Could not load ui script from '%s'", uiScriptPath.c_str());
return false;
}
if (!_lua.load(luaScript)) {
Log::error("Could not execute lua script from '%s': %s", uiScriptPath.c_str(), _lua.error().c_str());
return false;
}
_skipUntilReload = false;
return true;
}
}
}

View File

@ -1,38 +0,0 @@
/**
* @file
*/
#pragma once
#include "NuklearApp.h"
#include "commonlua/LUA.h"
#include "video/TexturePool.h"
namespace ui {
namespace nuklear {
/**
* @brief The lua UI application is using a lua script with in @code ui/$appname$.lua @endcode to assemble the
* UI. This script is automatically reloaded if it is changed in the filesystem.
* @ingroup UI
*/
class LUAUIApp : public NuklearApp {
private:
using Super = NuklearApp;
protected:
lua::LUA _lua;
video::TexturePoolPtr _texturePool;
bool _skipUntilReload = true;
public:
LUAUIApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, const video::TexturePoolPtr& texturePool);
virtual ~LUAUIApp();
core::AppState onInit() override;
core::AppState onCleanup() override;
bool reload();
bool onRenderUI() override;
};
}
}

View File

@ -1,21 +0,0 @@
/**
* @file
*/
#include "core/Assert.h"
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_DEFAULT_FONT
#define NK_ASSERT core_assert
/**
* @addtogroup UI
* @{
*/
#include "private/nuklear.h"
/**
* @}
*/

View File

@ -1,405 +0,0 @@
/**
* @file
*/
#include "NuklearApp.h"
#include "video/Renderer.h"
#include "video/ScopedViewPort.h"
#include "core/UTF8.h"
#include "core/io/Filesystem.h"
#include "core/Assert.h"
#define NK_IMPLEMENTATION
#include "Nuklear.h"
#undef NK_IMPLEMENTATION
#include <SDL.h>
namespace ui {
namespace nuklear {
static const int MAX_VERTEX_MEMORY = 32768 * sizeof(NuklearApp::Vertex);
static const int MAX_ELEMENT_MEMORY = 65536;
NuklearApp::NuklearApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider) :
Super(metric, filesystem, eventBus, timeProvider), _console(&_ctx), _camera(video::CameraType::FirstPerson, video::CameraMode::Orthogonal) {
}
NuklearApp::~NuklearApp() {
}
bool NuklearApp::onMouseWheel(int32_t x, int32_t y) {
if (_console.onMouseWheel(x, y)) {
return true;
}
if (Super::onMouseWheel(x, y)) {
return true;
}
nk_input_scroll(&_ctx, nk_vec2((float) x, (float) y));
return true;
}
void NuklearApp::onMouseMotion(int32_t x, int32_t y, int32_t relX, int32_t relY) {
if (_ctx.input.mouse.grabbed) {
const int x = (int) _ctx.input.mouse.prev.x;
const int y = (int) _ctx.input.mouse.prev.y;
nk_input_motion(&_ctx, x + relX, y + relY);
} else {
nk_input_motion(&_ctx, x, y);
}
}
void NuklearApp::onMouseButtonPress(int32_t x, int32_t y, uint8_t button, uint8_t clicks) {
if (_console.onMouseButtonPress(x, y, button)) {
return;
}
if (button == SDL_BUTTON_LEFT) {
if (clicks > 1) {
nk_input_button(&_ctx, NK_BUTTON_DOUBLE, x, y, true);
}
nk_input_button(&_ctx, NK_BUTTON_LEFT, x, y, true);
} else if (button == SDL_BUTTON_MIDDLE) {
nk_input_button(&_ctx, NK_BUTTON_MIDDLE, x, y, true);
} else if (button == SDL_BUTTON_RIGHT) {
nk_input_button(&_ctx, NK_BUTTON_RIGHT, x, y, true);
}
}
void NuklearApp::onMouseButtonRelease(int32_t x, int32_t y, uint8_t button) {
if (_console.isActive()) {
return;
}
if (button == SDL_BUTTON_LEFT) {
nk_input_button(&_ctx, NK_BUTTON_LEFT, x, y, false);
} else if (button == SDL_BUTTON_MIDDLE) {
nk_input_button(&_ctx, NK_BUTTON_MIDDLE, x, y, false);
} else if (button == SDL_BUTTON_RIGHT) {
nk_input_button(&_ctx, NK_BUTTON_RIGHT, x, y, false);
}
}
bool NuklearApp::onTextInput(const std::string& text) {
if (_console.onTextInput(text)) {
return true;
}
const char *c = text.c_str();
for (;;) {
const int key = core::utf8::next(&c);
if (key == -1) {
return true;
}
nk_glyph glyph;
memcpy(glyph, &key, NK_UTF_SIZE);
nk_input_glyph(&_ctx, glyph);
}
return true;
}
bool NuklearApp::onKeyEvent(int32_t sym, int16_t modifier, bool down) {
bool ctrl = (modifier & KMOD_CTRL) != 0;
if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT) {
nk_input_key(&_ctx, NK_KEY_SHIFT, down);
} else if (sym == SDLK_DELETE) {
nk_input_key(&_ctx, NK_KEY_DEL, down);
} else if (sym == SDLK_RETURN) {
nk_input_key(&_ctx, NK_KEY_ENTER, down);
} else if (sym == SDLK_TAB) {
nk_input_key(&_ctx, NK_KEY_TAB, down);
} else if (sym == SDLK_BACKSPACE) {
nk_input_key(&_ctx, NK_KEY_BACKSPACE, down);
} else if (sym == SDLK_HOME) {
nk_input_key(&_ctx, NK_KEY_TEXT_START, down);
nk_input_key(&_ctx, NK_KEY_SCROLL_START, down);
} else if (sym == SDLK_END) {
nk_input_key(&_ctx, NK_KEY_TEXT_END, down);
nk_input_key(&_ctx, NK_KEY_SCROLL_END, down);
} else if (sym == SDLK_PAGEDOWN) {
nk_input_key(&_ctx, NK_KEY_SCROLL_DOWN, down);
} else if (sym == SDLK_PAGEUP) {
nk_input_key(&_ctx, NK_KEY_SCROLL_UP, down);
} else if (sym == SDLK_z) {
nk_input_key(&_ctx, NK_KEY_TEXT_UNDO, down && ctrl);
} else if (sym == SDLK_r) {
nk_input_key(&_ctx, NK_KEY_TEXT_REDO, down && ctrl);
} else if (sym == SDLK_c) {
nk_input_key(&_ctx, NK_KEY_COPY, down && ctrl);
} else if (sym == SDLK_v) {
nk_input_key(&_ctx, NK_KEY_PASTE, down && ctrl);
} else if (sym == SDLK_x) {
nk_input_key(&_ctx, NK_KEY_CUT, down && ctrl);
} else if (sym == SDLK_b) {
nk_input_key(&_ctx, NK_KEY_TEXT_LINE_START, down && ctrl);
} else if (sym == SDLK_e) {
nk_input_key(&_ctx, NK_KEY_TEXT_LINE_END, down && ctrl);
} else if (sym == SDLK_UP) {
nk_input_key(&_ctx, NK_KEY_UP, down);
} else if (sym == SDLK_DOWN) {
nk_input_key(&_ctx, NK_KEY_DOWN, down);
} else if (sym == SDLK_LEFT) {
if (ctrl) {
nk_input_key(&_ctx, NK_KEY_TEXT_WORD_LEFT, down);
} else {
nk_input_key(&_ctx, NK_KEY_LEFT, down);
}
} else if (sym == SDLK_RIGHT) {
if (ctrl) {
nk_input_key(&_ctx, NK_KEY_TEXT_WORD_RIGHT, down);
} else {
nk_input_key(&_ctx, NK_KEY_RIGHT, down);
}
} else {
return false;
}
return true;
}
bool NuklearApp::onKeyPress(int32_t key, int16_t modifier) {
if (_console.onKeyPress(key, modifier)) {
return true;
}
if (Super::onKeyPress(key, modifier)) {
return true;
}
return onKeyEvent(key, modifier, true);
}
bool NuklearApp::onKeyRelease(int32_t key, int16_t modifier) {
if (_console.isActive()) {
return true;
}
if (Super::onKeyRelease(key, modifier)) {
return true;
}
return onKeyEvent(key, modifier, false);
}
static void nk_sdl_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) {
if (!SDL_HasClipboardText()) {
return;
}
const char *text = SDL_GetClipboardText();
nk_textedit_paste(edit, text, nk_strlen(text));
}
static void nk_sdl_clipbard_copy(nk_handle usr, const char *text, int len) {
if (len <= 0) {
return;
}
char* str = new char[len + 1];
memcpy(str, text, (size_t) len);
str[len] = '\0';
SDL_SetClipboardText(str);
delete[] str;
}
core::AppState NuklearApp::onInit() {
const core::AppState state = Super::onInit();
SDL_StartTextInput();
showCursor(false);
centerMousePosition();
video::checkError();
if (state != core::AppState::Running) {
return state;
}
_fontTexture = video::createEmptyTexture("**font**");
nk_init_default(&_ctx, nullptr);
_ctx.clip.copy = nk_sdl_clipbard_copy;
_ctx.clip.paste = nk_sdl_clipbard_paste;
_ctx.clip.userdata = nk_handle_ptr(this);
nk_font_atlas_init_default(&_atlas);
nk_font_atlas_begin(&_atlas);
nk_buffer_init_default(&_cmds);
const int fontSize = 16;
const io::FilePtr& file = filesystem()->open("font.ttf", io::FileMode::Read);
if (file) {
void *fontData = nullptr;
const size_t fontDataSize = file->read((void **) &fontData);
_font = nk_font_atlas_add_from_memory(&_atlas, fontData, fontDataSize, fontSize, nullptr);
if (_font != nullptr) {
int w, h;
const void *image = nk_font_atlas_bake(&_atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
_fontTexture->upload(w, h, (const uint8_t*) image);
nk_style_set_font(&_ctx, &_font->handle);
} else {
Log::warn("Failed to add font to atlas");
}
} else {
Log::warn("Failed to load font.ttf");
}
if (_font == nullptr) {
_font = nk_font_atlas_add_default(&_atlas, fontSize, nullptr);
}
nk_font_atlas_end(&_atlas, nk_handle_id((int)_fontTexture->handle()), &_null);
nk_style_load_all_cursors(&_ctx, _atlas.cursors);
if (_atlas.default_font) {
nk_style_set_font(&_ctx, &_atlas.default_font->handle);
}
if (!_shader.setup()) {
Log::error("Could not load the ui shader");
return core::AppState::InitFailure;
}
_vertexBufferIndex = _vbo.create();
if (_vertexBufferIndex < 0) {
Log::error("Failed to create ui vbo");
return core::AppState::InitFailure;
}
_vbo.setMode(_vertexBufferIndex, video::BufferMode::Stream);
_elementBufferIndex = _vbo.create(nullptr, 0, video::BufferType::IndexBuffer);
if (_elementBufferIndex < 0) {
Log::error("Failed to create ui ibo");
return core::AppState::InitFailure;
}
_camera.setNearPlane(-1.0f);
_camera.setFarPlane(1.0f);
_camera.init(glm::ivec2(0), frameBufferDimension(), windowDimension());
_camera.update(0L);
_vbo.addAttribute(_shader.getColorAttribute(_vertexBufferIndex, &Vertex::r, true));
_vbo.addAttribute(_shader.getTexcoordAttribute(_vertexBufferIndex, &Vertex::u));
_vbo.addAttribute(_shader.getPosAttribute(_vertexBufferIndex, &Vertex::x));
if (!_vbo.update(_vertexBufferIndex, nullptr, MAX_VERTEX_MEMORY)) {
Log::error("Failed to upload vertex buffer data with %i bytes", MAX_VERTEX_MEMORY);
return core::AppState::InitFailure;
}
if (!_vbo.update(_elementBufferIndex, nullptr, MAX_ELEMENT_MEMORY)) {
Log::error("Failed to upload index buffer data with %i bytes", MAX_ELEMENT_MEMORY);
return core::AppState::InitFailure;
}
static constexpr struct nk_draw_vertex_layout_element vertexLayout[] = {
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(Vertex, x)},
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(Vertex, u)},
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(Vertex, r)},
{NK_VERTEX_LAYOUT_END}
};
memset(&_config, 0, sizeof(_config));
_config.vertex_layout = vertexLayout;
_config.vertex_size = sizeof(Vertex);
_config.vertex_alignment = NK_ALIGNOF(Vertex);
_config.null = _null;
_config.circle_segment_count = 22;
_config.curve_segment_count = 22;
_config.arc_segment_count = 22;
_config.global_alpha = 1.0f;
_config.shape_AA = NK_ANTI_ALIASING_ON;
_config.line_AA = NK_ANTI_ALIASING_ON;
_console.init();
return state;
}
void NuklearApp::onWindowResize(int windowWidth, int windowHeight) {
Super::onWindowResize(windowWidth, windowHeight);
_camera.init(glm::zero<glm::ivec2>(), frameBufferDimension(), windowDimension());
}
core::AppState NuklearApp::onConstruct() {
const core::AppState state = Super::onConstruct();
_console.construct();
return state;
}
core::AppState NuklearApp::onRunning() {
_console.update(_deltaFrameMillis);
nk_input_begin(&_ctx);
core::AppState state = Super::onRunning();
nk_input_motion(&_ctx, _mousePos.x, _mousePos.y);
nk_input_end(&_ctx);
if (!onRenderUI()) {
if (_ctx.current) {
nk_end(&_ctx);
}
nk_clear(&_ctx);
return state;
}
const math::Rect<int> rect(0, 0, _frameBufferDimension.x, _frameBufferDimension.y);
_console.render(rect, _deltaFrameMillis);
video::ScopedShader scopedShader(_shader);
_shader.setViewprojection(_camera.projectionMatrix());
_shader.setModel(glm::mat4(1.0f));
_shader.setTexture(video::TextureUnit::Zero);
video::ScopedViewPort scopedViewPort(0, 0, _frameBufferDimension.x, _frameBufferDimension.y);
video::enable(video::State::Blend);
video::blendEquation(video::BlendEquation::Add);
video::blendFunc(video::BlendMode::SourceAlpha, video::BlendMode::OneMinusSourceAlpha);
video::disable(video::State::CullFace);
video::disable(video::State::DepthTest);
video::enable(video::State::Scissor);
void *vertices = _vbo.mapData(_vertexBufferIndex, video::AccessMode::Write);
if (vertices == nullptr) {
Log::warn("Failed to map vertices");
return core::AppState::Cleanup;
}
void *elements = _vbo.mapData(_elementBufferIndex, video::AccessMode::Write);
if (elements == nullptr) {
Log::warn("Failed to map indices");
return core::AppState::Cleanup;
}
struct nk_buffer vbuf;
struct nk_buffer ebuf;
nk_buffer_init_fixed(&vbuf, vertices, (nk_size) MAX_VERTEX_MEMORY);
nk_buffer_init_fixed(&ebuf, elements, (nk_size) MAX_ELEMENT_MEMORY);
const bool convertRes = nk_convert(&_ctx, &_cmds, &vbuf, &ebuf, &_config) == NK_CONVERT_SUCCESS;
Log::trace("vertices buffer size: %i", (int)vbuf.size);
Log::trace("index buffer size: %i", (int)ebuf.size);
_vbo.unmapData(_vertexBufferIndex);
_vbo.unmapData(_elementBufferIndex);
if (convertRes) {
const nk_draw_index *offset = nullptr;
const struct nk_draw_command *cmd;
nk_draw_foreach(cmd, &_ctx, &_cmds) {
if (!cmd->elem_count) {
continue;
}
video::bindTexture(video::TextureUnit::Zero, video::TextureType::Texture2D, cmd->texture.id);
video::scissor(cmd->clip_rect.x, cmd->clip_rect.y, cmd->clip_rect.w, cmd->clip_rect.h);
video::drawElements(video::Primitive::Triangles, (size_t) cmd->elem_count, video::mapType<nk_draw_index>(), (void*) offset);
offset += cmd->elem_count;
}
} else {
Log::warn("Could not convert draw command to vbo data");
}
nk_clear(&_ctx);
return state;
}
core::AppState NuklearApp::onCleanup() {
nk_font_atlas_clear(&_atlas);
nk_buffer_free(&_cmds);
nk_free(&_ctx);
_console.shutdown();
_shader.shutdown();
_vbo.shutdown();
if (_fontTexture) {
_fontTexture->shutdown();
}
return Super::onCleanup();
}
}
}

View File

@ -1,74 +0,0 @@
/**
* @file
*/
#pragma once
#include "video/WindowedApp.h"
#include "video/Camera.h"
#include "video/Buffer.h"
#include "video/Texture.h"
#include "Console.h"
#include "RenderShaders.h"
#include "Nuklear.h"
namespace ui {
namespace nuklear {
/**
* @ingroup UI
*/
class NuklearApp: public video::WindowedApp {
private:
using Super = video::WindowedApp;
public:
struct Vertex {
float x, y;
float u, v;
union {
struct { uint8_t r, g, b, a; };
uint32_t col;
};
};
protected:
struct nk_context _ctx;
struct nk_font_atlas _atlas;
struct nk_draw_null_texture _null;
struct nk_buffer _cmds;
struct nk_convert_config _config;
struct nk_font *_font = nullptr;
Console _console;
shader::TextureShader _shader;
video::Camera _camera;
video::Buffer _vbo;
video::TexturePtr _fontTexture;
int32_t _vertexBufferIndex = -1;
int32_t _elementBufferIndex = -1;
bool onKeyEvent(int32_t sym, int16_t modifier, bool down);
virtual bool onKeyRelease(int32_t key, int16_t modifier) override;
virtual bool onKeyPress(int32_t key, int16_t modifier) override;
virtual bool onTextInput(const std::string& text) override;
virtual bool onMouseWheel(int32_t x, int32_t y) override;
virtual void onMouseMotion(int32_t x, int32_t y, int32_t relX, int32_t relY) override;
virtual void onMouseButtonPress(int32_t x, int32_t y, uint8_t button, uint8_t clicks) override;
virtual void onMouseButtonRelease(int32_t x, int32_t y, uint8_t button) override;
public:
NuklearApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider);
virtual ~NuklearApp();
virtual bool onRenderUI() = 0;
virtual void onWindowResize(int windowWidth, int windowHeight) override;
virtual core::AppState onConstruct() override;
virtual core::AppState onInit() override;
virtual core::AppState onRunning() override;
virtual core::AppState onCleanup() override;
};
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,8 @@ add_subdirectory(testplane)
add_subdirectory(testglslcomp)
add_subdirectory(testglslgeom)
add_subdirectory(testimgui)
add_subdirectory(testnuklear)
add_subdirectory(testturbobadger)
add_subdirectory(testgpumc)
add_subdirectory(testluaui)
add_subdirectory(testcamera)
add_subdirectory(testoctree)
add_subdirectory(testoctreevisit)

View File

@ -24,10 +24,6 @@ Test the dearimgui integration
Test geometry shader integration
# testnuklear
Test the nuklear imgui integration
# testcomputetexture3d
Test the OpenCL 3d texture integration of a 3d voxel volume (rendered as 2d side view)
@ -77,7 +73,6 @@ Conversion of OpenCL marching cubes taken from: https://github.com/smistad/GPU-M
Renders the turbobadger demo.
# testluaui
# testoctreevisit
Visit the frustum in the octree.

View File

@ -1,9 +0,0 @@
project(testluaui)
set(SRCS
TestLUAUI.h TestLUAUI.cpp
)
set(LUA_SRCS
ui/${PROJECT_NAME}.lua
)
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} WINDOWED LUA_SRCS ${LUA_SRCS} NOINSTALL)
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES nuklear)

View File

@ -1,23 +0,0 @@
/**
* @file
*/
#include "TestLUAUI.h"
#include "core/io/Filesystem.h"
#include "video/TexturePool.h"
#include "core/TimeProvider.h"
#include "core/EventBus.h"
TestLUAUI::TestLUAUI(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, const video::TexturePoolPtr& texturePool) :
Super(metric, filesystem, eventBus, timeProvider, texturePool) {
init(ORGANISATION, "testluaui");
}
int main(int argc, char *argv[]) {
const core::EventBusPtr& eventBus = std::make_shared<core::EventBus>();
const io::FilesystemPtr& filesystem = std::make_shared<io::Filesystem>();
const core::TimeProviderPtr& timeProvider = std::make_shared<core::TimeProvider>();
const video::TexturePoolPtr& texturePool = std::make_shared<video::TexturePool>(filesystem);
const metric::MetricPtr& metric = std::make_shared<metric::Metric>();
TestLUAUI app(metric, filesystem, eventBus, timeProvider, texturePool);
return app.startMainLoop(argc, argv);
}

View File

@ -1,14 +0,0 @@
/**
* @file
*/
#pragma once
#include "ui/nuklear/LUAUIApp.h"
class TestLUAUI: public ui::nuklear::LUAUIApp {
private:
using Super = ui::nuklear::LUAUIApp;
public:
TestLUAUI(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, const video::TexturePoolPtr& texturePool);
};

View File

@ -1,200 +0,0 @@
-- An overview of most of the supported widgets.
-- Simple calculator example
local ops = {'+', '-', '*', '/'}
local a, b, op = '0'
local function clear()
a, b, op = '0'
end
local function digit(d)
if op then
if b == nil or b == '0' then
b = d
else
b = b..d
end
else
if a == '0' then
a = d
else
a = a..d
end
end
end
local function decimal()
if op then
b = b or '0'
b = b:find('.') and b or b..'.'
else
a = a:find('.') and a or a..'.'
end
end
local function equals()
if not tonumber(b) then
return
end
if op == '+' then
a, b, op = tostring(tonumber(a) + tonumber(b))
elseif op == '-' then
a, b, op = tostring(tonumber(a) - tonumber(b))
elseif op == '*' then
a, b, op = tostring(tonumber(a) * tonumber(b))
elseif op == '/' then
a, b, op = tostring(tonumber(a) / tonumber(b))
end
end
local function operator(o)
if op then
equals()
end
op = o
end
local function display()
return b or a
end
local checkA = {value = false}
local checkB = {value = true}
local radio = {value = 'A'}
local selectA = {value = false}
local selectB = {value = true}
local slider = {value = 0.2}
local progress = {value = 1}
local colorPicker = {value = '#ff0000'}
local property = {value = 6}
local edit = {value = 'Edit text'}
local comboA = {value = 1, items = {'A', 'B', 'C'}}
function update(dt)
if ui.windowBegin('Overview', 100, 100, 600, 450, 'border', 'movable', 'title') then
ui.menubarBegin()
ui.layoutRowBegin('static', 25, 5);
ui.layoutRowPush(45);
if ui.menuBegin('Menu', nil, 120, 90) then
ui.layoutRow('dynamic', 40, 1)
ui.menuItem('Item A')
ui.menuItem('Item B')
ui.menuItem('Item C')
ui.menuEnd()
end
ui.menubarEnd()
ui.layoutRow('dynamic', 400, 3)
if ui.groupBegin('Group 1', 'border') then
ui.layoutRow('dynamic', 30, 1)
ui.label('Left label')
ui.label('Centered label', 'centered')
ui.label('Right label', 'right')
ui.label('Colored label', 'left', '#ff0000')
if ui.treePush('tab', 'Tree Tab') then
if ui.treePush('node', 'Tree Node 1') then
ui.label('Label 1')
ui.treePop()
end
if ui.treePush('node', 'Tree Node 2') then
ui.label('Label 2')
ui.treePop()
end
ui.treePop()
end
ui.spacing(1)
if ui.button('Button') then
print('button pressed!')
end
ui.spacing(1)
ui.checkbox('Checkbox A', checkA)
ui.checkbox('Checkbox B', checkB)
ui.groupEnd()
end
if ui.groupBegin('Group 2', 'border') then
ui.layoutRow('dynamic', 30, 1)
ui.label('Radio buttons:')
ui.layoutRow('dynamic', 30, 3)
ui.radio('A', radio)
ui.radio('B', radio)
ui.radio('C', radio)
ui.layoutRow('dynamic', 30, 1)
ui.selectable('Selectable A', selectA)
ui.selectable('Selectable B', selectB)
ui.layoutRow('dynamic', 30, {.35, .65})
ui.label('Slider:')
ui.slider(0, slider, 1, 0.05)
ui.label('Progress:')
ui.progress(progress, 10, true)
ui.layoutRow('dynamic', 30, 2)
ui.spacing(2)
ui.label('Color picker:')
ui.button(nil, colorPicker.value)
ui.layoutRow('dynamic', 90, 1)
ui.colorpicker(colorPicker)
ui.groupEnd()
end
if ui.groupBegin('Group 3', 'border') then
ui.layoutRow('dynamic', 30, 1)
ui.property('Property', 0, property, 10, 0.25, 0.05)
ui.spacing(1)
ui.label('Edit:')
ui.layoutRow('dynamic', 90, 1)
ui.edit('box', edit)
ui.layoutRow('dynamic', 5, 1)
ui.spacing(1)
ui.layoutRow('dynamic', 30, 1)
ui.label('Combobox:')
ui.combobox(comboA, comboA.items)
ui.layoutRow('dynamic', 5, 1)
ui.spacing(1)
ui.layoutRow('dynamic', 30, 1)
if ui.isWidgetHovered() then
ui.tooltip('Test tooltip')
end
local x, y, w, h = ui.getWidgetBounds()
if ui.contextualBegin(100, 100, x, y, w, h) then
ui.layoutRow('dynamic', 30, 1)
ui.contextualItem('Item A')
ui.contextualItem('Item B')
ui.contextualEnd()
end
ui.label('Contextual (Right click me)')
ui.groupEnd()
end
end
ui.windowEnd()
if ui.windowBegin('Calculator', 50, 50, 180, 250, 'border', 'movable', 'title') then
ui.layoutRow('dynamic', 35, 1)
ui.label(display(), 'right')
ui.layoutRow('dynamic', 35, 4)
for i=1,16 do
if i >= 13 and i < 16 then
if i == 13 then
if ui.button('C') then
clear()
end
if ui.button('0') then
digit('0')
end
if ui.button('=') then
equals()
end
end
elseif i % 4 ~= 0 then
local d = tostring(math.floor(i / 4) * 3 + (i % 4))
if ui.button(d) then
digit(d)
end
else
local o = ops[math.floor(i / 4)]
if ui.button(o) then
operator(o)
end
end
end
end
ui.windowEnd()
end

View File

@ -1,6 +0,0 @@
project(testnuklear)
set(SRCS
TestNuklear.h TestNuklear.cpp
)
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} WINDOWED NOINSTALL)
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES nuklear)

View File

@ -1,21 +0,0 @@
/**
* @file
*/
#include "TestNuklear.h"
#include "testcore/TestAppMain.h"
#include "core/io/Filesystem.h"
#include "ui/nuklear/Nuklear.h"
#include "overview.c"
TestNuklear::TestNuklear(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider) :
Super(metric, filesystem, eventBus, timeProvider) {
init(ORGANISATION, "testnuklear");
}
bool TestNuklear::onRenderUI() {
overview(&_ctx);
return true;
}
TEST_APP(TestNuklear)

View File

@ -1,16 +0,0 @@
/**
* @file
*/
#pragma once
#include "ui/nuklear/NuklearApp.h"
class TestNuklear: public ui::nuklear::NuklearApp {
private:
using Super = ui::nuklear::NuklearApp;
public:
TestNuklear(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider);
bool onRenderUI() override;
};

File diff suppressed because it is too large Load Diff