UI: removed nuklear ui
parent
768c057ad4
commit
1fb662810e
|
@ -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)
|
||||
|
|
7
Makefile
7
Makefile
|
@ -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:
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
add_subdirectory(imgui)
|
||||
add_subdirectory(turbobadger)
|
||||
add_subdirectory(nuklear)
|
||||
|
|
|
@ -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)
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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
|
||||
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
Loading…
Reference in New Issue