diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/.gitmodules b/.gitmodules index 26ee9e0..d87571a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "src/nuklear"] path = src/nuklear - url = https://github.com/vurtun/nuklear.git + url = https://github.com/Immediate-Mode-UI/Nuklear.git diff --git a/CMakeLists.txt b/CMakeLists.txt index d87381b..9d8c1f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,4 +24,14 @@ TARGET_LINK_LIBRARIES( ${LUA_LIBRARIES} ) +IF(MSVC) + TARGET_COMPILE_DEFINITIONS(${LIB_NAME} PRIVATE LUA_BUILD_AS_DLL) +endif(MSVC) + SET_TARGET_PROPERTIES("${LIB_NAME}" PROPERTIES PREFIX "") + +IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "..." FORCE) +ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + +INSTALL(TARGETS "${LIB_NAME}" DESTINATION .) diff --git a/README.md b/README.md index 1a3648f..77244e5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LÖVE-Nuklear -[Nuklear](https://github.com/vurtun/nuklear) module for the [LÖVE](https://love2d.org/) game engine. +[Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) module for the [LÖVE](https://love2d.org/) game engine. Provides a lightweight immediate mode GUI for LÖVE games. @@ -54,12 +54,12 @@ function love.keyreleased(key, scancode) ui:keyreleased(key, scancode) end -function love.mousepressed(x, y, button, istouch) - ui:mousepressed(x, y, button, istouch) +function love.mousepressed(x, y, button, istouch, presses) + ui:mousepressed(x, y, button, istouch, presses) end -function love.mousereleased(x, y, button, istouch) - ui:mousereleased(x, y, button, istouch) +function love.mousereleased(x, y, button, istouch, presses) + ui:mousereleased(x, y, button, istouch, presses) end function love.mousemoved(x, y, dx, dy, istouch) @@ -81,23 +81,30 @@ Windows binaries are available for each [release](https://github.com/keharriso/l To build the library yourself, grab the code with: ```sh -$ git clone --recursive git@github.com:keharriso/love-nuklear.git +$ git clone --recursive https://github.com/keharriso/love-nuklear.git ``` Next, you need to compile the code to a native Lua module. ### Compiling with CMake on Linux -1. First, ensure you have the `cmake` and `luajit` packages installed. +1. First, ensure you have a C compiler and the `cmake` and `luajit` or `lua51-luajit` (for openSUSE) packages installed, as well as `libluajit-5.1-dev` (for Ubuntu/Debian), `luajit-devel` (for Fedora), or `lua51-luajit-devel` (for openSUSE) if your distro has one of these packages. 2. Create a new folder next to `love-nuklear` called `love-nuklear-build`. 3. Open a terminal inside `love-nuklear-build`. -4. Compile with +4. Compile the library with ```sh -$ cmake ../love-nuklear +$ cmake -DCMAKE_BUILD_TYPE=Release ../love-nuklear $ make ``` 5. Locate `nuklear.so` in the build folder. +#### Via GNU Guix + +LÖVE-Nuklear is also available as a [Guix](http://guix.gnu.org/) package, and can thus be directly downloaded and built via: +``` +$ guix package --install love-nuklear +``` + ### Compiling with CMake and MinGW on Windows 1. Install [CMake](https://cmake.org/download/) and [MinGW](http://mingw.org/) or [MinGW-w64](https://mingw-w64.org/doku.php). @@ -125,6 +132,22 @@ $ mingw32-make ``` 18. Locate `nuklear.dll` inside the build folder. +### Compiling with CMake and MSVC on Windows + +1. Install [CMake](https://cmake.org/download/) and [Visual Studio](https://visualstudio.microsoft.com/). +Community or Express edition is sufficient. +2. Download the source code for [LuaJIT](http://luajit.org/download.html). +3. Open a Visual Studio Command Prompt (x86 or x64 depending on what architecture you need) +and set the current directory to the LuaJIT folder (the one that contains "README"). Also +remember this path. +4. At the VS Command Prompt, set your current directory to `src` then +execute `msvcbuild.bat`. This will create lua51.dll, lua51.lib, and luajit.exe +5. Now open new command prompt window inside the `love-nuklear` folder. +6. Type `set "LUA_DIR="` +7. Then type `cmake -Bbuild -H. -A Win32 -DLUA_INCLUDE_DIR=%LUA_DIR%\src -DLUA_LIBRARY=%LUA_DIR%\src\lua51.lib -DCMAKE_INSTALL_PREFIX=%CD%\install`. +If you previously compile LuaJIT using x64 VS command prompt, replace `Win32` with `x64` at above command. +8. Then type `cmake --build build --config Release --target install` and you'll found `nuklear.dll` inside "install" folder. + ## Documentation A complete description of all functions and style properties, alongside additional examples, is available at the [LÖVE-Nuklear wiki](https://github.com/keharriso/love-nuklear/wiki). diff --git a/cmake/FindLuaJIT.cmake b/cmake/FindLuaJIT.cmake index e8384e2..762526b 100644 --- a/cmake/FindLuaJIT.cmake +++ b/cmake/FindLuaJIT.cmake @@ -11,7 +11,7 @@ find_path(LUA_INCLUDE_DIR luajit.h HINTS ENV LUA_DIR - PATH_SUFFIXES include/luajit-2.0 include + PATH_SUFFIXES include/luajit-2.0 include/luajit-2.1 include/luajit-5_1-2.1 include PATHS ~/Library/Frameworks /Library/Frameworks diff --git a/example/closure.lua b/example/closure.lua new file mode 100644 index 0000000..754f7e7 --- /dev/null +++ b/example/closure.lua @@ -0,0 +1,51 @@ +-- Show off the optional closure-oriented versions of basic functions + +local function menu(ui) + ui:layoutRow('dynamic', 30, 2) + ui:menu('Menu A', nil, 100, 200, function () + ui:layoutRow('dynamic', 30, 1) + if ui:menuItem('Item 1') then + print 'Closure: Item 1' + end + if ui:menuItem('Item 2') then + print 'Closure: Item 2' + end + end) + ui:menu('Menu B', nil, 100, 200, function () + ui:layoutRow('dynamic', 30, 1) + if ui:menuItem('Item 3') then + print 'Closure: Item 3' + end + if ui:menuItem('Item 4') then + print 'Closure: Item 4' + end + end) +end + +local comboText = 'Combo 1' + +function combo(ui) + ui:layoutRow('dynamic', 30, 1) + if ui:comboboxItem('Combo 1') then + print 'Closure: Combo 1' + comboText = 'Combo 1' + end + if ui:comboboxItem('Combo 2') then + print 'Closure: Combo 2' + comboText = 'Combo 2' + end + if ui:comboboxItem('Combo 3') then + print 'Closure: Combo 3' + comboText = 'Combo 3' + end +end + +local function window(ui) + ui:menubar(menu) + ui:layoutRow('dynamic', 30, 1) + ui:combobox(comboText, combo) +end + +return function (ui) + ui:window('Closure', 200, 200, 150, 120, {'title', 'movable', 'border'}, window) +end diff --git a/example/draw.lua b/example/draw.lua index 3a5611b..5a93770 100644 --- a/example/draw.lua +++ b/example/draw.lua @@ -5,7 +5,7 @@ local img = love.graphics.newImage 'skin/button.png' return function (ui) if ui:windowBegin('Draw Example', 300, 300, 200, 200, 'title', 'movable', 'border') then local x, y, w, h = ui:windowGetBounds() - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 0, 0) ui:line(x + 10, y + 40, x + 50, y + 40, x + 50, y + 80) ui:curve(x + 50, y + 80, x + 80, y + 40, x + 100, y + 80, x + 80, y + 80) ui:polygon('line', x + 100, y + 150, x + 60, y + 140, x + 70, y + 70) @@ -13,7 +13,7 @@ return function (ui) ui:ellipse('fill', x + 30, y + 150, 20, 40) ui:arc('fill', x + 150, y + 80, 40, 3 * math.pi / 2, 2 * math.pi); ui:rectMultiColor(x + 95, y + 50, 50, 50, '#ff0000', '#00ff00', '#0000ff', '#000000') - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) ui:image(img, x + 120, y + 120, 70, 50) ui:text('DRAW TEXT', x + 15, y + 75, 100, 100) end diff --git a/example/main.lua b/example/main.lua index e9f021e..e335370 100644 --- a/example/main.lua +++ b/example/main.lua @@ -3,6 +3,7 @@ local nuklear = require 'nuklear' local calculator = require 'calculator' +local closure = require 'closure' local draw = require 'draw' local overview = require 'overview' local style = require 'style' @@ -13,6 +14,7 @@ local transform = require 'transform' local ui1, ui2 function love.load() + love.keyboard.setKeyRepeat(true) ui1, ui2 = nuklear.newUI(), nuklear.newUI() end @@ -20,6 +22,7 @@ function love.update(dt) ui1:frameBegin() calculator(ui1) style(ui1) + closure(ui1) overview(ui1) draw(ui1) template(ui1) @@ -33,7 +36,7 @@ end function love.draw() ui1:draw() ui2:draw() - love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10) + love.graphics.print('Current FPS: '..tostring(love.timer.getFPS( )), 10, 10) end local function input(name, ...) @@ -48,12 +51,12 @@ function love.keyreleased(key, scancode) input('keyreleased', key, scancode) end -function love.mousepressed(x, y, button, istouch) - input('mousepressed', x, y, button, istouch) +function love.mousepressed(x, y, button, istouch, presses) + input('mousepressed', x, y, button, istouch, presses) end -function love.mousereleased(x, y, button, istouch) - input('mousereleased', x, y, button, istouch) +function love.mousereleased(x, y, button, istouch, presses) + input('mousereleased', x, y, button, istouch, presses) end function love.mousemoved(x, y, dx, dy, istouch) diff --git a/example/overview.lua b/example/overview.lua index 5909c77..7c4ae28 100644 --- a/example/overview.lua +++ b/example/overview.lua @@ -11,6 +11,7 @@ local colorPicker = {value = '#ff0000'} local property = {value = 6} local edit = {value = 'Edit text'} local comboA = {value = 1, items = {'A', 'B', 'C'}} +local scissorActive = false return function (ui) if ui:windowBegin('Overview', 100, 100, 600, 450, 'border', 'movable', 'title') then @@ -49,6 +50,9 @@ return function (ui) ui:spacing(1) ui:checkbox('Checkbox A', checkA) ui:checkbox('Checkbox B', checkB) + if ui:button('Scissor') then + scissorActive = not scissorActive + end ui:groupEnd() end if ui:groupBegin('Group 2', 'border') then @@ -104,4 +108,11 @@ return function (ui) end end ui:windowEnd() + if(scissorActive) then + love.graphics.setScissor() + love.graphics.clear() + love.graphics.setScissor(130, 130, 500, 400) + else + love.graphics.setScissor() + end end diff --git a/src/nuklear b/src/nuklear index 181cfd8..614abce 160000 --- a/src/nuklear +++ b/src/nuklear @@ -1 +1 @@ -Subproject commit 181cfd86c47ae83eceabaf4e640587b844e613b6 +Subproject commit 614abce05b9455849bbf1519b7f86e53c78b04ab diff --git a/src/nuklear_love.c b/src/nuklear_love.c index 98faa4b..67d8380 100644 --- a/src/nuklear_love.c +++ b/src/nuklear_love.c @@ -8,6 +8,8 @@ #include #include +#define LUA_LIB + #include #include @@ -39,16 +41,24 @@ #define NK_LOVE_COMBOBOX_MAX_ITEMS 1024 #define NK_LOVE_MAX_FONTS 1024 #define NK_LOVE_MAX_RATIOS 1024 -#define NK_LOVE_GRADIENT_RESOLUTION 32 -static lua_State *L; static char *edit_buffer; static const char **combobox_items; static float *points; +struct nk_love_handle { + lua_State *L; + int ref; +}; + +struct nk_love_font { + struct nk_user_font font; + struct nk_love_handle handle; +}; + static struct nk_love_context { struct nk_context nkctx; - struct nk_user_font *fonts; + struct nk_love_font *fonts; int font_count; float *layout_ratios; int layout_ratio_count; @@ -57,7 +67,7 @@ static struct nk_love_context { int transform_allowed; } *context; -static void nk_love_assert(int pass, const char *msg) +static void nk_love_assert(lua_State *L, int pass, const char *msg) { if (!pass) { lua_Debug ar; @@ -70,24 +80,24 @@ static void nk_love_assert(int pass, const char *msg) } } -static void nk_love_assert_argc(int pass) +static void nk_love_assert_argc(lua_State *L, int pass) { - nk_love_assert(pass, "wrong number of arguments to '%s'"); + nk_love_assert(L, pass, "wrong number of arguments to '%s'"); } -static void nk_love_assert_alloc(void *mem) +static void nk_love_assert_alloc(lua_State *L, void *mem) { - nk_love_assert(mem != NULL, "out of memory in '%s'"); + nk_love_assert(L, mem != NULL, "out of memory in '%s'"); } -static void *nk_love_malloc(size_t size) +static void *nk_love_malloc(lua_State *L, size_t size) { void *mem = malloc(size); - nk_love_assert_alloc(mem); + nk_love_assert_alloc(L, mem); return mem; } -static struct nk_love_context *nk_love_checkcontext(int index) +static struct nk_love_context *nk_love_checkcontext(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -103,21 +113,21 @@ static struct nk_love_context *nk_love_checkcontext(int index) luaL_typerror(L, index, "Nuklear context"); } -static void nk_love_assert_context(int index) +static void nk_love_assert_context(lua_State *L, int index) { - struct nk_love_context *ctx = nk_love_checkcontext(index); + struct nk_love_context *ctx = nk_love_checkcontext(L, index); ctx->transform_allowed = 0; - nk_love_assert(ctx == context, "%s: UI calls must reside between ui:frameBegin and ui:frameEnd"); + nk_love_assert(L, ctx == context, "%s: UI calls must reside between ui:frameBegin and ui:frameEnd"); } -static void nk_love_assert_transform(void) +static void nk_love_assert_transform(lua_State *L) { - struct nk_love_context *ctx = nk_love_checkcontext(1); - nk_love_assert(ctx == context && ctx->transform_allowed, + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); + nk_love_assert(L, ctx == context && ctx->transform_allowed, "%s: UI transformations must occur directly after ui:frameBegin"); } -static void nk_love_pushregistry(const char *name) +static void nk_love_pushregistry(lua_State *L, const char *name) { lua_getfield(L, LUA_REGISTRYINDEX, "nuklear"); lua_pushlightuserdata(L, context); @@ -127,7 +137,7 @@ static void nk_love_pushregistry(const char *name) lua_pop(L, 1); } -static int nk_love_is_type(int index, const char *type) +static int nk_love_is_type(lua_State *L, int index, const char *type) { if (index < 0) index += lua_gettop(L) + 1; @@ -150,8 +160,10 @@ static int nk_love_is_type(int index, const char *type) static float nk_love_get_text_width(nk_handle handle, float height, const char *text, int len) { - nk_love_pushregistry("font"); - lua_rawgeti(L, -1, handle.id); + struct nk_love_handle *love_handle = handle.ptr; + lua_State *L = love_handle->L; + nk_love_pushregistry(L, "font"); + lua_rawgeti(L, -1, love_handle->ref); lua_getfield(L, -1, "getWidth"); lua_replace(L, -3); lua_pushlstring(L, text, len); @@ -161,30 +173,32 @@ static float nk_love_get_text_width(nk_handle handle, float height, return width; } -static void nk_love_checkFont(int index, struct nk_user_font *font) +static void nk_love_checkFont(lua_State *L, int index, struct nk_love_font *font) { if (index < 0) index += lua_gettop(L) + 1; - if (!nk_love_is_type(index, "Font")) + if (!nk_love_is_type(L, index, "Font")) luaL_typerror(L, index, "Font"); - nk_love_pushregistry("font"); + nk_love_pushregistry(L, "font"); lua_pushvalue(L, index); int ref = luaL_ref(L, -2); lua_getfield(L, index, "getHeight"); lua_pushvalue(L, index); lua_call(L, 1, 1); float height = lua_tonumber(L, -1); - font->userdata = nk_handle_id(ref); - font->height = height; - font->width = nk_love_get_text_width; + font->handle.L = L; + font->handle.ref = ref; + font->font.userdata.ptr = &font->handle; + font->font.height = height; + font->font.width = nk_love_get_text_width; lua_pop(L, 2); } -static void nk_love_checkImage(int index, struct nk_image *image) +static void nk_love_checkImage(lua_State *L, int index, struct nk_image *image) { if (index < 0) index += lua_gettop(L) + 1; - if (nk_love_is_type(index, "Image")) { + if (nk_love_is_type(L, index, "Image") || nk_love_is_type(L, index, "Canvas")) { lua_getglobal(L, "love"); lua_getfield(L, -1, "graphics"); lua_getfield(L, -1, "newQuad"); @@ -206,16 +220,16 @@ static void nk_love_checkImage(int index, struct nk_image *image) lua_createtable(L, 2, 0); lua_rawgeti(L, index, 2); lua_rawgeti(L, index, 1); - if (nk_love_is_type(-1, "Image") && nk_love_is_type(-2, "Quad")) { + if ((nk_love_is_type(L, -1, "Image") || nk_love_is_type(L, -1, "Canvas")) && nk_love_is_type(L, -2, "Quad")) { lua_rawseti(L, -3, 1); lua_rawseti(L, -2, 2); } else { - luaL_argerror(L, index, "expecting {Image, Quad}"); + luaL_argerror(L, index, "expecting {Image, Quad} or {Canvas, Quad}"); } } else { - luaL_argerror(L, index, "expecting Image or {Image, Quad}"); + luaL_argerror(L, index, "expecting Image or Canvas or {Image, Quad} or {Canvas, Quad}"); } - nk_love_pushregistry("image"); + nk_love_pushregistry(L, "image"); lua_pushvalue(L, -2); int ref = luaL_ref(L, -2); image->handle = nk_handle_id(ref); @@ -229,7 +243,7 @@ static int nk_love_is_hex(char c) || (c >= 'A' && c <= 'F'); } -static int nk_love_is_color(int index) +static int nk_love_is_color(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -248,11 +262,11 @@ static int nk_love_is_color(int index) return 0; } -static struct nk_color nk_love_checkcolor(int index) +static struct nk_color nk_love_checkcolor(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; - if (!nk_love_is_color(index)) { + if (!nk_love_is_color(L, index)) { if (lua_isstring(L, index)){ const char *msg = lua_pushfstring(L, "bad color string '%s'", lua_tostring(L, index)); luaL_argerror(L, index, msg); @@ -271,8 +285,8 @@ static struct nk_color nk_love_checkcolor(int index) return color; } -static struct nk_colorf nk_love_checkcolorf(int index) { - return nk_color_cf(nk_love_checkcolor(index)); +static struct nk_colorf nk_love_checkcolorf(lua_State *L, int index) { + return nk_color_cf(nk_love_checkcolor(L, index)); } static void nk_love_color(int r, int g, int b, int a, char *color_string) @@ -290,12 +304,20 @@ static void nk_love_color(int r, int g, int b, int a, char *color_string) sprintf(color_string, format_string, r, g, b, a); } -static nk_flags nk_love_parse_window_flags(int flags_begin) +static nk_flags nk_love_parse_window_flags(lua_State *L, int flags_begin, int flags_end) { - int argc = lua_gettop(L); - nk_flags flags = NK_WINDOW_NO_SCROLLBAR; int i; - for (i = flags_begin; i <= argc; ++i) { + if (flags_begin == flags_end && lua_istable(L, flags_begin)) { + size_t flagCount = lua_objlen(L, flags_begin); + nk_love_assert(L, lua_checkstack(L, flagCount), "%s: failed to allocate stack space"); + for (i = 1; i <= flagCount; ++i) { + lua_rawgeti(L, flags_begin, i); + } + lua_remove(L, flags_begin); + flags_end = flags_begin + flagCount - 1; + } + nk_flags flags = NK_WINDOW_NO_SCROLLBAR; + for (i = flags_begin; i <= flags_end; ++i) { const char *flag = luaL_checkstring(L, i); if (!strcmp(flag, "border")) flags |= NK_WINDOW_BORDER; @@ -323,7 +345,7 @@ static nk_flags nk_love_parse_window_flags(int flags_begin) return flags; } -static enum nk_symbol_type nk_love_checksymbol(int index) +static enum nk_symbol_type nk_love_checksymbol(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -362,7 +384,7 @@ static enum nk_symbol_type nk_love_checksymbol(int index) } } -static nk_flags nk_love_checkalign(int index) +static nk_flags nk_love_checkalign(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -391,7 +413,7 @@ static nk_flags nk_love_checkalign(int index) } } -static enum nk_buttons nk_love_checkbutton(int index) +static enum nk_buttons nk_love_checkbutton(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -408,7 +430,7 @@ static enum nk_buttons nk_love_checkbutton(int index) } } -static enum nk_layout_format nk_love_checkformat(int index) +static enum nk_layout_format nk_love_checkformat(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -423,7 +445,7 @@ static enum nk_layout_format nk_love_checkformat(int index) } } -static enum nk_tree_type nk_love_checktree(int index) +static enum nk_tree_type nk_love_checktree(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -438,7 +460,7 @@ static enum nk_tree_type nk_love_checktree(int index) } } -static enum nk_collapse_states nk_love_checkstate(int index) +static enum nk_collapse_states nk_love_checkstate(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -453,7 +475,7 @@ static enum nk_collapse_states nk_love_checkstate(int index) } } -static enum nk_button_behavior nk_love_checkbehavior(int index) +static enum nk_button_behavior nk_love_checkbehavior(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -468,7 +490,7 @@ static enum nk_button_behavior nk_love_checkbehavior(int index) } } -static enum nk_color_format nk_love_checkcolorformat(int index) +static enum nk_color_format nk_love_checkcolorformat(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -483,7 +505,7 @@ static enum nk_color_format nk_love_checkcolorformat(int index) } } -static nk_flags nk_love_checkedittype(int index) +static nk_flags nk_love_checkedittype(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -500,7 +522,7 @@ static nk_flags nk_love_checkedittype(int index) } } -static enum nk_popup_type nk_love_checkpopup(int index) +static enum nk_popup_type nk_love_checkpopup(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -517,7 +539,7 @@ static enum nk_popup_type nk_love_checkpopup(int index) enum nk_love_draw_mode {NK_LOVE_FILL, NK_LOVE_LINE}; -static enum nk_love_draw_mode nk_love_checkdraw(int index) +static enum nk_love_draw_mode nk_love_checkdraw(lua_State *L, int index) { if (index < 0) index += lua_gettop(L) + 1; @@ -557,7 +579,7 @@ static void nk_love_transform(float *T, int *x, int *y) * =============================================================== */ -static void nk_love_configureGraphics(int line_thickness, struct nk_color col) +static void nk_love_configureGraphics(lua_State *L, int line_thickness, struct nk_color col) { lua_getglobal(L, "love"); lua_getfield(L, -1, "graphics"); @@ -575,7 +597,7 @@ static void nk_love_configureGraphics(int line_thickness, struct nk_color col) lua_call(L, 4, 0); } -static void nk_love_getGraphics(float *line_thickness, struct nk_color *color) +static void nk_love_getGraphics(lua_State *L, float *line_thickness, struct nk_color *color) { lua_getglobal(L, "love"); lua_getfield(L, -1, "graphics"); @@ -592,7 +614,8 @@ static void nk_love_getGraphics(float *line_thickness, struct nk_color *color) lua_pop(L, 6); } -static void nk_love_scissor(int x, int y, int w, int h) +static void nk_love_scissor(lua_State *L, int x, int y, int w, int h, + int nested, int px, int py, int pw, int ph) { lua_getglobal(L, "love"); lua_getfield(L, -1, "graphics"); @@ -606,18 +629,24 @@ static void nk_love_scissor(int x, int y, int w, int h) int top = NK_MIN(NK_MIN(y1, y2), NK_MIN(y3, y4)); int right = NK_MAX(NK_MAX(x1, x2), NK_MAX(x3, x4)); int bottom = NK_MAX(NK_MAX(y1, y2), NK_MAX(y3, y4)); + if (nested) { + left = NK_MAX(left, px); + top = NK_MAX(top, py); + right = NK_MIN(right, px + pw); + bottom = NK_MIN(bottom, py + ph); + } lua_pushnumber(L, left); lua_pushnumber(L, top); - lua_pushnumber(L, right - left); - lua_pushnumber(L, bottom - top); + lua_pushnumber(L, NK_MAX(0, right - left)); + lua_pushnumber(L, NK_MAX(0, bottom - top)); lua_call(L, 4, 0); lua_pop(L, 2); } -static void nk_love_draw_line(int x0, int y0, int x1, int y1, +static void nk_love_draw_line(lua_State *L, int x0, int y0, int x1, int y1, int line_thickness, struct nk_color col) { - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "line"); lua_pushnumber(L, x0 + 0.5); lua_pushnumber(L, y0 + 0.5); @@ -627,11 +656,11 @@ static void nk_love_draw_line(int x0, int y0, int x1, int y1, lua_pop(L, 1); } -static void nk_love_draw_rect(int x, int y, unsigned int w, +static void nk_love_draw_rect(lua_State *L, int x, int y, unsigned int w, unsigned int h, unsigned int r, int line_thickness, struct nk_color col) { - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "rectangle"); if (line_thickness >= 0) lua_pushstring(L, "line"); @@ -647,10 +676,10 @@ static void nk_love_draw_rect(int x, int y, unsigned int w, lua_pop(L, 1); } -static void nk_love_draw_triangle(int x0, int y0, int x1, int y1, +static void nk_love_draw_triangle(lua_State *L, int x0, int y0, int x1, int y1, int x2, int y2, int line_thickness, struct nk_color col) { - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "polygon"); if (line_thickness >= 0) lua_pushstring(L, "line"); @@ -666,10 +695,10 @@ static void nk_love_draw_triangle(int x0, int y0, int x1, int y1, lua_pop(L, 1); } -static void nk_love_draw_polygon(const struct nk_vec2i *pnts, int count, +static void nk_love_draw_polygon(lua_State *L, const struct nk_vec2i *pnts, int count, int line_thickness, struct nk_color col) { - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "polygon"); if (line_thickness >= 0) lua_pushstring(L, "line"); @@ -684,10 +713,10 @@ static void nk_love_draw_polygon(const struct nk_vec2i *pnts, int count, lua_pop(L, 1); } -static void nk_love_draw_polyline(const struct nk_vec2i *pnts, +static void nk_love_draw_polyline(lua_State *L, const struct nk_vec2i *pnts, int count, int line_thickness, struct nk_color col) { - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "line"); int i; for (i = 0; (i < count) && (i < NK_LOVE_MAX_POINTS); ++i) { @@ -698,10 +727,10 @@ static void nk_love_draw_polyline(const struct nk_vec2i *pnts, lua_pop(L, 1); } -static void nk_love_draw_circle(int x, int y, unsigned int w, +static void nk_love_draw_circle(lua_State *L, int x, int y, unsigned int w, unsigned int h, int line_thickness, struct nk_color col) { - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "ellipse"); if (line_thickness >= 0) lua_pushstring(L, "line"); @@ -715,7 +744,7 @@ static void nk_love_draw_circle(int x, int y, unsigned int w, lua_pop(L, 1); } -static void nk_love_draw_curve(struct nk_vec2i p1, struct nk_vec2i p2, +static void nk_love_draw_curve(lua_State *L, struct nk_vec2i p1, struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4, unsigned int num_segments, int line_thickness, struct nk_color col) { @@ -726,7 +755,7 @@ static void nk_love_draw_curve(struct nk_vec2i p1, struct nk_vec2i p2, if (num_segments < 1) num_segments = 1; t_step = 1.0f/(float)num_segments; - nk_love_configureGraphics(line_thickness, col); + nk_love_configureGraphics(L, line_thickness, col); lua_getfield(L, -1, "line"); for (i_step = 1; i_step <= num_segments; ++i_step) { float t = t_step * (float)i_step; @@ -744,7 +773,7 @@ static void nk_love_draw_curve(struct nk_vec2i p1, struct nk_vec2i p2, lua_pop(L, 1); } -static void nk_love_draw_text(int fontref, struct nk_color cbg, +static void nk_love_draw_text(lua_State *L, int fontref, struct nk_color cbg, struct nk_color cfg, int x, int y, unsigned int w, unsigned int h, float height, int len, const char *text) { @@ -774,7 +803,7 @@ static void nk_love_draw_text(int fontref, struct nk_color cbg, lua_call(L, 4, 0); lua_getfield(L, -1, "setFont"); - nk_love_pushregistry("font"); + nk_love_pushregistry(L, "font"); lua_rawgeti(L, -1, fontref); lua_replace(L, -2); lua_call(L, 1, 0); @@ -802,7 +831,7 @@ static void interpolate_color(struct nk_color c1, struct nk_color c2, result->a = (nk_byte)NK_CLAMP(0, a, 255); } -static void nk_love_draw_rect_multi_color(int x, int y, unsigned int w, +static void nk_love_draw_rect_multi_color(lua_State *L, int x, int y, unsigned int w, unsigned int h, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom) { @@ -858,12 +887,12 @@ static void nk_love_draw_rect_multi_color(int x, int y, unsigned int w, lua_pop(L, 2); } -static void nk_love_draw_image(int x, int y, unsigned int w, unsigned int h, +static void nk_love_draw_image(lua_State *L, int x, int y, unsigned int w, unsigned int h, struct nk_image image, struct nk_color color) { - nk_love_configureGraphics(-1, color); + nk_love_configureGraphics(L, -1, color); lua_getfield(L, -1, "draw"); - nk_love_pushregistry("image"); + nk_love_pushregistry(L, "image"); lua_rawgeti(L, -1, image.handle.id); lua_rawgeti(L, -1, 1); lua_replace(L, -3); @@ -884,10 +913,10 @@ static void nk_love_draw_image(int x, int y, unsigned int w, unsigned int h, lua_pop(L, 1); } -static void nk_love_draw_arc(int cx, int cy, unsigned int r, +static void nk_love_draw_arc(lua_State *L, int cx, int cy, unsigned int r, int line_thickness, float a1, float a2, struct nk_color color) { - nk_love_configureGraphics(line_thickness, color); + nk_love_configureGraphics(L, line_thickness, color); lua_getfield(L, -1, "arc"); if (line_thickness >= 0) lua_pushstring(L, "line"); @@ -912,7 +941,7 @@ static void nk_love_draw_arc(int cx, int cy, unsigned int r, static void nk_love_clipboard_paste(nk_handle usr, struct nk_text_edit *edit) { - (void)usr; + lua_State *L = usr.ptr; lua_getglobal(L, "love"); lua_getfield(L, -1, "system"); lua_getfield(L, -1, "getClipboardText"); @@ -924,7 +953,7 @@ static void nk_love_clipboard_paste(nk_handle usr, struct nk_text_edit *edit) static void nk_love_clipboard_copy(nk_handle usr, const char *text, int len) { - (void)usr; + lua_State *L = usr.ptr; char *str = 0; if (!len) return; str = (char*)malloc((size_t)len+1); @@ -964,7 +993,7 @@ static int nk_love_is_active(struct nk_context *ctx) return 0; } -static int nk_love_keyevent(struct nk_context *ctx, const char *key, +static int nk_love_keyevent(lua_State *L, struct nk_context *ctx, const char *key, const char *scancode, int isrepeat, int down) { lua_getglobal(L, "love"); @@ -1027,7 +1056,7 @@ static int nk_love_keyevent(struct nk_context *ctx, const char *key, } static int nk_love_clickevent(struct nk_love_context *ctx, int x, int y, - int button, int istouch, int down) + int button, int istouch, int presses, int down) { nk_love_transform(ctx->Ti, &x, &y); struct nk_context *nkctx = &ctx->nkctx; @@ -1078,10 +1107,10 @@ static int nk_love_wheelmoved_event(struct nk_context *ctx, int x, int y) static int nk_love_new_ui(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 0); + nk_love_assert_argc(L, lua_gettop(L) == 0); lua_getfield(L, LUA_REGISTRYINDEX, "nuklear"); struct nk_love_context *ctx = lua_newuserdata(L, sizeof(struct nk_love_context)); - nk_love_assert_alloc(ctx); + nk_love_assert_alloc(L, ctx); lua_pushlightuserdata(L, ctx); lua_newtable(L); lua_newtable(L); @@ -1093,31 +1122,31 @@ static int nk_love_new_ui(lua_State *L) lua_settable(L, -4); lua_getfield(L, -2, "metatable"); lua_setmetatable(L, -2); - ctx->fonts = nk_love_malloc(sizeof(struct nk_user_font) * NK_LOVE_MAX_FONTS); + ctx->fonts = nk_love_malloc(L, sizeof(struct nk_love_font) * NK_LOVE_MAX_FONTS); lua_getglobal(L, "love"); - nk_love_assert(lua_istable(L, -1), "LOVE-Nuklear requires LOVE environment"); + nk_love_assert(L, lua_istable(L, -1), "LOVE-Nuklear requires LOVE environment"); lua_getfield(L, -1, "graphics"); lua_getfield(L, -1, "getFont"); lua_call(L, 0, 1); struct nk_love_context *current = context; context = ctx; - nk_love_checkFont(-1, &ctx->fonts[0]); + nk_love_checkFont(L, -1, &ctx->fonts[0]); context = current; - nk_init_default(&ctx->nkctx, &ctx->fonts[0]); + nk_init_default(&ctx->nkctx, &ctx->fonts[0].font); ctx->font_count = 1; ctx->nkctx.clip.copy = nk_love_clipboard_copy; ctx->nkctx.clip.paste = nk_love_clipboard_paste; - ctx->nkctx.clip.userdata = nk_handle_ptr(0); - ctx->layout_ratios = nk_love_malloc(sizeof(float) * NK_LOVE_MAX_RATIOS); + ctx->nkctx.clip.userdata = nk_handle_ptr(L); + ctx->layout_ratios = nk_love_malloc(L, sizeof(float) * NK_LOVE_MAX_RATIOS); ctx->layout_ratio_count = 0; lua_pop(L, 3); return 1; } -static int nk_love_destroy(lua_State *luaState) +static int nk_love_destroy(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); nk_free(&ctx->nkctx); free(ctx->fonts); free(ctx->layout_ratios); @@ -1130,57 +1159,59 @@ static int nk_love_destroy(lua_State *luaState) static int nk_love_keypressed(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 4); - struct nk_context *ctx = &nk_love_checkcontext(1)->nkctx; + nk_love_assert_argc(L, lua_gettop(L) == 4); + struct nk_context *ctx = &nk_love_checkcontext(L, 1)->nkctx; const char *key = luaL_checkstring(L, 2); const char *scancode = luaL_checkstring(L, 3); int isrepeat = nk_love_checkboolean(L, 4); - int consume = nk_love_keyevent(ctx, key, scancode, isrepeat, 1); + int consume = nk_love_keyevent(L, ctx, key, scancode, isrepeat, 1); lua_pushboolean(L, consume); return 1; } static int nk_love_keyreleased(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - struct nk_context *ctx = &nk_love_checkcontext(1)->nkctx; + nk_love_assert_argc(L, lua_gettop(L) == 3); + struct nk_context *ctx = &nk_love_checkcontext(L, 1)->nkctx; const char *key = luaL_checkstring(L, 2); const char *scancode = luaL_checkstring(L, 3); - int consume = nk_love_keyevent(ctx, key, scancode, 0, 0); + int consume = nk_love_keyevent(L, ctx, key, scancode, 0, 0); lua_pushboolean(L, consume); return 1; } static int nk_love_mousepressed(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 5 || lua_gettop(L) == 6); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); int button = luaL_checkint(L, 4); int istouch = nk_love_checkboolean(L, 5); - int consume = nk_love_clickevent(ctx, x, y, button, istouch, 1); + int presses = lua_gettop(L) == 6 ? luaL_checkint(L, 6) : 1; + int consume = nk_love_clickevent(ctx, x, y, button, istouch, presses, 1); lua_pushboolean(L, consume); return 1; } static int nk_love_mousereleased(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 5 || lua_gettop(L) == 6); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); int button = luaL_checkint(L, 4); int istouch = nk_love_checkboolean(L, 5); - int consume = nk_love_clickevent(ctx, x, y, button, istouch, 0); + int presses = lua_gettop(L) == 6 ? luaL_checkint(L, 6) : 1; + int consume = nk_love_clickevent(ctx, x, y, button, istouch, presses, 0); lua_pushboolean(L, consume); return 1; } static int nk_love_mousemoved(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 6); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 6); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); int dx = luaL_checkint(L, 4); @@ -1193,8 +1224,8 @@ static int nk_love_mousemoved(lua_State *L) static int nk_love_textinput(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - struct nk_context *ctx = &nk_love_checkcontext(1)->nkctx; + nk_love_assert_argc(L, lua_gettop(L) == 2); + struct nk_context *ctx = &nk_love_checkcontext(L, 1)->nkctx; const char *text = luaL_checkstring(L, 2); int consume = nk_love_textinput_event(ctx, text); lua_pushboolean(L, consume); @@ -1203,8 +1234,8 @@ static int nk_love_textinput(lua_State *L) static int nk_love_wheelmoved(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - struct nk_context *ctx = &nk_love_checkcontext(1)->nkctx; + nk_love_assert_argc(L, lua_gettop(L) == 3); + struct nk_context *ctx = &nk_love_checkcontext(L, 1)->nkctx; int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); int consume = nk_love_wheelmoved_event(ctx, x, y); @@ -1214,8 +1245,8 @@ static int nk_love_wheelmoved(lua_State *L) static int nk_love_draw(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - context = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + context = nk_love_checkcontext(L, 1); lua_getglobal(L, "love"); lua_getfield(L, -1, "graphics"); @@ -1227,7 +1258,20 @@ static int nk_love_draw(lua_State *L) lua_getfield(L, -1, "origin"); lua_call(L, 0, 0); - nk_love_pushregistry("transform"); + int nest_scissor = 0; + int px = 0, py = 0, pw = 0, ph = 0; + lua_getfield(L, -1, "getScissor"); + lua_call(L, 0, 4); + if (lua_isnumber(L, -4)) { + nest_scissor = 1; + px = lua_tonumber(L, -4); + py = lua_tonumber(L, -3); + pw = lua_tonumber(L, -2); + ph = lua_tonumber(L, -1); + } + lua_pop(L, 4); + + nk_love_pushregistry(L, "transform"); size_t transform_count = lua_objlen(L, -1); size_t i, j; for (i = 1; i <= transform_count; ++i) { @@ -1249,78 +1293,79 @@ static int nk_love_draw(lua_State *L) case NK_COMMAND_NOP: break; case NK_COMMAND_SCISSOR: { const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd; - nk_love_scissor(s->x, s->y, s->w, s->h); + nk_love_scissor(L, s->x, s->y, s->w, s->h, nest_scissor, px, py, pw, ph); } break; case NK_COMMAND_LINE: { const struct nk_command_line *l = (const struct nk_command_line *)cmd; - nk_love_draw_line(l->begin.x, l->begin.y, l->end.x, + nk_love_draw_line(L, l->begin.x, l->begin.y, l->end.x, l->end.y, l->line_thickness, l->color); } break; case NK_COMMAND_RECT: { const struct nk_command_rect *r = (const struct nk_command_rect *)cmd; - nk_love_draw_rect(r->x, r->y, r->w, r->h, + nk_love_draw_rect(L, r->x, r->y, r->w, r->h, (unsigned int)r->rounding, r->line_thickness, r->color); } break; case NK_COMMAND_RECT_FILLED: { const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd; - nk_love_draw_rect(r->x, r->y, r->w, r->h, (unsigned int)r->rounding, -1, r->color); + nk_love_draw_rect(L, r->x, r->y, r->w, r->h, (unsigned int)r->rounding, -1, r->color); } break; case NK_COMMAND_CIRCLE: { const struct nk_command_circle *c = (const struct nk_command_circle *)cmd; - nk_love_draw_circle(c->x, c->y, c->w, c->h, c->line_thickness, c->color); + nk_love_draw_circle(L, c->x, c->y, c->w, c->h, c->line_thickness, c->color); } break; case NK_COMMAND_CIRCLE_FILLED: { const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; - nk_love_draw_circle(c->x, c->y, c->w, c->h, -1, c->color); + nk_love_draw_circle(L, c->x, c->y, c->w, c->h, -1, c->color); } break; case NK_COMMAND_TRIANGLE: { const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd; - nk_love_draw_triangle(t->a.x, t->a.y, t->b.x, t->b.y, + nk_love_draw_triangle(L, t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, t->line_thickness, t->color); } break; case NK_COMMAND_TRIANGLE_FILLED: { const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd; - nk_love_draw_triangle(t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, -1, t->color); + nk_love_draw_triangle(L, t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, -1, t->color); } break; case NK_COMMAND_POLYGON: { const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd; - nk_love_draw_polygon(p->points, p->point_count, p->line_thickness, p->color); + nk_love_draw_polygon(L, p->points, p->point_count, p->line_thickness, p->color); } break; case NK_COMMAND_POLYGON_FILLED: { const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd; - nk_love_draw_polygon(p->points, p->point_count, -1, p->color); + nk_love_draw_polygon(L, p->points, p->point_count, -1, p->color); } break; case NK_COMMAND_POLYLINE: { const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd; - nk_love_draw_polyline(p->points, p->point_count, p->line_thickness, p->color); + nk_love_draw_polyline(L, p->points, p->point_count, p->line_thickness, p->color); } break; case NK_COMMAND_TEXT: { const struct nk_command_text *t = (const struct nk_command_text*)cmd; - nk_love_draw_text(t->font->userdata.id, t->background, + struct nk_love_handle *love_handle = t->font->userdata.ptr; + nk_love_draw_text(love_handle->L, love_handle->ref, t->background, t->foreground, t->x, t->y, t->w, t->h, t->height, t->length, (const char*)t->string); } break; case NK_COMMAND_CURVE: { const struct nk_command_curve *q = (const struct nk_command_curve *)cmd; - nk_love_draw_curve(q->begin, q->ctrl[0], q->ctrl[1], + nk_love_draw_curve(L, q->begin, q->ctrl[0], q->ctrl[1], q->end, 22, q->line_thickness, q->color); } break; case NK_COMMAND_RECT_MULTI_COLOR: { const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd; - nk_love_draw_rect_multi_color(r->x, r->y, r->w, r->h, r->left, r->top, r->bottom, r->right); + nk_love_draw_rect_multi_color(L, r->x, r->y, r->w, r->h, r->left, r->top, r->bottom, r->right); } break; case NK_COMMAND_IMAGE: { const struct nk_command_image *i = (const struct nk_command_image *)cmd; - nk_love_draw_image(i->x, i->y, i->w, i->h, i->img, i->col); + nk_love_draw_image(L, i->x, i->y, i->w, i->h, i->img, i->col); } break; case NK_COMMAND_ARC: { const struct nk_command_arc *a = (const struct nk_command_arc *)cmd; - nk_love_draw_arc(a->cx, a->cy, a->r, a->line_thickness, + nk_love_draw_arc(L, a->cx, a->cy, a->r, a->line_thickness, a->a[0], a->a[1], a->color); } break; case NK_COMMAND_ARC_FILLED: { const struct nk_command_arc_filled *a = (const struct nk_command_arc_filled *)cmd; - nk_love_draw_arc(a->cx, a->cy, a->r, -1, a->a[0], a->a[1], a->color); + nk_love_draw_arc(L, a->cx, a->cy, a->r, -1, a->a[0], a->a[1], a->color); } break; default: break; } @@ -1334,140 +1379,140 @@ static int nk_love_draw(lua_State *L) return 0; } -static void nk_love_preserve(struct nk_style_item *item) +static void nk_love_preserve(lua_State *L, struct nk_style_item *item) { if (item->type == NK_STYLE_ITEM_IMAGE) { lua_rawgeti(L, -1, item->data.image.handle.id); - nk_love_checkImage(-1, &item->data.image); + nk_love_checkImage(L, -1, &item->data.image); lua_pop(L, 1); } } -static void nk_love_preserve_all(void) +static void nk_love_preserve_all(lua_State *L) { - nk_love_preserve(&context->nkctx.style.button.normal); - nk_love_preserve(&context->nkctx.style.button.hover); - nk_love_preserve(&context->nkctx.style.button.active); + nk_love_preserve(L, &context->nkctx.style.button.normal); + nk_love_preserve(L, &context->nkctx.style.button.hover); + nk_love_preserve(L, &context->nkctx.style.button.active); - nk_love_preserve(&context->nkctx.style.contextual_button.normal); - nk_love_preserve(&context->nkctx.style.contextual_button.hover); - nk_love_preserve(&context->nkctx.style.contextual_button.active); + nk_love_preserve(L, &context->nkctx.style.contextual_button.normal); + nk_love_preserve(L, &context->nkctx.style.contextual_button.hover); + nk_love_preserve(L, &context->nkctx.style.contextual_button.active); - nk_love_preserve(&context->nkctx.style.menu_button.normal); - nk_love_preserve(&context->nkctx.style.menu_button.hover); - nk_love_preserve(&context->nkctx.style.menu_button.active); + nk_love_preserve(L, &context->nkctx.style.menu_button.normal); + nk_love_preserve(L, &context->nkctx.style.menu_button.hover); + nk_love_preserve(L, &context->nkctx.style.menu_button.active); - nk_love_preserve(&context->nkctx.style.option.normal); - nk_love_preserve(&context->nkctx.style.option.hover); - nk_love_preserve(&context->nkctx.style.option.active); - nk_love_preserve(&context->nkctx.style.option.cursor_normal); - nk_love_preserve(&context->nkctx.style.option.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.option.normal); + nk_love_preserve(L, &context->nkctx.style.option.hover); + nk_love_preserve(L, &context->nkctx.style.option.active); + nk_love_preserve(L, &context->nkctx.style.option.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.option.cursor_hover); - nk_love_preserve(&context->nkctx.style.checkbox.normal); - nk_love_preserve(&context->nkctx.style.checkbox.hover); - nk_love_preserve(&context->nkctx.style.checkbox.active); - nk_love_preserve(&context->nkctx.style.checkbox.cursor_normal); - nk_love_preserve(&context->nkctx.style.checkbox.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.checkbox.normal); + nk_love_preserve(L, &context->nkctx.style.checkbox.hover); + nk_love_preserve(L, &context->nkctx.style.checkbox.active); + nk_love_preserve(L, &context->nkctx.style.checkbox.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.checkbox.cursor_hover); - nk_love_preserve(&context->nkctx.style.selectable.normal); - nk_love_preserve(&context->nkctx.style.selectable.hover); - nk_love_preserve(&context->nkctx.style.selectable.pressed); - nk_love_preserve(&context->nkctx.style.selectable.normal_active); - nk_love_preserve(&context->nkctx.style.selectable.hover_active); - nk_love_preserve(&context->nkctx.style.selectable.pressed_active); + nk_love_preserve(L, &context->nkctx.style.selectable.normal); + nk_love_preserve(L, &context->nkctx.style.selectable.hover); + nk_love_preserve(L, &context->nkctx.style.selectable.pressed); + nk_love_preserve(L, &context->nkctx.style.selectable.normal_active); + nk_love_preserve(L, &context->nkctx.style.selectable.hover_active); + nk_love_preserve(L, &context->nkctx.style.selectable.pressed_active); - nk_love_preserve(&context->nkctx.style.slider.normal); - nk_love_preserve(&context->nkctx.style.slider.hover); - nk_love_preserve(&context->nkctx.style.slider.active); - nk_love_preserve(&context->nkctx.style.slider.cursor_normal); - nk_love_preserve(&context->nkctx.style.slider.cursor_hover); - nk_love_preserve(&context->nkctx.style.slider.cursor_active); + nk_love_preserve(L, &context->nkctx.style.slider.normal); + nk_love_preserve(L, &context->nkctx.style.slider.hover); + nk_love_preserve(L, &context->nkctx.style.slider.active); + nk_love_preserve(L, &context->nkctx.style.slider.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.slider.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.slider.cursor_active); - nk_love_preserve(&context->nkctx.style.progress.normal); - nk_love_preserve(&context->nkctx.style.progress.hover); - nk_love_preserve(&context->nkctx.style.progress.active); - nk_love_preserve(&context->nkctx.style.progress.cursor_normal); - nk_love_preserve(&context->nkctx.style.progress.cursor_hover); - nk_love_preserve(&context->nkctx.style.progress.cursor_active); + nk_love_preserve(L, &context->nkctx.style.progress.normal); + nk_love_preserve(L, &context->nkctx.style.progress.hover); + nk_love_preserve(L, &context->nkctx.style.progress.active); + nk_love_preserve(L, &context->nkctx.style.progress.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.progress.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.progress.cursor_active); - nk_love_preserve(&context->nkctx.style.property.normal); - nk_love_preserve(&context->nkctx.style.property.hover); - nk_love_preserve(&context->nkctx.style.property.active); - nk_love_preserve(&context->nkctx.style.property.edit.normal); - nk_love_preserve(&context->nkctx.style.property.edit.hover); - nk_love_preserve(&context->nkctx.style.property.edit.active); - nk_love_preserve(&context->nkctx.style.property.inc_button.normal); - nk_love_preserve(&context->nkctx.style.property.inc_button.hover); - nk_love_preserve(&context->nkctx.style.property.inc_button.active); - nk_love_preserve(&context->nkctx.style.property.dec_button.normal); - nk_love_preserve(&context->nkctx.style.property.dec_button.hover); - nk_love_preserve(&context->nkctx.style.property.dec_button.active); + nk_love_preserve(L, &context->nkctx.style.property.normal); + nk_love_preserve(L, &context->nkctx.style.property.hover); + nk_love_preserve(L, &context->nkctx.style.property.active); + nk_love_preserve(L, &context->nkctx.style.property.edit.normal); + nk_love_preserve(L, &context->nkctx.style.property.edit.hover); + nk_love_preserve(L, &context->nkctx.style.property.edit.active); + nk_love_preserve(L, &context->nkctx.style.property.inc_button.normal); + nk_love_preserve(L, &context->nkctx.style.property.inc_button.hover); + nk_love_preserve(L, &context->nkctx.style.property.inc_button.active); + nk_love_preserve(L, &context->nkctx.style.property.dec_button.normal); + nk_love_preserve(L, &context->nkctx.style.property.dec_button.hover); + nk_love_preserve(L, &context->nkctx.style.property.dec_button.active); - nk_love_preserve(&context->nkctx.style.edit.normal); - nk_love_preserve(&context->nkctx.style.edit.hover); - nk_love_preserve(&context->nkctx.style.edit.active); - nk_love_preserve(&context->nkctx.style.edit.scrollbar.normal); - nk_love_preserve(&context->nkctx.style.edit.scrollbar.hover); - nk_love_preserve(&context->nkctx.style.edit.scrollbar.active); - nk_love_preserve(&context->nkctx.style.edit.scrollbar.cursor_normal); - nk_love_preserve(&context->nkctx.style.edit.scrollbar.cursor_hover); - nk_love_preserve(&context->nkctx.style.edit.scrollbar.cursor_active); + nk_love_preserve(L, &context->nkctx.style.edit.normal); + nk_love_preserve(L, &context->nkctx.style.edit.hover); + nk_love_preserve(L, &context->nkctx.style.edit.active); + nk_love_preserve(L, &context->nkctx.style.edit.scrollbar.normal); + nk_love_preserve(L, &context->nkctx.style.edit.scrollbar.hover); + nk_love_preserve(L, &context->nkctx.style.edit.scrollbar.active); + nk_love_preserve(L, &context->nkctx.style.edit.scrollbar.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.edit.scrollbar.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.edit.scrollbar.cursor_active); - nk_love_preserve(&context->nkctx.style.chart.background); + nk_love_preserve(L, &context->nkctx.style.chart.background); - nk_love_preserve(&context->nkctx.style.scrollh.normal); - nk_love_preserve(&context->nkctx.style.scrollh.hover); - nk_love_preserve(&context->nkctx.style.scrollh.active); - nk_love_preserve(&context->nkctx.style.scrollh.cursor_normal); - nk_love_preserve(&context->nkctx.style.scrollh.cursor_hover); - nk_love_preserve(&context->nkctx.style.scrollh.cursor_active); + nk_love_preserve(L, &context->nkctx.style.scrollh.normal); + nk_love_preserve(L, &context->nkctx.style.scrollh.hover); + nk_love_preserve(L, &context->nkctx.style.scrollh.active); + nk_love_preserve(L, &context->nkctx.style.scrollh.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.scrollh.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.scrollh.cursor_active); - nk_love_preserve(&context->nkctx.style.scrollv.normal); - nk_love_preserve(&context->nkctx.style.scrollv.hover); - nk_love_preserve(&context->nkctx.style.scrollv.active); - nk_love_preserve(&context->nkctx.style.scrollv.cursor_normal); - nk_love_preserve(&context->nkctx.style.scrollv.cursor_hover); - nk_love_preserve(&context->nkctx.style.scrollv.cursor_active); + nk_love_preserve(L, &context->nkctx.style.scrollv.normal); + nk_love_preserve(L, &context->nkctx.style.scrollv.hover); + nk_love_preserve(L, &context->nkctx.style.scrollv.active); + nk_love_preserve(L, &context->nkctx.style.scrollv.cursor_normal); + nk_love_preserve(L, &context->nkctx.style.scrollv.cursor_hover); + nk_love_preserve(L, &context->nkctx.style.scrollv.cursor_active); - nk_love_preserve(&context->nkctx.style.tab.background); - nk_love_preserve(&context->nkctx.style.tab.tab_maximize_button.normal); - nk_love_preserve(&context->nkctx.style.tab.tab_maximize_button.hover); - nk_love_preserve(&context->nkctx.style.tab.tab_maximize_button.active); - nk_love_preserve(&context->nkctx.style.tab.tab_minimize_button.normal); - nk_love_preserve(&context->nkctx.style.tab.tab_minimize_button.hover); - nk_love_preserve(&context->nkctx.style.tab.tab_minimize_button.active); - nk_love_preserve(&context->nkctx.style.tab.node_maximize_button.normal); - nk_love_preserve(&context->nkctx.style.tab.node_maximize_button.hover); - nk_love_preserve(&context->nkctx.style.tab.node_maximize_button.active); - nk_love_preserve(&context->nkctx.style.tab.node_minimize_button.normal); - nk_love_preserve(&context->nkctx.style.tab.node_minimize_button.hover); - nk_love_preserve(&context->nkctx.style.tab.node_minimize_button.active); + nk_love_preserve(L, &context->nkctx.style.tab.background); + nk_love_preserve(L, &context->nkctx.style.tab.tab_maximize_button.normal); + nk_love_preserve(L, &context->nkctx.style.tab.tab_maximize_button.hover); + nk_love_preserve(L, &context->nkctx.style.tab.tab_maximize_button.active); + nk_love_preserve(L, &context->nkctx.style.tab.tab_minimize_button.normal); + nk_love_preserve(L, &context->nkctx.style.tab.tab_minimize_button.hover); + nk_love_preserve(L, &context->nkctx.style.tab.tab_minimize_button.active); + nk_love_preserve(L, &context->nkctx.style.tab.node_maximize_button.normal); + nk_love_preserve(L, &context->nkctx.style.tab.node_maximize_button.hover); + nk_love_preserve(L, &context->nkctx.style.tab.node_maximize_button.active); + nk_love_preserve(L, &context->nkctx.style.tab.node_minimize_button.normal); + nk_love_preserve(L, &context->nkctx.style.tab.node_minimize_button.hover); + nk_love_preserve(L, &context->nkctx.style.tab.node_minimize_button.active); - nk_love_preserve(&context->nkctx.style.combo.normal); - nk_love_preserve(&context->nkctx.style.combo.hover); - nk_love_preserve(&context->nkctx.style.combo.active); - nk_love_preserve(&context->nkctx.style.combo.button.normal); - nk_love_preserve(&context->nkctx.style.combo.button.hover); - nk_love_preserve(&context->nkctx.style.combo.button.active); + nk_love_preserve(L, &context->nkctx.style.combo.normal); + nk_love_preserve(L, &context->nkctx.style.combo.hover); + nk_love_preserve(L, &context->nkctx.style.combo.active); + nk_love_preserve(L, &context->nkctx.style.combo.button.normal); + nk_love_preserve(L, &context->nkctx.style.combo.button.hover); + nk_love_preserve(L, &context->nkctx.style.combo.button.active); - nk_love_preserve(&context->nkctx.style.window.fixed_background); - nk_love_preserve(&context->nkctx.style.window.scaler); - nk_love_preserve(&context->nkctx.style.window.header.normal); - nk_love_preserve(&context->nkctx.style.window.header.hover); - nk_love_preserve(&context->nkctx.style.window.header.active); - nk_love_preserve(&context->nkctx.style.window.header.close_button.normal); - nk_love_preserve(&context->nkctx.style.window.header.close_button.hover); - nk_love_preserve(&context->nkctx.style.window.header.close_button.active); - nk_love_preserve(&context->nkctx.style.window.header.minimize_button.normal); - nk_love_preserve(&context->nkctx.style.window.header.minimize_button.hover); - nk_love_preserve(&context->nkctx.style.window.header.minimize_button.active); + nk_love_preserve(L, &context->nkctx.style.window.fixed_background); + nk_love_preserve(L, &context->nkctx.style.window.scaler); + nk_love_preserve(L, &context->nkctx.style.window.header.normal); + nk_love_preserve(L, &context->nkctx.style.window.header.hover); + nk_love_preserve(L, &context->nkctx.style.window.header.active); + nk_love_preserve(L, &context->nkctx.style.window.header.close_button.normal); + nk_love_preserve(L, &context->nkctx.style.window.header.close_button.hover); + nk_love_preserve(L, &context->nkctx.style.window.header.close_button.active); + nk_love_preserve(L, &context->nkctx.style.window.header.minimize_button.normal); + nk_love_preserve(L, &context->nkctx.style.window.header.minimize_button.hover); + nk_love_preserve(L, &context->nkctx.style.window.header.minimize_button.active); } static int nk_love_frame_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert(context == NULL, "%s: missing ui:frameEnd for previous frame"); - context = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert(L, context == NULL, "%s: missing ui:frameEnd for previous frame"); + context = nk_love_checkcontext(L, 1); nk_input_end(&context->nkctx); lua_getglobal(L, "love"); lua_getfield(L, -1, "timer"); @@ -1481,23 +1526,25 @@ static int nk_love_frame_begin(lua_State *L) lua_getfield(L, -1, "image"); lua_newtable(L); lua_setfield(L, -3, "image"); - nk_love_preserve_all(); + nk_love_preserve_all(L); lua_pop(L, 1); lua_getfield(L, -1, "font"); lua_newtable(L); lua_setfield(L, -3, "font"); context->font_count = 0; - lua_rawgeti(L, -1, context->nkctx.style.font->userdata.id); - nk_love_checkFont(-1, &context->fonts[context->font_count]); + struct nk_love_handle *love_handle = context->nkctx.style.font->userdata.ptr; + lua_rawgeti(L, -1, love_handle->ref); + nk_love_checkFont(L, -1, &context->fonts[context->font_count]); lua_pop(L, 1); - context->nkctx.style.font = &context->fonts[context->font_count++]; + context->nkctx.style.font = &context->fonts[context->font_count++].font; int i; for (i = 0; i < context->nkctx.stacks.fonts.head; ++i) { struct nk_config_stack_user_font_element *element = &context->nkctx.stacks.fonts.elements[i]; - lua_rawgeti(L, -1, element->old_value->userdata.id); - nk_love_checkFont(-1, &context->fonts[context->font_count]); + love_handle = element->old_value->userdata.ptr; + lua_rawgeti(L, -1, love_handle->ref); + nk_love_checkFont(L, -1, &context->fonts[context->font_count]); lua_pop(L, 1); - context->nkctx.stacks.fonts.elements[i].old_value = &context->fonts[context->font_count++]; + context->nkctx.stacks.fonts.elements[i].old_value = &context->fonts[context->font_count++].font; } lua_pop(L, 1); context->layout_ratio_count = 0; @@ -1511,13 +1558,29 @@ static int nk_love_frame_begin(lua_State *L) static int nk_love_frame_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_input_begin(&context->nkctx); context = NULL; return 0; } +static int nk_love_frame(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 2); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_getfield(L, 1, "frameBegin"); + lua_pushvalue(L, 1); + lua_call(L, 1, 0); + lua_pushvalue(L, 1); + lua_call(L, 1, 0); + lua_getfield(L, 1, "frameEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + return 0; +} + /* * =============================================================== * @@ -1533,10 +1596,10 @@ sin cos 0 | -sin cos 0 */ static int nk_love_rotate(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_transform(); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_transform(L); float angle = luaL_checknumber(L, 2); - nk_love_pushregistry("transform"); + nk_love_pushregistry(L, "transform"); size_t len = lua_objlen(L, -1); lua_newtable(L); lua_pushstring(L, "rotate"); @@ -1581,11 +1644,11 @@ sx 0 0 | 1/sx 0 0 */ static int nk_love_scale(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) >= 2 && lua_gettop(L) <= 3); - nk_love_assert_transform(); + nk_love_assert_argc(L, lua_gettop(L) >= 2 && lua_gettop(L) <= 3); + nk_love_assert_transform(L); float sx = luaL_checknumber(L, 2); float sy = luaL_optnumber(L, 3, sx); - nk_love_pushregistry("transform"); + nk_love_pushregistry(L, "transform"); size_t len = lua_objlen(L, -1); lua_newtable(L); lua_pushstring(L, "scale"); @@ -1618,11 +1681,11 @@ ky 1 0 | ky/(kx*ky-1) 1/(1-kx*ky) 0 */ static int nk_love_shear(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - nk_love_assert_transform(); + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_transform(L); float kx = luaL_checknumber(L, 2); float ky = luaL_checknumber(L, 3); - nk_love_pushregistry("transform"); + nk_love_pushregistry(L, "transform"); size_t len = lua_objlen(L, -1); lua_newtable(L); lua_pushstring(L, "shear"); @@ -1669,11 +1732,11 @@ static int nk_love_shear(lua_State *L) */ static int nk_love_translate(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - nk_love_assert_transform(); + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_transform(L); float dx = luaL_checknumber(L, 2); float dy = luaL_checknumber(L, 3); - nk_love_pushregistry("transform"); + nk_love_pushregistry(L, "transform"); size_t len = lua_objlen(L, -1); lua_newtable(L); lua_pushstring(L, "translate"); @@ -1713,21 +1776,21 @@ static int nk_love_translate(lua_State *L) static int nk_love_window_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) >= 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) >= 1); + nk_love_assert_context(L, 1); const char *name, *title; int bounds_begin; if (lua_isnumber(L, 3)) { - nk_love_assert_argc(lua_gettop(L) >= 6); + nk_love_assert_argc(L, lua_gettop(L) >= 6); name = title = luaL_checkstring(L, 2); bounds_begin = 3; } else { - nk_love_assert_argc(lua_gettop(L) >= 7); + nk_love_assert_argc(L, lua_gettop(L) >= 7); name = luaL_checkstring(L, 2); title = luaL_checkstring(L, 3); bounds_begin = 4; } - nk_flags flags = nk_love_parse_window_flags(bounds_begin + 4); + nk_flags flags = nk_love_parse_window_flags(L, bounds_begin + 4, lua_gettop(L)); float x = luaL_checknumber(L, bounds_begin); float y = luaL_checknumber(L, bounds_begin + 1); float width = luaL_checknumber(L, bounds_begin + 2); @@ -1739,16 +1802,41 @@ static int nk_love_window_begin(lua_State *L) static int nk_love_window_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_end(&context->nkctx); return 0; } +static int nk_love_window(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 2), "%s: failed to allocate stack space"); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_getfield(L, 1, "windowBegin"); + lua_insert(L, 3); + lua_call(L, lua_gettop(L) - 3, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_pushvalue(L, 1); + lua_call(L, 1, 0); + } else { + lua_pop(L, 1); + } + lua_getfield(L, -1, "windowEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + return 0; +} + static int nk_love_window_get_bounds(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_rect rect = nk_window_get_bounds(&context->nkctx); lua_pushnumber(L, rect.x); lua_pushnumber(L, rect.y); @@ -1759,8 +1847,8 @@ static int nk_love_window_get_bounds(lua_State *L) static int nk_love_window_get_position(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_vec2 pos = nk_window_get_position(&context->nkctx); lua_pushnumber(L, pos.x); lua_pushnumber(L, pos.y); @@ -1769,18 +1857,29 @@ static int nk_love_window_get_position(lua_State *L) static int nk_love_window_get_size(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_vec2 size = nk_window_get_size(&context->nkctx); lua_pushnumber(L, size.x); lua_pushnumber(L, size.y); return 2; } +static int nk_love_window_get_scroll(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); + nk_uint offset_x, offset_y; + nk_window_get_scroll(&context->nkctx, &offset_x, &offset_y); + lua_pushinteger(L, offset_x); + lua_pushinteger(L, offset_y); + return 2; +} + static int nk_love_window_get_content_region(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_rect rect = nk_window_get_content_region(&context->nkctx); lua_pushnumber(L, rect.x); lua_pushnumber(L, rect.y); @@ -1791,8 +1890,8 @@ static int nk_love_window_get_content_region(lua_State *L) static int nk_love_window_has_focus(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); int has_focus = nk_window_has_focus(&context->nkctx); lua_pushboolean(L, has_focus); return 1; @@ -1800,8 +1899,8 @@ static int nk_love_window_has_focus(lua_State *L) static int nk_love_window_is_collapsed(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); int is_collapsed = nk_window_is_collapsed(&context->nkctx, name); lua_pushboolean(L, is_collapsed); @@ -1810,8 +1909,8 @@ static int nk_love_window_is_collapsed(lua_State *L) static int nk_love_window_is_closed(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); int is_closed = nk_window_is_closed(&context->nkctx, name); lua_pushboolean(L, is_closed); @@ -1820,8 +1919,8 @@ static int nk_love_window_is_closed(lua_State *L) static int nk_love_window_is_hidden(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); int is_hidden = nk_window_is_hidden(&context->nkctx, name); lua_pushboolean(L, is_hidden); @@ -1830,8 +1929,8 @@ static int nk_love_window_is_hidden(lua_State *L) static int nk_love_window_is_active(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); int is_active = nk_window_is_active(&context->nkctx, name); lua_pushboolean(L, is_active); @@ -1840,8 +1939,8 @@ static int nk_love_window_is_active(lua_State *L) static int nk_love_window_is_hovered(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); int is_hovered = nk_window_is_hovered(&context->nkctx); lua_pushboolean(L, is_hovered); return 1; @@ -1849,8 +1948,8 @@ static int nk_love_window_is_hovered(lua_State *L) static int nk_love_window_is_any_hovered(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); int is_any_hovered = nk_window_is_any_hovered(&context->nkctx); lua_pushboolean(L, is_any_hovered); return 1; @@ -1858,16 +1957,16 @@ static int nk_love_window_is_any_hovered(lua_State *L) static int nk_love_item_is_any_active(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); lua_pushboolean(L, nk_love_is_active(&context->nkctx)); return 1; } static int nk_love_window_set_bounds(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 6); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 6); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); struct nk_rect bounds; bounds.x = luaL_checknumber(L, 3); @@ -1880,8 +1979,8 @@ static int nk_love_window_set_bounds(lua_State *L) static int nk_love_window_set_position(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 4); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); struct nk_vec2 pos; pos.x = luaL_checknumber(L, 3); @@ -1892,8 +1991,8 @@ static int nk_love_window_set_position(lua_State *L) static int nk_love_window_set_size(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 4); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); struct nk_vec2 size; size.x = luaL_checknumber(L, 3); @@ -1904,17 +2003,28 @@ static int nk_love_window_set_size(lua_State *L) static int nk_love_window_set_focus(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); nk_window_set_focus(&context->nkctx, name); return 0; } +static int nk_love_window_set_scroll(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_context(L, 1); + nk_uint offset_x, offset_y; + offset_x = luaL_checkinteger(L, 2); + offset_y = luaL_checkinteger(L, 3); + nk_window_set_scroll(&context->nkctx, offset_x, offset_y); + return 0; +} + static int nk_love_window_close(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); nk_window_close(&context->nkctx, name); return 0; @@ -1922,8 +2032,8 @@ static int nk_love_window_close(lua_State *L) static int nk_love_window_collapse(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); nk_window_collapse(&context->nkctx, name, NK_MINIMIZED); return 0; @@ -1931,8 +2041,8 @@ static int nk_love_window_collapse(lua_State *L) static int nk_love_window_expand(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); nk_window_collapse(&context->nkctx, name, NK_MAXIMIZED); return 0; @@ -1940,8 +2050,8 @@ static int nk_love_window_expand(lua_State *L) static int nk_love_window_show(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); nk_window_show(&context->nkctx, name, NK_SHOWN); return 0; @@ -1949,8 +2059,8 @@ static int nk_love_window_show(lua_State *L) static int nk_love_window_hide(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); nk_window_show(&context->nkctx, name, NK_HIDDEN); return 0; @@ -1967,53 +2077,69 @@ static int nk_love_window_hide(lua_State *L) static int nk_love_layout_row(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 4 && argc <= 5); - nk_love_assert_context(1); - enum nk_layout_format format = nk_love_checkformat(2); - float height = luaL_checknumber(L, 3); - int use_ratios = 0; - if (format == NK_DYNAMIC) { - nk_love_assert_argc(argc == 4); - if (lua_isnumber(L, 4)) { - int cols = luaL_checkint(L, 4); - nk_layout_row_dynamic(&context->nkctx, height, cols); - } else { - if (!lua_istable(L, 4)) - luaL_argerror(L, 4, "should be a number or table"); - use_ratios = 1; + if (argc == 5 && lua_isfunction(L, 5)) { + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "layoutRowBegin"); + lua_insert(L, 4); + lua_call(L, 4, 0); + lua_call(L, 1, 0); + lua_getfield(L, 1, "layoutRowEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } else { + nk_love_assert_argc(L, argc >= 4 && argc <= 5); + nk_love_assert_context(L, 1); + enum nk_layout_format format = nk_love_checkformat(L, 2); + float height = luaL_checknumber(L, 3); + int use_ratios = 0; + if (format == NK_DYNAMIC) { + nk_love_assert_argc(L, argc == 4); + if (lua_isnumber(L, 4)) { + int cols = luaL_checkint(L, 4); + nk_layout_row_dynamic(&context->nkctx, height, cols); + } else { + if (!lua_istable(L, 4)) + luaL_argerror(L, 4, "should be a number or table"); + use_ratios = 1; + } + } else if (format == NK_STATIC) { + if (argc == 5) { + int item_width = luaL_checkint(L, 4); + int cols = luaL_checkint(L, 5); + nk_layout_row_static(&context->nkctx, height, item_width, cols); + } else { + if (!lua_istable(L, 4)) + luaL_argerror(L, 4, "should be a number or table"); + use_ratios = 1; + } } - } else if (format == NK_STATIC) { - if (argc == 5) { - int item_width = luaL_checkint(L, 4); - int cols = luaL_checkint(L, 5); - nk_layout_row_static(&context->nkctx, height, item_width, cols); - } else { - if (!lua_istable(L, 4)) - luaL_argerror(L, 4, "should be a number or table"); - use_ratios = 1; + if (use_ratios) { + int cols = lua_objlen(L, -1); + int i, j; + for (i = 1, j = context->layout_ratio_count; i <= cols && j < NK_LOVE_MAX_RATIOS; ++i, ++j) { + lua_rawgeti(L, -1, i); + if (!lua_isnumber(L, -1)) + luaL_argerror(L, lua_gettop(L) - 1, "should contain numbers only"); + context->layout_ratios[j] = lua_tonumber(L, -1); + lua_pop(L, 1); + } + nk_layout_row(&context->nkctx, format, height, cols, context->layout_ratios + context->layout_ratio_count); + context->layout_ratio_count += cols; } } - if (use_ratios) { - int cols = lua_objlen(L, -1); - int i, j; - for (i = 1, j = context->layout_ratio_count; i <= cols && j < NK_LOVE_MAX_RATIOS; ++i, ++j) { - lua_rawgeti(L, -1, i); - if (!lua_isnumber(L, -1)) - luaL_argerror(L, lua_gettop(L) - 1, "should contain numbers only"); - context->layout_ratios[j] = lua_tonumber(L, -1); - lua_pop(L, 1); - } - nk_layout_row(&context->nkctx, format, height, cols, context->layout_ratios + context->layout_ratio_count); - context->layout_ratio_count += cols; - } return 0; } static int nk_love_layout_row_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 4); - nk_love_assert_context(1); - enum nk_layout_format format = nk_love_checkformat(2); + nk_love_assert_argc(L, lua_gettop(L) == 4); + nk_love_assert_context(L, 1); + enum nk_layout_format format = nk_love_checkformat(L, 2); float height = luaL_checknumber(L, 3); int cols = luaL_checkint(L, 4); nk_layout_row_begin(&context->nkctx, format, height, cols); @@ -2022,8 +2148,8 @@ static int nk_love_layout_row_begin(lua_State *L) static int nk_love_layout_row_push(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); float value = luaL_checknumber(L, 2); nk_layout_row_push(&context->nkctx, value); return 0; @@ -2031,16 +2157,16 @@ static int nk_love_layout_row_push(lua_State *L) static int nk_love_layout_row_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_layout_row_end(&context->nkctx); return 0; } static int nk_love_layout_template_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); float height = luaL_checknumber(L, 2); nk_layout_row_template_begin(&context->nkctx, height); return 0; @@ -2048,13 +2174,14 @@ static int nk_love_layout_template_begin(lua_State *L) static int nk_love_layout_template_push(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2 || lua_gettop(L) == 3); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2 || lua_gettop(L) == 3); + nk_love_assert_context(L, 1); const char *mode = luaL_checkstring(L, 2); - if (lua_gettop(L) == 2) { - nk_love_assert(!strcmp(mode, "dynamic"), "%s: expecting 'dynamic' mode or width argument"); + if (!strcmp(mode, "dynamic")) { + nk_love_assert_argc(L, lua_gettop(L) == 2); nk_layout_row_template_push_dynamic(&context->nkctx); } else { + nk_love_assert_argc(L, lua_gettop(L) == 3); float width = luaL_checknumber(L, 3); if (!strcmp(mode, "variable")) { nk_layout_row_template_push_variable(&context->nkctx, width); @@ -2069,16 +2196,38 @@ static int nk_love_layout_template_push(lua_State *L) static int nk_love_layout_template_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_layout_row_template_end(&context->nkctx); + return 0; +} + +static int nk_love_layout_template(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) == 3); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "layoutTemplateBegin"); + lua_insert(L, 4); + lua_call(L, 2, 0); + lua_call(L, 1, 0); + lua_getfield(L, 1, "layoutTemplateEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + return 0; } static int nk_love_layout_space_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 4); - nk_love_assert_context(1); - enum nk_layout_format format = nk_love_checkformat(2); + nk_love_assert_argc(L, lua_gettop(L) == 4); + nk_love_assert_context(L, 1); + enum nk_layout_format format = nk_love_checkformat(L, 2); float height = luaL_checknumber(L, 3); int widget_count = luaL_checkint(L, 4); nk_layout_space_begin(&context->nkctx, format, height, widget_count); @@ -2087,8 +2236,8 @@ static int nk_love_layout_space_begin(lua_State *L) static int nk_love_layout_space_push(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); float x = luaL_checknumber(L, 2); float y = luaL_checknumber(L, 3); float width = luaL_checknumber(L, 4); @@ -2099,16 +2248,37 @@ static int nk_love_layout_space_push(lua_State *L) static int nk_love_layout_space_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_layout_space_end(&context->nkctx); return 0; } +static int nk_love_layout_space(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) == 5); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "layoutSpaceBegin"); + lua_insert(L, 4); + lua_call(L, 4, 0); + lua_call(L, 1, 0); + lua_getfield(L, 1, "layoutSpaceEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + return 0; +} + static int nk_love_layout_space_bounds(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_rect bounds = nk_layout_space_bounds(&context->nkctx); lua_pushnumber(L, bounds.x); lua_pushnumber(L, bounds.y); @@ -2119,8 +2289,8 @@ static int nk_love_layout_space_bounds(lua_State *L) static int nk_love_layout_space_to_screen(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_context(L, 1); struct nk_vec2 local; local.x = luaL_checknumber(L, 2); local.y = luaL_checknumber(L, 3); @@ -2132,8 +2302,8 @@ static int nk_love_layout_space_to_screen(lua_State *L) static int nk_love_layout_space_to_local(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_context(L, 1); struct nk_vec2 screen; screen.x = luaL_checknumber(L, 2); screen.y = luaL_checknumber(L, 3); @@ -2145,8 +2315,8 @@ static int nk_love_layout_space_to_local(lua_State *L) static int nk_love_layout_space_rect_to_screen(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); struct nk_rect local; local.x = luaL_checknumber(L, 2); local.y = luaL_checknumber(L, 3); @@ -2162,8 +2332,8 @@ static int nk_love_layout_space_rect_to_screen(lua_State *L) static int nk_love_layout_space_rect_to_local(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); struct nk_rect screen; screen.x = luaL_checknumber(L, 2); screen.y = luaL_checknumber(L, 3); @@ -2179,8 +2349,8 @@ static int nk_love_layout_space_rect_to_local(lua_State *L) static int nk_love_layout_ratio_from_pixel(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); float pixel_width = luaL_checknumber(L, 2); float ratio = nk_layout_ratio_from_pixel(&context->nkctx, pixel_width); lua_pushnumber(L, ratio); @@ -2197,10 +2367,10 @@ static int nk_love_layout_ratio_from_pixel(lua_State *L) static int nk_love_group_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) >= 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) >= 2); + nk_love_assert_context(L, 1); const char *title = luaL_checkstring(L, 2); - nk_flags flags = nk_love_parse_window_flags(3); + nk_flags flags = nk_love_parse_window_flags(L, 3, lua_gettop(L)); int open = nk_group_begin(&context->nkctx, title, flags); lua_pushboolean(L, open); return 1; @@ -2208,28 +2378,78 @@ static int nk_love_group_begin(lua_State *L) static int nk_love_group_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_group_end(&context->nkctx); return 0; } +static int nk_love_group(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) >= 3); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "groupBegin"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "groupEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } else { + lua_pop(L, 3); + } + return 0; +} + +static int nk_love_group_get_scroll(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); + const char *id = luaL_checkstring(L, 2); + nk_uint x_offset, y_offset; + nk_group_get_scroll(&context->nkctx, id, &x_offset, &y_offset); + lua_pushinteger(L, x_offset); + lua_pushinteger(L, y_offset); + return 2; +} + +static int nk_love_group_set_scroll(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 4); + nk_love_assert_context(L, 1); + const char *id = luaL_checkstring(L, 2); + nk_uint x_offset = luaL_checkint(L, 3); + nk_uint y_offset = luaL_checkint(L, 4); + nk_group_set_scroll(&context->nkctx, id, x_offset, y_offset); + return 0; +} + static int nk_love_tree_push(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 3 && argc <= 5); - nk_love_assert_context(1); - enum nk_tree_type type = nk_love_checktree(2); + nk_love_assert_argc(L, argc >= 3 && argc <= 5); + nk_love_assert_context(L, 1); + enum nk_tree_type type = nk_love_checktree(L, 2); const char *title = luaL_checkstring(L, 3); struct nk_image image; int use_image = 0; if (argc >= 4 && !lua_isnil(L, 4)) { - nk_love_checkImage(4, &image); + nk_love_checkImage(L, 4, &image); use_image = 1; } enum nk_collapse_states state = NK_MINIMIZED; if (argc >= 5 && !lua_isnil(L, 5)) - state = nk_love_checkstate(5); + state = nk_love_checkstate(L, 5); lua_Debug ar; lua_getstack(L, 1, &ar); lua_getinfo(L, "l", &ar); @@ -2245,16 +2465,100 @@ static int nk_love_tree_push(lua_State *L) static int nk_love_tree_pop(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_tree_pop(&context->nkctx); return 0; } +static int nk_love_tree(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) >= 4); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "treePush"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "treePop"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } + return 0; +} + +static int nk_love_tree_state_push(lua_State *L) +{ + int argc = lua_gettop(L); + nk_love_assert_argc(L, argc >= 3 && argc <= 5); + nk_love_assert_context(L, 1); + enum nk_tree_type type = nk_love_checktree(L, 2); + const char *title = luaL_checkstring(L, 3); + struct nk_image image; + int use_image = 0; + if (argc >= 4 && !lua_isnil(L, 4)) { + nk_love_checkImage(L, 4, &image); + use_image = 1; + } + enum nk_collapse_states state = NK_MINIMIZED; + if (argc >= 5) + state = nk_love_checkstate(L, 5); + + int open = 0; + if (use_image) + open = nk_tree_state_image_push(&context->nkctx, type, image, title, &state); + else + open = nk_tree_state_push(&context->nkctx, type, title, &state); + lua_pushboolean(L, open); + return 1; +} + +static int nk_love_tree_state_pop(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); + nk_tree_state_pop(&context->nkctx); + return 0; +} + +static int nk_love_tree_state(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) >= 4); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "treeStatePush"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "treeStatePop"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } + return 0; +} + static int nk_love_color_rgba(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc == 3 || argc == 4); + nk_love_assert_argc(L, argc == 3 || argc == 4); int r = luaL_checkint(L, 1); int g = luaL_checkint(L, 2); int b = luaL_checkint(L, 3); @@ -2270,7 +2574,7 @@ static int nk_love_color_rgba(lua_State *L) static int nk_love_color_hsva(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc == 3 || argc == 4); + nk_love_assert_argc(L, argc == 3 || argc == 4); int h = NK_CLAMP(0, luaL_checkint(L, 1), 255); int s = NK_CLAMP(0, luaL_checkint(L, 2), 255); int v = NK_CLAMP(0, luaL_checkint(L, 3), 255); @@ -2286,8 +2590,8 @@ static int nk_love_color_hsva(lua_State *L) static int nk_love_color_parse_rgba(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - struct nk_color rgba = nk_love_checkcolor(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + struct nk_color rgba = nk_love_checkcolor(L, 1); lua_pushnumber(L, rgba.r); lua_pushnumber(L, rgba.g); lua_pushnumber(L, rgba.b); @@ -2297,8 +2601,8 @@ static int nk_love_color_parse_rgba(lua_State *L) static int nk_love_color_parse_hsva(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - struct nk_color rgba = nk_love_checkcolor(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + struct nk_color rgba = nk_love_checkcolor(L, 1); int h, s, v, a2; nk_color_hsva_i(&h, &s, &v, &a2, rgba); lua_pushnumber(L, h); @@ -2311,8 +2615,8 @@ static int nk_love_color_parse_hsva(lua_State *L) static int nk_love_label(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 4); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); nk_flags align = NK_TEXT_LEFT; int wrap = 0; @@ -2323,9 +2627,9 @@ static int nk_love_label(lua_State *L) if (!strcmp(align_string, "wrap")) wrap = 1; else - align = nk_love_checkalign(3); + align = nk_love_checkalign(L, 3); if (argc >= 4) { - color = nk_love_checkcolor(4); + color = nk_love_checkcolor(L, 4); use_color = 1; } } @@ -2346,10 +2650,10 @@ static int nk_love_label(lua_State *L) static int nk_love_image(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc == 2 || argc == 6); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc == 2 || argc == 6); + nk_love_assert_context(L, 1); struct nk_image image; - nk_love_checkImage(2, &image); + nk_love_checkImage(L, 2, &image); if (argc == 2) { nk_image(&context->nkctx, image); } else { @@ -2359,7 +2663,7 @@ static int nk_love_image(lua_State *L) float h = luaL_checknumber(L, 6); float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); nk_draw_image(&context->nkctx.current->buffer, nk_rect(x, y, w, h), &image, color); } return 0; @@ -2368,8 +2672,8 @@ static int nk_love_image(lua_State *L) static int nk_love_button(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 3); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 3); + nk_love_assert_context(L, 1); const char *title = NULL; if (!lua_isnil(L, 2)) title = luaL_checkstring(L, 2); @@ -2379,14 +2683,14 @@ static int nk_love_button(lua_State *L) struct nk_image image; if (argc >= 3 && !lua_isnil(L, 3)) { if (lua_isstring(L, 3)) { - if (nk_love_is_color(3)) { - color = nk_love_checkcolor(3); + if (nk_love_is_color(L, 3)) { + color = nk_love_checkcolor(L, 3); use_color = 1; } else { - symbol = nk_love_checksymbol(3); + symbol = nk_love_checksymbol(L, 3); } } else { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } } @@ -2394,7 +2698,7 @@ static int nk_love_button(lua_State *L) int activated = 0; if (title != NULL) { if (use_color) - nk_love_assert(0, "%s: color buttons can't have titles"); + nk_love_assert(L, 0, "%s: color buttons can't have titles"); else if (symbol != NK_SYMBOL_NONE) activated = nk_button_symbol_label(&context->nkctx, symbol, title, align); else if (use_image) @@ -2409,7 +2713,7 @@ static int nk_love_button(lua_State *L) else if (use_image) activated = nk_button_image(&context->nkctx, image); else - nk_love_assert(0, "%s: must specify a title, color, symbol, and/or image"); + nk_love_assert(L, 0, "%s: must specify a title, color, symbol, and/or image"); } lua_pushboolean(L, activated); return 1; @@ -2417,34 +2721,34 @@ static int nk_love_button(lua_State *L) static int nk_love_button_set_behavior(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); - enum nk_button_behavior behavior = nk_love_checkbehavior(2); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); + enum nk_button_behavior behavior = nk_love_checkbehavior(L, 2); nk_button_set_behavior(&context->nkctx, behavior); return 0; } static int nk_love_button_push_behavior(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); - enum nk_button_behavior behavior = nk_love_checkbehavior(2); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); + enum nk_button_behavior behavior = nk_love_checkbehavior(L, 2); nk_button_push_behavior(&context->nkctx, behavior); return 0; } static int nk_love_button_pop_behavior(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_button_pop_behavior(&context->nkctx); return 0; } static int nk_love_checkbox(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); if (lua_isboolean(L, 3)) { int value = lua_toboolean(L, 3); @@ -2470,8 +2774,8 @@ static int nk_love_checkbox(lua_State *L) static int nk_love_radio(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc == 3 || argc == 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc == 3 || argc == 4); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); const char *text = name; if (argc == 4) @@ -2505,18 +2809,18 @@ static int nk_love_radio(lua_State *L) static int nk_love_selectable(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 3 && argc <= 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 3 && argc <= 5); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); struct nk_image image; int use_image = 0; if (argc >= 4 && !lua_isnil(L, 3)) { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } nk_flags align = NK_TEXT_LEFT; if (argc >= 5) - align = nk_love_checkalign(4); + align = nk_love_checkalign(L, 4); if (lua_isboolean(L, -1)) { int value = lua_toboolean(L, -1); if (use_image) @@ -2547,8 +2851,8 @@ static int nk_love_selectable(lua_State *L) static int nk_love_slider(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); float min = luaL_checknumber(L, 2); float max = luaL_checknumber(L, 4); float step = luaL_checknumber(L, 5); @@ -2576,8 +2880,8 @@ static int nk_love_slider(lua_State *L) static int nk_love_progress(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 3 || argc <= 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 3 || argc <= 4); + nk_love_assert_context(L, 1); nk_size max = luaL_checklong(L, 3); int modifiable = 0; if (argc >= 4 && !lua_isnil(L, 4)) @@ -2606,13 +2910,13 @@ static int nk_love_progress(lua_State *L) static int nk_love_color_picker(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 3); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 3); + nk_love_assert_context(L, 1); enum nk_color_format format = NK_RGB; if (argc >= 3) - format = nk_love_checkcolorformat(3); + format = nk_love_checkcolorformat(L, 3); if (lua_isstring(L, 2)) { - struct nk_colorf color = nk_love_checkcolorf(2); + struct nk_colorf color = nk_love_checkcolorf(L, 2); color = nk_color_picker(&context->nkctx, color, format); char new_color_string[10]; nk_love_color((int) (color.r * 255), (int) (color.g * 255), @@ -2620,9 +2924,9 @@ static int nk_love_color_picker(lua_State *L) lua_pushstring(L, new_color_string); } else if (lua_istable(L, 2)) { lua_getfield(L, 2, "value"); - if (!nk_love_is_color(-1)) + if (!nk_love_is_color(L, -1)) luaL_argerror(L, 2, "should have a color string value"); - struct nk_colorf color = nk_love_checkcolorf(-1); + struct nk_colorf color = nk_love_checkcolorf(L, -1); int changed = nk_color_pick(&context->nkctx, &color, format); if (changed) { char new_color_string[10]; @@ -2640,8 +2944,8 @@ static int nk_love_color_picker(lua_State *L) static int nk_love_property(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 7); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 7); + nk_love_assert_context(L, 1); const char *name = luaL_checkstring(L, 2); double min = luaL_checknumber(L, 3); double max = luaL_checknumber(L, 5); @@ -2672,9 +2976,9 @@ static int nk_love_property(lua_State *L) static int nk_love_edit(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 3); - nk_love_assert_context(1); - nk_flags flags = nk_love_checkedittype(2); + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_context(L, 1); + nk_flags flags = nk_love_checkedittype(L, 2); if (!lua_istable(L, 3)) luaL_typerror(L, 3, "table"); lua_getfield(L, 3, "value"); @@ -2707,32 +3011,32 @@ static int nk_love_edit(lua_State *L) int nk_love_edit_focus(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_edit_focus(&context->nkctx, NK_EDIT_DEFAULT); return 0; } int nk_love_edit_unfocus(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_edit_unfocus(&context->nkctx); return 0; } static int nk_love_popup_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) >= 7); - nk_love_assert_context(1); - enum nk_popup_type type = nk_love_checkpopup(2); + nk_love_assert_argc(L, lua_gettop(L) >= 7); + nk_love_assert_context(L, 1); + enum nk_popup_type type = nk_love_checkpopup(L, 2); const char *title = luaL_checkstring(L, 3); struct nk_rect bounds; bounds.x = luaL_checknumber(L, 4); bounds.y = luaL_checknumber(L, 5); bounds.w = luaL_checknumber(L, 6); bounds.h = luaL_checknumber(L, 7); - nk_flags flags = nk_love_parse_window_flags(8); + nk_flags flags = nk_love_parse_window_flags(L, 8, lua_gettop(L)); int open = nk_popup_begin(&context->nkctx, type, title, flags, bounds); lua_pushboolean(L, open); return 1; @@ -2740,25 +3044,92 @@ static int nk_love_popup_begin(lua_State *L) static int nk_love_popup_close(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_popup_close(&context->nkctx); return 0; } static int nk_love_popup_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_popup_end(&context->nkctx); return 0; } +static int nk_love_popup(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) >= 8); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "popupBegin"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "popupEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } + return 0; +} + +static int nk_love_popup_get_scroll(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); + nk_uint offset_x, offset_y; + nk_popup_get_scroll(&context->nkctx, &offset_x, &offset_y); + lua_pushinteger(L, offset_x); + lua_pushinteger(L, offset_y); + return 2; +} + +static int nk_love_popup_set_scroll(lua_State *L) +{ + nk_love_assert_argc(L, lua_gettop(L) == 3); + nk_love_assert_context(L, 1); + nk_uint offset_x, offset_y; + offset_x = luaL_checkinteger(L, 2); + offset_y = luaL_checkinteger(L, 3); + nk_popup_set_scroll(&context->nkctx, offset_x, offset_y); + return 0; +} + static int nk_love_combobox(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 3 && argc <= 6); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 3 && argc <= 6); + nk_love_assert_context(L, 1); + if (lua_isfunction(L, -1)) { + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "comboboxBegin"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "comboboxEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } + return 0; + } if (!lua_istable(L, 3)) luaL_typerror(L, 3, "table"); int i; @@ -2781,14 +3152,14 @@ static int nk_love_combobox(lua_State *L) if (argc >= 6 && !lua_isnil(L, 6)) size.y = luaL_checknumber(L, 6); if (lua_isnumber(L, 2)) { - int value = lua_tointeger(L, 2) - 1; + int value = luaL_checkinteger(L, 2) - 1; value = nk_combo(&context->nkctx, combobox_items, i, value, item_height, size); lua_pushnumber(L, value + 1); } else if (lua_istable(L, 2)) { lua_getfield(L, 2, "value"); if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "should have a number value"); - int value = lua_tointeger(L, -1) - 1; + int value = luaL_checkinteger(L, -1) - 1; int old = value; nk_combobox(&context->nkctx, combobox_items, i, &value, item_height, size); int changed = value != old; @@ -2806,8 +3177,8 @@ static int nk_love_combobox(lua_State *L) static int nk_love_combobox_begin(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 5); + nk_love_assert_context(L, 1); const char *text = NULL; if (!lua_isnil(L, 2)) text = luaL_checkstring(L, 2); @@ -2818,14 +3189,14 @@ static int nk_love_combobox_begin(lua_State *L) int use_image = 0; if (argc >= 3 && !lua_isnil(L, 3)) { if (lua_isstring(L, 3)) { - if (nk_love_is_color(3)) { - color = nk_love_checkcolor(3); + if (nk_love_is_color(L, 3)) { + color = nk_love_checkcolor(L, 3); use_color = 1; } else { - symbol = nk_love_checksymbol(3); + symbol = nk_love_checksymbol(L, 3); } } else { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } } @@ -2838,7 +3209,7 @@ static int nk_love_combobox_begin(lua_State *L) int open = 0; if (text != NULL) { if (use_color) - nk_love_assert(0, "%s: color comboboxes can't have titles"); + nk_love_assert(L, 0, "%s: color comboboxes can't have titles"); else if (symbol != NK_SYMBOL_NONE) open = nk_combo_begin_symbol_label(&context->nkctx, text, symbol, size); else if (use_image) @@ -2853,7 +3224,7 @@ static int nk_love_combobox_begin(lua_State *L) else if (use_image) open = nk_combo_begin_image(&context->nkctx, image, size); else - nk_love_assert(0, "%s: must specify color, symbol, image, and/or title"); + nk_love_assert(L, 0, "%s: must specify color, symbol, image, and/or title"); } lua_pushboolean(L, open); return 1; @@ -2862,23 +3233,23 @@ static int nk_love_combobox_begin(lua_State *L) static int nk_love_combobox_item(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 4); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); enum nk_symbol_type symbol = NK_SYMBOL_NONE; struct nk_image image; int use_image = 0; if (argc >= 3 && !lua_isnil(L, 3)) { if (lua_isstring(L, 3)) { - symbol = nk_love_checksymbol(3); + symbol = nk_love_checksymbol(L, 3); } else { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } } nk_flags align = NK_TEXT_LEFT; if (argc >= 4 && !lua_isnil(L, 4)) - align = nk_love_checkalign(4); + align = nk_love_checkalign(L, 4); int activated = 0; if (symbol != NK_SYMBOL_NONE) activated = nk_combo_item_symbol_label(&context->nkctx, symbol, text, align); @@ -2892,24 +3263,24 @@ static int nk_love_combobox_item(lua_State *L) static int nk_love_combobox_close(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_combo_close(&context->nkctx); return 0; } static int nk_love_combobox_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_combo_end(&context->nkctx); return 0; } static int nk_love_contextual_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) >= 7); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) >= 7); + nk_love_assert_context(L, 1); struct nk_vec2 size; size.x = luaL_checknumber(L, 2); size.y = luaL_checknumber(L, 3); @@ -2918,7 +3289,7 @@ static int nk_love_contextual_begin(lua_State *L) trigger.y = luaL_checknumber(L, 5); trigger.w = luaL_checknumber(L, 6); trigger.h = luaL_checknumber(L, 7); - nk_flags flags = nk_love_parse_window_flags(8); + nk_flags flags = nk_love_parse_window_flags(L, 8, lua_gettop(L)); int open = nk_contextual_begin(&context->nkctx, flags, size, trigger); lua_pushboolean(L, open); return 1; @@ -2927,23 +3298,23 @@ static int nk_love_contextual_begin(lua_State *L) static int nk_love_contextual_item(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 4); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); enum nk_symbol_type symbol = NK_SYMBOL_NONE; struct nk_image image; int use_image = 0; if (argc >= 3 && !lua_isnil(L, 3)) { if (lua_isstring(L, 3)) { - symbol = nk_love_checksymbol(3); + symbol = nk_love_checksymbol(L, 3); } else { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } } nk_flags align = NK_TEXT_LEFT; if (argc >= 4 && !lua_isnil(L, 4)) - align = nk_love_checkalign(4); + align = nk_love_checkalign(L, 4); int activated; if (symbol != NK_SYMBOL_NONE) activated = nk_contextual_item_symbol_label(&context->nkctx, symbol, text, align); @@ -2957,33 +3328,49 @@ static int nk_love_contextual_item(lua_State *L) static int nk_love_contextual_close(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_contextual_close(&context->nkctx); return 0; } static int nk_love_contextual_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_contextual_end(&context->nkctx); return 0; } -static int nk_love_tooltip(lua_State *L) +static int nk_love_contextual(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); - const char *text = luaL_checkstring(L, 2); - nk_tooltip(&context->nkctx, text); + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) >= 8); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "contextualBegin"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "contextualEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } return 0; } static int nk_love_tooltip_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); float width = luaL_checknumber(L, 2); int open = nk_tooltip_begin(&context->nkctx, width); lua_pushnumber(L, open); @@ -2992,41 +3379,93 @@ static int nk_love_tooltip_begin(lua_State *L) static int nk_love_tooltip_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_tooltip_end(&context->nkctx); return 0; } +static int nk_love_tooltip(lua_State *L) +{ + if (lua_gettop(L) == 3) { + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "tooltipBegin"); + lua_insert(L, 4); + lua_call(L, 2, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "tooltipEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } + } else { + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); + const char *text = luaL_checkstring(L, 2); + nk_tooltip(&context->nkctx, text); + } + return 0; +} + static int nk_love_menubar_begin(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_menubar_begin(&context->nkctx); return 0; } static int nk_love_menubar_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_menubar_end(&context->nkctx); return 0; } +static int nk_love_menubar(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) == 2); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "menubarBegin"); + lua_insert(L, 4); + lua_call(L, 1, 0); + lua_call(L, 1, 0); + lua_getfield(L, 1, "menubarEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + return 0; +} + static int nk_love_menu_begin(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 5 && argc <= 6); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 5 && argc <= 6); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); enum nk_symbol_type symbol = NK_SYMBOL_NONE; struct nk_image image; int use_image = 0; if (lua_isstring(L, 3)) { - symbol = nk_love_checksymbol(3); + symbol = nk_love_checksymbol(L, 3); } else if (!lua_isnil(L, 3)) { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } struct nk_vec2 size; @@ -3034,7 +3473,7 @@ static int nk_love_menu_begin(lua_State *L) size.y = luaL_checknumber(L, 5); nk_flags align = NK_TEXT_LEFT; if (argc >= 6 && !lua_isnil(L, 6)) - align = nk_love_checkalign(6); + align = nk_love_checkalign(L, 6); int open; if (symbol != NK_SYMBOL_NONE) open = nk_menu_begin_symbol_label(&context->nkctx, text, align, symbol, size); @@ -3049,23 +3488,23 @@ static int nk_love_menu_begin(lua_State *L) static int nk_love_menu_item(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 2 && argc <= 4); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 2 && argc <= 4); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); enum nk_symbol_type symbol = NK_SYMBOL_NONE; struct nk_image image; int use_image = 0; if (argc >= 3 && !lua_isnil(L, 3)) { if (lua_isstring(L, 3)) { - symbol = nk_love_checksymbol(3); + symbol = nk_love_checksymbol(L, 3); } else { - nk_love_checkImage(3, &image); + nk_love_checkImage(L, 3, &image); use_image = 1; } } nk_flags align = NK_TEXT_LEFT; if (argc >= 4 && !lua_isnil(L, 4)) - align = nk_love_checkalign(4); + align = nk_love_checkalign(L, 4); int activated; if (symbol != NK_SYMBOL_NONE) activated = nk_menu_item_symbol_label(&context->nkctx, symbol, text, align); @@ -3079,20 +3518,45 @@ static int nk_love_menu_item(lua_State *L) static int nk_love_menu_close(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_menu_close(&context->nkctx); return 0; } static int nk_love_menu_end(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); nk_menu_end(&context->nkctx); return 0; } +static int nk_love_menu(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) == 6 || lua_gettop(L) == 7); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "menuBegin"); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 4, 1); + int open = lua_toboolean(L, -1); + lua_pop(L, 1); + if (open) { + lua_call(L, 1, 0); + lua_getfield(L, 1, "menuEnd"); + lua_insert(L, 1); + lua_call(L, 1, 0); + } + return 0; +} + /* * =============================================================== * @@ -3103,25 +3567,25 @@ static int nk_love_menu_end(lua_State *L) static int nk_love_style_default(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); nk_style_default(&ctx->nkctx); return 0; } #define NK_LOVE_LOAD_COLOR(type) \ lua_getfield(L, -1, (type)); \ - if (!nk_love_is_color(-1)) { \ + if (!nk_love_is_color(L, -1)) { \ const char *msg = lua_pushfstring(L, "%%s: table missing color value for '%s'", type); \ - nk_love_assert(0, msg); \ + nk_love_assert(L, 0, msg); \ } \ - colors[index++] = nk_love_checkcolor(-1); \ + colors[index++] = nk_love_checkcolor(L, -1); \ lua_pop(L, 1) static int nk_love_style_load_colors(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); if (!lua_istable(L, 2)) luaL_typerror(L, 2, "table"); struct nk_color colors[NK_COLOR_COUNT]; @@ -3160,21 +3624,21 @@ static int nk_love_style_load_colors(lua_State *L) static int nk_love_style_set_font(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - struct nk_love_context *ctx = nk_love_checkcontext(1); - nk_love_checkFont(2, &ctx->fonts[ctx->font_count]); - nk_style_set_font(&ctx->nkctx, &ctx->fonts[ctx->font_count++]); + nk_love_assert_argc(L, lua_gettop(L) == 2); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); + nk_love_checkFont(L, 2, &ctx->fonts[ctx->font_count]); + nk_style_set_font(&ctx->nkctx, &ctx->fonts[ctx->font_count++].font); return 0; } -static int nk_love_style_push_color(struct nk_color *field) +static int nk_love_style_push_color(lua_State *L, struct nk_color *field) { - struct nk_love_context *ctx = nk_love_checkcontext(1); - if (!nk_love_is_color(-1)) { + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); + if (!nk_love_is_color(L, -1)) { const char *msg = lua_pushfstring(L, "%%s: bad color string '%s'", lua_tostring(L, -1)); - nk_love_assert(0, msg); + nk_love_assert(L, 0, msg); } - struct nk_color color = nk_love_checkcolor(-1); + struct nk_color color = nk_love_checkcolor(L, -1); int success = nk_style_push_color(&ctx->nkctx, field, color); if (success) { lua_pushstring(L, "color"); @@ -3184,15 +3648,15 @@ static int nk_love_style_push_color(struct nk_color *field) return success; } -static int nk_love_style_push_vec2(struct nk_vec2 *field) +static int nk_love_style_push_vec2(lua_State *L, struct nk_vec2 *field) { - struct nk_love_context *ctx = nk_love_checkcontext(1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); static const char *msg = "%s: vec2 fields must have x and y components"; - nk_love_assert(lua_istable(L, -1), msg); + nk_love_assert(L, lua_istable(L, -1), msg); lua_getfield(L, -1, "x"); - nk_love_assert(lua_isnumber(L, -1), msg); + nk_love_assert(L, lua_isnumber(L, -1), msg); lua_getfield(L, -2, "y"); - nk_love_assert(lua_isnumber(L, -1), msg); + nk_love_assert(L, lua_isnumber(L, -1), msg); struct nk_vec2 vec2; vec2.x = lua_tonumber(L, -2); vec2.y = lua_tonumber(L, -1); @@ -3206,20 +3670,20 @@ static int nk_love_style_push_vec2(struct nk_vec2 *field) return success; } -static int nk_love_style_push_item(struct nk_style_item *field) +static int nk_love_style_push_item(lua_State *L, struct nk_style_item *field) { - struct nk_love_context *ctx = nk_love_checkcontext(1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); struct nk_style_item item; if (lua_isstring(L, -1)) { - if (!nk_love_is_color(-1)) { + if (!nk_love_is_color(L, -1)) { const char *msg = lua_pushfstring(L, "%%s: bad color string '%s'", lua_tostring(L, -1)); - nk_love_assert(0, msg); + nk_love_assert(L, 0, msg); } item.type = NK_STYLE_ITEM_COLOR; - item.data.color = nk_love_checkcolor(-1); + item.data.color = nk_love_checkcolor(L, -1); } else { item.type = NK_STYLE_ITEM_IMAGE; - nk_love_checkImage(-1, &item.data.image); + nk_love_checkImage(L, -1, &item.data.image); } int success = nk_style_push_style_item(&ctx->nkctx, field, item); if (success) { @@ -3230,10 +3694,10 @@ static int nk_love_style_push_item(struct nk_style_item *field) return success; } -static int nk_love_style_push_align(nk_flags *field) +static int nk_love_style_push_align(lua_State *L, nk_flags *field) { - struct nk_love_context *ctx = nk_love_checkcontext(1); - nk_flags align = nk_love_checkalign(-1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); + nk_flags align = nk_love_checkalign(L, -1); int success = nk_style_push_flags(&ctx->nkctx, field, align); if (success) { lua_pushstring(L, "flags"); @@ -3243,9 +3707,9 @@ static int nk_love_style_push_align(nk_flags *field) return success; } -static int nk_love_style_push_float(float *field) +static int nk_love_style_push_float(lua_State *L, float *field) { - struct nk_love_context *ctx = nk_love_checkcontext(1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); float f = luaL_checknumber(L, -1); int success = nk_style_push_float(&ctx->nkctx, field, f); if (success) { @@ -3256,11 +3720,11 @@ static int nk_love_style_push_float(float *field) return success; } -static int nk_love_style_push_font(const struct nk_user_font **field) +static int nk_love_style_push_font(lua_State *L, const struct nk_user_font **field) { - struct nk_love_context *ctx = nk_love_checkcontext(1); - nk_love_checkFont(-1, &context->fonts[context->font_count]); - int success = nk_style_push_font(&ctx->nkctx, &context->fonts[context->font_count++]); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); + nk_love_checkFont(L, -1, &context->fonts[context->font_count]); + int success = nk_style_push_font(&ctx->nkctx, &context->fonts[context->font_count++].font); if (success) { lua_pushstring(L, "font"); size_t stack_size = lua_objlen(L, 2); @@ -3270,22 +3734,22 @@ static int nk_love_style_push_font(const struct nk_user_font **field) } #define NK_LOVE_STYLE_PUSH(name, type, field) \ - nk_love_assert(lua_istable(L, -1), "%s: " name " field must be a table"); \ + nk_love_assert(L, lua_istable(L, -1), "%s: " name " field must be a table"); \ lua_getfield(L, -1, name); \ if (!lua_isnil(L, -1)) \ - nk_love_style_push_##type(field); \ + nk_love_style_push_##type(L, field); \ lua_pop(L, 1); -static void nk_love_style_push_text(struct nk_style_text *style) +static void nk_love_style_push_text(lua_State *L, struct nk_style_text *style) { - nk_love_assert(lua_istable(L, -1), "%s: text style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: text style must be a table"); NK_LOVE_STYLE_PUSH("color", color, &style->color); NK_LOVE_STYLE_PUSH("padding", vec2, &style->padding); } -static void nk_love_style_push_button(struct nk_style_button *style) +static void nk_love_style_push_button(lua_State *L, struct nk_style_button *style) { - nk_love_assert(lua_istable(L, -1), "%s: button style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: button style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3302,9 +3766,9 @@ static void nk_love_style_push_button(struct nk_style_button *style) NK_LOVE_STYLE_PUSH("touch padding", vec2, &style->touch_padding); } -static void nk_love_style_push_scrollbar(struct nk_style_scrollbar *style) +static void nk_love_style_push_scrollbar(lua_State *L, struct nk_style_scrollbar *style) { - nk_love_assert(lua_istable(L, -1), "%s: scrollbar style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: scrollbar style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3320,9 +3784,9 @@ static void nk_love_style_push_scrollbar(struct nk_style_scrollbar *style) NK_LOVE_STYLE_PUSH("padding", vec2, &style->padding); } -static void nk_love_style_push_edit(struct nk_style_edit *style) +static void nk_love_style_push_edit(lua_State *L, struct nk_style_edit *style) { - nk_love_assert(lua_istable(L, -1), "%s: edit style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: edit style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3347,9 +3811,9 @@ static void nk_love_style_push_edit(struct nk_style_edit *style) NK_LOVE_STYLE_PUSH("row padding", float, &style->row_padding); } -static void nk_love_style_push_toggle(struct nk_style_toggle *style) +static void nk_love_style_push_toggle(lua_State *L, struct nk_style_toggle *style) { - nk_love_assert(lua_istable(L, -1), "%s: toggle style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: toggle style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3367,9 +3831,9 @@ static void nk_love_style_push_toggle(struct nk_style_toggle *style) NK_LOVE_STYLE_PUSH("border", float, &style->border); } -static void nk_love_style_push_selectable(struct nk_style_selectable *style) +static void nk_love_style_push_selectable(lua_State *L, struct nk_style_selectable *style) { - nk_love_assert(lua_istable(L, -1), "%s: selectable style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: selectable style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("pressed", item, &style->pressed); @@ -3390,9 +3854,9 @@ static void nk_love_style_push_selectable(struct nk_style_selectable *style) NK_LOVE_STYLE_PUSH("image padding", vec2, &style->image_padding); } -static void nk_love_style_push_slider(struct nk_style_slider *style) +static void nk_love_style_push_slider(lua_State *L, struct nk_style_slider *style) { - nk_love_assert(lua_istable(L, -1), "%s: slider style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: slider style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3411,16 +3875,16 @@ static void nk_love_style_push_slider(struct nk_style_slider *style) NK_LOVE_STYLE_PUSH("cursor size", vec2, &style->cursor_size); } -static void nk_love_style_push_progress(struct nk_style_progress *style) +static void nk_love_style_push_progress(lua_State *L, struct nk_style_progress *style) { - nk_love_assert(lua_istable(L, -1), "%s: progress style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: progress style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); NK_LOVE_STYLE_PUSH("border color", color, &style->border_color); NK_LOVE_STYLE_PUSH("cursor normal", item, &style->cursor_normal); NK_LOVE_STYLE_PUSH("cursor hover", item, &style->cursor_hover); - NK_LOVE_STYLE_PUSH("cusor active", item, &style->cursor_active); + NK_LOVE_STYLE_PUSH("cursor active", item, &style->cursor_active); NK_LOVE_STYLE_PUSH("cursor border color", color, &style->cursor_border_color); NK_LOVE_STYLE_PUSH("rounding", float, &style->rounding); NK_LOVE_STYLE_PUSH("border", float, &style->border); @@ -3429,9 +3893,9 @@ static void nk_love_style_push_progress(struct nk_style_progress *style) NK_LOVE_STYLE_PUSH("padding", vec2, &style->padding); } -static void nk_love_style_push_property(struct nk_style_property *style) +static void nk_love_style_push_property(lua_State *L, struct nk_style_property *style) { - nk_love_assert(lua_istable(L, -1), "%s: property style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: property style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3447,9 +3911,9 @@ static void nk_love_style_push_property(struct nk_style_property *style) NK_LOVE_STYLE_PUSH("dec button", button, &style->dec_button); } -static void nk_love_style_push_chart(struct nk_style_chart *style) +static void nk_love_style_push_chart(lua_State *L, struct nk_style_chart *style) { - nk_love_assert(lua_istable(L, -1), "%s: chart style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: chart style must be a table"); NK_LOVE_STYLE_PUSH("background", item, &style->background); NK_LOVE_STYLE_PUSH("border color", color, &style->border_color); NK_LOVE_STYLE_PUSH("selected color", color, &style->selected_color); @@ -3459,9 +3923,9 @@ static void nk_love_style_push_chart(struct nk_style_chart *style) NK_LOVE_STYLE_PUSH("padding", vec2, &style->padding); } -static void nk_love_style_push_tab(struct nk_style_tab *style) +static void nk_love_style_push_tab(lua_State *L, struct nk_style_tab *style) { - nk_love_assert(lua_istable(L, -1), "%s: tab style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: tab style must be a table"); NK_LOVE_STYLE_PUSH("background", item, &style->background); NK_LOVE_STYLE_PUSH("border color", color, &style->border_color); NK_LOVE_STYLE_PUSH("text", color, &style->text); @@ -3476,9 +3940,9 @@ static void nk_love_style_push_tab(struct nk_style_tab *style) NK_LOVE_STYLE_PUSH("spacing", vec2, &style->spacing); } -static void nk_love_style_push_combo(struct nk_style_combo *style) +static void nk_love_style_push_combo(lua_State *L, struct nk_style_combo *style) { - nk_love_assert(lua_istable(L, -1), "%s: combo style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: combo style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3497,9 +3961,9 @@ static void nk_love_style_push_combo(struct nk_style_combo *style) NK_LOVE_STYLE_PUSH("spacing", vec2, &style->spacing); } -static void nk_love_style_push_window_header(struct nk_style_window_header *style) +static void nk_love_style_push_window_header(lua_State *L, struct nk_style_window_header *style) { - nk_love_assert(lua_istable(L, -1), "%s: window header style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: window header style must be a table"); NK_LOVE_STYLE_PUSH("normal", item, &style->normal); NK_LOVE_STYLE_PUSH("hover", item, &style->hover); NK_LOVE_STYLE_PUSH("active", item, &style->active); @@ -3513,9 +3977,9 @@ static void nk_love_style_push_window_header(struct nk_style_window_header *styl NK_LOVE_STYLE_PUSH("spacing", vec2, &style->spacing); } -static void nk_love_style_push_window(struct nk_style_window *style) +static void nk_love_style_push_window(lua_State *L, struct nk_style_window *style) { - nk_love_assert(lua_istable(L, -1), "%s: window style must be a table"); + nk_love_assert(L, lua_istable(L, -1), "%s: window style must be a table"); NK_LOVE_STYLE_PUSH("header", window_header, &style->header); NK_LOVE_STYLE_PUSH("fixed background", item, &style->fixed_background); NK_LOVE_STYLE_PUSH("background", color, &style->background); @@ -3549,10 +4013,13 @@ static void nk_love_style_push_window(struct nk_style_window *style) static int nk_love_style_push(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); if (!lua_istable(L, 2)) luaL_typerror(L, 2, "table"); + int outOfContext = (context == NULL); + if (outOfContext) + context = ctx; lua_newtable(L); lua_insert(L, 2); NK_LOVE_STYLE_PUSH("font", font, &ctx->nkctx.style.font); @@ -3581,13 +4048,18 @@ static int nk_love_style_push(lua_State *L) size_t stack_size = lua_objlen(L, -1); lua_pushvalue(L, 2); lua_rawseti(L, -2, stack_size + 1); + if (outOfContext) + context = NULL; return 0; } static int nk_love_style_pop(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - struct nk_love_context *ctx = nk_love_checkcontext(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + struct nk_love_context *ctx = nk_love_checkcontext(L, 1); + int outOfContext = (context == NULL); + if (outOfContext) + context = ctx; lua_getfield(L, LUA_REGISTRYINDEX, "nuklear"); lua_pushlightuserdata(L, ctx); lua_gettable(L, -2); @@ -3615,10 +4087,33 @@ static int nk_love_style_pop(lua_State *L) nk_style_pop_font(&ctx->nkctx); } else { const char *msg = lua_pushfstring(L, "%%s: bad style item type '%s'", lua_tostring(L, -1)); - nk_love_assert(0, msg); + nk_love_assert(L, 0, msg); } lua_pop(L, 1); } + if (outOfContext) + context = NULL; + return 0; +} + +static int nk_love_style(lua_State *L) +{ + nk_love_assert(L, lua_checkstack(L, 3), "%s: failed to allocate stack space"); + nk_love_assert_argc(L, lua_gettop(L) == 3); + if (!lua_isfunction(L, -1)) + luaL_typerror(L, lua_gettop(L), "function"); + lua_pushvalue(L, 1); + lua_insert(L, 2); + lua_pushvalue(L, 1); + lua_insert(L, 3); + lua_insert(L, 2); + lua_getfield(L, 1, "stylePush"); + lua_insert(L, 4); + lua_call(L, 2, 0); + lua_call(L, 1, 0); + lua_getfield(L, 1, "stylePop"); + lua_insert(L, 1); + lua_call(L, 1, 0); return 0; } @@ -3632,8 +4127,8 @@ static int nk_love_style_pop(lua_State *L) static int nk_love_widget_bounds(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_rect bounds = nk_widget_bounds(&context->nkctx); lua_pushnumber(L, bounds.x); lua_pushnumber(L, bounds.y); @@ -3644,8 +4139,8 @@ static int nk_love_widget_bounds(lua_State *L) static int nk_love_widget_position(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_vec2 pos = nk_widget_position(&context->nkctx); lua_pushnumber(L, pos.x); lua_pushnumber(L, pos.y); @@ -3654,8 +4149,8 @@ static int nk_love_widget_position(lua_State *L) static int nk_love_widget_size(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); struct nk_vec2 pos = nk_widget_size(&context->nkctx); lua_pushnumber(L, pos.x); lua_pushnumber(L, pos.y); @@ -3664,8 +4159,8 @@ static int nk_love_widget_size(lua_State *L) static int nk_love_widget_width(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); float width = nk_widget_width(&context->nkctx); lua_pushnumber(L, width); return 1; @@ -3673,8 +4168,8 @@ static int nk_love_widget_width(lua_State *L) static int nk_love_widget_height(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); float height = nk_widget_height(&context->nkctx); lua_pushnumber(L, height); return 1; @@ -3682,8 +4177,8 @@ static int nk_love_widget_height(lua_State *L) static int nk_love_widget_is_hovered(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 1); + nk_love_assert_context(L, 1); int hovered = nk_widget_is_hovered(&context->nkctx); lua_pushboolean(L, hovered); return 1; @@ -3692,11 +4187,11 @@ static int nk_love_widget_is_hovered(lua_State *L) static int nk_love_widget_has_mouse(lua_State *L, int down) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 1 && argc <= 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 1 && argc <= 2); + nk_love_assert_context(L, 1); enum nk_buttons button = NK_BUTTON_LEFT; if (argc >= 2 && !lua_isnil(L, 2)) - button = nk_love_checkbutton(2); + button = nk_love_checkbutton(L, 2); int ret = nk_widget_has_mouse_click_down(&context->nkctx, button, down); lua_pushboolean(L, ret); return 1; @@ -3715,11 +4210,11 @@ static int nk_love_widget_has_mouse_released(lua_State *L) static int nk_love_widget_is_mouse(lua_State *L, int down) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 1 && argc <= 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 1 && argc <= 2); + nk_love_assert_context(L, 1); enum nk_buttons button = NK_BUTTON_LEFT; if (argc >= 2 && !lua_isnil(L, 2)) - button = nk_love_checkbutton(2); + button = nk_love_checkbutton(L, 2); struct nk_rect bounds = nk_widget_bounds(&context->nkctx); int ret = nk_input_is_mouse_click_down_in_rect(&context->nkctx.input, button, bounds, down); lua_pushboolean(L, ret); @@ -3738,8 +4233,8 @@ static int nk_love_widget_is_mouse_released(lua_State *L) static int nk_love_spacing(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 2); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 2); + nk_love_assert_context(L, 1); int cols = luaL_checkint(L, 2); nk_spacing(&context->nkctx, cols); return 0; @@ -3748,24 +4243,24 @@ static int nk_love_spacing(lua_State *L) static int nk_love_line(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 5 && argc % 2 == 1); - nk_love_assert_context(1); + nk_love_assert_argc(L, argc >= 5 && argc % 2 == 1); + nk_love_assert_context(L, 1); int i; for (i = 0; i < argc - 1; ++i) { - nk_love_assert(lua_isnumber(L, i + 2), "%s: point coordinates should be numbers"); + nk_love_assert(L, lua_isnumber(L, i + 2), "%s: point coordinates should be numbers"); points[i] = lua_tonumber(L, i + 2); } float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); nk_stroke_polyline(&context->nkctx.current->buffer, points, (argc - 1) / 2, line_thickness, color); return 0; } static int nk_love_curve(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 9); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 9); + nk_love_assert_context(L, 1); int i; float ax = luaL_checknumber(L, 2); float ay = luaL_checknumber(L, 3); @@ -3777,7 +4272,7 @@ static int nk_love_curve(lua_State *L) float by = luaL_checknumber(L, 9); float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); nk_stroke_curve(&context->nkctx.current->buffer, ax, ay, ctrl0x, ctrl0y, ctrl1x, ctrl1y, bx, by, line_thickness, color); return 0; } @@ -3785,17 +4280,17 @@ static int nk_love_curve(lua_State *L) static int nk_love_polygon(lua_State *L) { int argc = lua_gettop(L); - nk_love_assert_argc(argc >= 8 && argc % 2 == 0); - nk_love_assert_context(1); - enum nk_love_draw_mode mode = nk_love_checkdraw(2); + nk_love_assert_argc(L, argc >= 8 && argc % 2 == 0); + nk_love_assert_context(L, 1); + enum nk_love_draw_mode mode = nk_love_checkdraw(L, 2); int i; for (i = 0; i < argc - 2; ++i) { - nk_love_assert(lua_isnumber(L, i + 3), "%s: point coordinates should be numbers"); + nk_love_assert(L, lua_isnumber(L, i + 3), "%s: point coordinates should be numbers"); points[i] = lua_tonumber(L, i + 3); } float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); if (mode == NK_LOVE_FILL) nk_fill_polygon(&context->nkctx.current->buffer, points, (argc - 2) / 2, color); else if (mode == NK_LOVE_LINE) @@ -3805,15 +4300,15 @@ static int nk_love_polygon(lua_State *L) static int nk_love_circle(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); - enum nk_love_draw_mode mode = nk_love_checkdraw(2); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); + enum nk_love_draw_mode mode = nk_love_checkdraw(L, 2); float x = luaL_checknumber(L, 3); float y = luaL_checknumber(L, 4); float r = luaL_checknumber(L, 5); float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); if (mode == NK_LOVE_FILL) nk_fill_circle(&context->nkctx.current->buffer, nk_rect(x - r, y - r, r * 2, r * 2), color); else if (mode == NK_LOVE_LINE) @@ -3823,16 +4318,16 @@ static int nk_love_circle(lua_State *L) static int nk_love_ellipse(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 6); - nk_love_assert_context(1); - enum nk_love_draw_mode mode = nk_love_checkdraw(2); + nk_love_assert_argc(L, lua_gettop(L) == 6); + nk_love_assert_context(L, 1); + enum nk_love_draw_mode mode = nk_love_checkdraw(L, 2); float x = luaL_checknumber(L, 3); float y = luaL_checknumber(L, 4); float rx = luaL_checknumber(L, 5); float ry = luaL_checknumber(L, 6); float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); if (mode == NK_LOVE_FILL) nk_fill_circle(&context->nkctx.current->buffer, nk_rect(x - rx, y - ry, rx * 2, ry * 2), color); else if (mode == NK_LOVE_LINE) @@ -3842,9 +4337,9 @@ static int nk_love_ellipse(lua_State *L) static int nk_love_arc(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 7); - nk_love_assert_context(1); - enum nk_love_draw_mode mode = nk_love_checkdraw(2); + nk_love_assert_argc(L, lua_gettop(L) == 7); + nk_love_assert_context(L, 1); + enum nk_love_draw_mode mode = nk_love_checkdraw(L, 2); float cx = luaL_checknumber(L, 3); float cy = luaL_checknumber(L, 4); float r = luaL_checknumber(L, 5); @@ -3852,7 +4347,7 @@ static int nk_love_arc(lua_State *L) float a1 = luaL_checknumber(L, 7); float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); + nk_love_getGraphics(L, &line_thickness, &color); if (mode == NK_LOVE_FILL) nk_fill_arc(&context->nkctx.current->buffer, cx, cy, r, a0, a1, color); else if (mode == NK_LOVE_LINE) @@ -3862,24 +4357,24 @@ static int nk_love_arc(lua_State *L) static int nk_love_rect_multi_color(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 9); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 9); + nk_love_assert_context(L, 1); float x = luaL_checknumber(L, 2); float y = luaL_checknumber(L, 3); float w = luaL_checknumber(L, 4); float h = luaL_checknumber(L, 5); - struct nk_color topLeft = nk_love_checkcolor(6); - struct nk_color topRight = nk_love_checkcolor(7); - struct nk_color bottomLeft = nk_love_checkcolor(8); - struct nk_color bottomRight = nk_love_checkcolor(9); + struct nk_color topLeft = nk_love_checkcolor(L, 6); + struct nk_color topRight = nk_love_checkcolor(L, 7); + struct nk_color bottomLeft = nk_love_checkcolor(L, 8); + struct nk_color bottomRight = nk_love_checkcolor(L, 9); nk_fill_rect_multi_color(&context->nkctx.current->buffer, nk_rect(x, y, w, h), topLeft, topRight, bottomLeft, bottomRight); return 0; } static int nk_love_push_scissor(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); float x = luaL_checknumber(L, 2); float y = luaL_checknumber(L, 3); float w = luaL_checknumber(L, 4); @@ -3890,8 +4385,8 @@ static int nk_love_push_scissor(lua_State *L) static int nk_love_text(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 6); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 6); + nk_love_assert_context(L, 1); const char *text = luaL_checkstring(L, 2); float x = luaL_checknumber(L, 3); float y = luaL_checknumber(L, 4); @@ -3901,20 +4396,20 @@ static int nk_love_text(lua_State *L) lua_getfield(L, -1, "graphics"); lua_getfield(L, -1, "getFont"); lua_call(L, 0, 1); - nk_love_checkFont(-1, &context->fonts[context->font_count]); + nk_love_checkFont(L, -1, &context->fonts[context->font_count]); float line_thickness; struct nk_color color; - nk_love_getGraphics(&line_thickness, &color); - nk_draw_text(&context->nkctx.current->buffer, nk_rect(x, y, w, h), text, strlen(text), &context->fonts[context->font_count++], nk_rgba(0, 0, 0, 0), color); + nk_love_getGraphics(L, &line_thickness, &color); + nk_draw_text(&context->nkctx.current->buffer, nk_rect(x, y, w, h), text, strlen(text), &context->fonts[context->font_count++].font, nk_rgba(0, 0, 0, 0), color); return 0; } -static int nk_love_input_has_mouse(int down) +static int nk_love_input_has_mouse(lua_State *L, int down) { int argc = lua_gettop(L); - nk_love_assert_argc(argc == 6); - nk_love_assert_context(1); - enum nk_buttons button = nk_love_checkbutton(2); + nk_love_assert_argc(L, argc == 6); + nk_love_assert_context(L, 1); + enum nk_buttons button = nk_love_checkbutton(L, 2); float x = luaL_checknumber(L, 3); float y = luaL_checknumber(L, 4); float w = luaL_checknumber(L, 5); @@ -3926,20 +4421,20 @@ static int nk_love_input_has_mouse(int down) static int nk_love_input_has_mouse_pressed(lua_State *L) { - return nk_love_input_has_mouse(nk_true); + return nk_love_input_has_mouse(L, nk_true); } static int nk_love_input_has_mouse_released(lua_State *L) { - return nk_love_input_has_mouse(nk_false); + return nk_love_input_has_mouse(L, nk_false); } -static int nk_love_input_is_mouse(int down) +static int nk_love_input_is_mouse(lua_State *L, int down) { int argc = lua_gettop(L); - nk_love_assert_argc(argc == 6); - nk_love_assert_context(1); - enum nk_buttons button = nk_love_checkbutton(2); + nk_love_assert_argc(L, argc == 6); + nk_love_assert_context(L, 1); + enum nk_buttons button = nk_love_checkbutton(L, 2); float x = luaL_checknumber(L, 3); float y = luaL_checknumber(L, 4); float w = luaL_checknumber(L, 5); @@ -3951,18 +4446,18 @@ static int nk_love_input_is_mouse(int down) static int nk_love_input_is_mouse_pressed(lua_State *L) { - return nk_love_input_is_mouse(nk_true); + return nk_love_input_is_mouse(L, nk_true); } static int nk_love_input_is_mouse_released(lua_State *L) { - return nk_love_input_is_mouse(nk_false); + return nk_love_input_is_mouse(L, nk_false); } static int nk_love_input_was_hovered(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); float x = luaL_checknumber(L, 2); float y = luaL_checknumber(L, 3); float w = luaL_checknumber(L, 4); @@ -3974,8 +4469,8 @@ static int nk_love_input_was_hovered(lua_State *L) static int nk_love_input_is_hovered(lua_State *L) { - nk_love_assert_argc(lua_gettop(L) == 5); - nk_love_assert_context(1); + nk_love_assert_argc(L, lua_gettop(L) == 5); + nk_love_assert_context(L, 1); float x = luaL_checknumber(L, 2); float y = luaL_checknumber(L, 3); float w = luaL_checknumber(L, 4); @@ -3997,19 +4492,18 @@ static int nk_love_input_is_hovered(lua_State *L) lua_pushcfunction(L, func); \ lua_setfield(L, -2, name) -LUALIB_API int luaopen_nuklear(lua_State *luaState) +LUALIB_API int luaopen_nuklear(lua_State *L) { - L = luaState; - edit_buffer = nk_love_malloc(NK_LOVE_EDIT_BUFFER_LEN); - combobox_items = nk_love_malloc(sizeof(char*) * NK_LOVE_COMBOBOX_MAX_ITEMS); - points = nk_love_malloc(sizeof(float) * NK_LOVE_MAX_POINTS * 2); + edit_buffer = nk_love_malloc(L, NK_LOVE_EDIT_BUFFER_LEN); + combobox_items = nk_love_malloc(L, sizeof(char*) * NK_LOVE_COMBOBOX_MAX_ITEMS); + points = nk_love_malloc(L, sizeof(float) * NK_LOVE_MAX_POINTS * 2); lua_newtable(L); lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, "nuklear"); lua_getglobal(L, "love"); - nk_love_assert(lua_istable(L, -1), "LOVE-Nuklear requires LOVE environment"); + nk_love_assert(L, lua_istable(L, -1), "LOVE-Nuklear requires LOVE environment"); lua_pop(L, 1); lua_newtable(L); @@ -4026,6 +4520,7 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("frameBegin", nk_love_frame_begin); NK_LOVE_REGISTER("frameEnd", nk_love_frame_end); + NK_LOVE_REGISTER("frame", nk_love_frame); NK_LOVE_REGISTER("rotate", nk_love_rotate); NK_LOVE_REGISTER("scale", nk_love_scale); @@ -4034,9 +4529,11 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("windowBegin", nk_love_window_begin); NK_LOVE_REGISTER("windowEnd", nk_love_window_end); + NK_LOVE_REGISTER("window", nk_love_window); NK_LOVE_REGISTER("windowGetBounds", nk_love_window_get_bounds); NK_LOVE_REGISTER("windowGetPosition", nk_love_window_get_position); NK_LOVE_REGISTER("windowGetSize", nk_love_window_get_size); + NK_LOVE_REGISTER("windowGetScroll", nk_love_window_get_scroll); NK_LOVE_REGISTER("windowGetContentRegion", nk_love_window_get_content_region); NK_LOVE_REGISTER("windowHasFocus", nk_love_window_has_focus); NK_LOVE_REGISTER("windowIsCollapsed", nk_love_window_is_collapsed); @@ -4050,6 +4547,7 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("windowSetPosition", nk_love_window_set_position); NK_LOVE_REGISTER("windowSetSize", nk_love_window_set_size); NK_LOVE_REGISTER("windowSetFocus", nk_love_window_set_focus); + NK_LOVE_REGISTER("windowSetScroll", nk_love_window_set_scroll); NK_LOVE_REGISTER("windowClose", nk_love_window_close); NK_LOVE_REGISTER("windowCollapse", nk_love_window_collapse); NK_LOVE_REGISTER("windowExpand", nk_love_window_expand); @@ -4063,9 +4561,11 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("layoutTemplateBegin", nk_love_layout_template_begin); NK_LOVE_REGISTER("layoutTemplatePush", nk_love_layout_template_push); NK_LOVE_REGISTER("layoutTemplateEnd", nk_love_layout_template_end); + NK_LOVE_REGISTER("layoutTemplate", nk_love_layout_template); NK_LOVE_REGISTER("layoutSpaceBegin", nk_love_layout_space_begin); NK_LOVE_REGISTER("layoutSpacePush", nk_love_layout_space_push); NK_LOVE_REGISTER("layoutSpaceEnd", nk_love_layout_space_end); + NK_LOVE_REGISTER("layoutSpace", nk_love_layout_space); NK_LOVE_REGISTER("layoutSpaceBounds", nk_love_layout_space_bounds); NK_LOVE_REGISTER("layoutSpaceToScreen", nk_love_layout_space_to_screen); NK_LOVE_REGISTER("layoutSpaceToLocal", nk_love_layout_space_to_local); @@ -4075,9 +4575,17 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("groupBegin", nk_love_group_begin); NK_LOVE_REGISTER("groupEnd", nk_love_group_end); + NK_LOVE_REGISTER("group", nk_love_group); + NK_LOVE_REGISTER("groupGetScroll", nk_love_group_get_scroll); + NK_LOVE_REGISTER("groupSetScroll", nk_love_group_set_scroll); NK_LOVE_REGISTER("treePush", nk_love_tree_push); NK_LOVE_REGISTER("treePop", nk_love_tree_pop); + NK_LOVE_REGISTER("tree", nk_love_tree); + + NK_LOVE_REGISTER("treeStatePush", nk_love_tree_state_push); + NK_LOVE_REGISTER("treeStatePop", nk_love_tree_state_pop); + NK_LOVE_REGISTER("treeState", nk_love_tree_state); NK_LOVE_REGISTER("label", nk_love_label); NK_LOVE_REGISTER("image", nk_love_image); @@ -4098,6 +4606,9 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("popupBegin", nk_love_popup_begin); NK_LOVE_REGISTER("popupClose", nk_love_popup_close); NK_LOVE_REGISTER("popupEnd", nk_love_popup_end); + NK_LOVE_REGISTER("popup", nk_love_popup); + NK_LOVE_REGISTER("popupGetScroll", nk_love_popup_get_scroll); + NK_LOVE_REGISTER("popupSetScroll", nk_love_popup_set_scroll); NK_LOVE_REGISTER("combobox", nk_love_combobox); NK_LOVE_REGISTER("comboboxBegin", nk_love_combobox_begin); NK_LOVE_REGISTER("comboboxItem", nk_love_combobox_item); @@ -4107,21 +4618,25 @@ LUALIB_API int luaopen_nuklear(lua_State *luaState) NK_LOVE_REGISTER("contextualItem", nk_love_contextual_item); NK_LOVE_REGISTER("contextualClose", nk_love_contextual_close); NK_LOVE_REGISTER("contextualEnd", nk_love_contextual_end); + NK_LOVE_REGISTER("contextual", nk_love_contextual); NK_LOVE_REGISTER("tooltip", nk_love_tooltip); NK_LOVE_REGISTER("tooltipBegin", nk_love_tooltip_begin); NK_LOVE_REGISTER("tooltipEnd", nk_love_tooltip_end); NK_LOVE_REGISTER("menubarBegin", nk_love_menubar_begin); NK_LOVE_REGISTER("menubarEnd", nk_love_menubar_end); + NK_LOVE_REGISTER("menubar", nk_love_menubar); NK_LOVE_REGISTER("menuBegin", nk_love_menu_begin); NK_LOVE_REGISTER("menuItem", nk_love_menu_item); NK_LOVE_REGISTER("menuClose", nk_love_menu_close); NK_LOVE_REGISTER("menuEnd", nk_love_menu_end); + NK_LOVE_REGISTER("menu", nk_love_menu); NK_LOVE_REGISTER("styleDefault", nk_love_style_default); NK_LOVE_REGISTER("styleLoadColors", nk_love_style_load_colors); NK_LOVE_REGISTER("styleSetFont", nk_love_style_set_font); NK_LOVE_REGISTER("stylePush", nk_love_style_push); NK_LOVE_REGISTER("stylePop", nk_love_style_pop); + NK_LOVE_REGISTER("style", nk_love_style); NK_LOVE_REGISTER("widgetBounds", nk_love_widget_bounds); NK_LOVE_REGISTER("widgetPosition", nk_love_widget_position);