From 9699a814395dd6344c0f2fab1965b8bed30967b2 Mon Sep 17 00:00:00 2001 From: sanine-a Date: Sat, 24 Oct 2020 23:56:18 -0500 Subject: add window focus callback functions --- demo/main.lua | 8 ++++++ src/window/window.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/window/window.h | 22 ++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/demo/main.lua b/demo/main.lua index e7f95c1..9cae165 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -16,6 +16,14 @@ honey.window.set_title('honey engine demo') honey.input.bind_key(honey.input.key.a, a_func) honey.window.resize_bind(resize_func) + +local focus_func = function(focus) + print('focus:', focus) +end + +honey.window.focus_bind(focus_func) + + function honey.update(dt) end diff --git a/src/window/window.c b/src/window/window.c index 0980c87..da1ddc9 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -3,6 +3,8 @@ int honey_window_info_ref = LUA_NOREF; int honey_window_resize_callback_ref = LUA_NOREF; int honey_window_resize_callback_data_ref = LUA_NOREF; +int honey_window_focus_callback_ref = LUA_NOREF; +int honey_window_focus_callback_data_ref = LUA_NOREF; static void honey_glfw_window_resize_callback(honey_window window, int width, int height) @@ -29,7 +31,32 @@ static void honey_glfw_window_resize_callback(honey_window window, } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static void honey_glfw_window_focus_callback(honey_window window, + int focused) +{ + lua_State* L = glfwGetWindowUserPointer(window); + + int callback = honey_window_focus_callback_ref; + int data = honey_window_focus_callback_data_ref; + + if (callback == LUA_NOREF) + return; + lua_rawgeti(L, LUA_REGISTRYINDEX, callback); + + lua_pushboolean(L, focused); + + if (data == LUA_NOREF || data == LUA_REFNIL) + lua_pushnil(L); + else + lua_rawgeti(L, LUA_REGISTRYINDEX, data); + + honey_lua_pcall(L, 2, 0); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + bool honey_setup_window(lua_State* L) { honey_window_information* info = lua_newuserdata(L, sizeof(honey_window_information)); @@ -68,6 +95,8 @@ bool honey_setup_window(lua_State* L) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glfwSetWindowSizeCallback(info->window, honey_glfw_window_resize_callback); + glfwSetWindowFocusCallback(info->window, honey_glfw_window_focus_callback); + honey_lua_element window_elements[] = { { "set_fullscreen", HONEY_FUNC, { .function = honey_window_set_fullscreen } }, @@ -76,9 +105,11 @@ bool honey_setup_window(lua_State* L) { "set_size", HONEY_FUNC, { .function = honey_window_set_size } }, { "resize_bind", HONEY_FUNC, { .function = honey_window_resize_bind } }, { "resize_unbind", HONEY_FUNC, { .function = honey_window_resize_unbind } }, + { "focus_bind", HONEY_FUNC, { .function = honey_window_focus_bind } }, + { "focus_unbind", HONEY_FUNC, { .function = honey_window_focus_unbind } }, }; - honey_lua_create_table(L, window_elements, 6); + honey_lua_create_table(L, window_elements, 8); return true; } @@ -175,7 +206,57 @@ int honey_window_resize_bind(lua_State* L) int honey_window_resize_unbind(lua_State* L) { + int callback = honey_window_resize_callback_ref; + int data = honey_window_resize_callback_data_ref; + + if (callback != LUA_NOREF) { + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, callback); + } + + if (data != LUA_NOREF && data != LUA_REFNIL) { + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, callback); + } + honey_window_resize_callback_ref = LUA_NOREF; honey_window_resize_callback_data_ref = LUA_NOREF; return 0; } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_window_focus_bind(lua_State* L) +{ + if (!honey_lua_validate_types(L, 2, HONEY_FUNC, HONEY_ANY)) + lua_error(L); + + lua_pushvalue(L, 1); + honey_window_focus_callback_ref = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushvalue(L, 2); + honey_window_focus_callback_data_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_window_focus_unbind(lua_State* L) +{ + int callback = honey_window_focus_callback_ref; + int data = honey_window_focus_callback_data_ref; + + if (callback != LUA_NOREF) { + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, callback); + } + + if (data != LUA_NOREF && data != LUA_REFNIL) { + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, callback); + } + + honey_window_focus_callback_ref = LUA_NOREF; + honey_window_focus_callback_data_ref = LUA_NOREF; + return 0; +} diff --git a/src/window/window.h b/src/window/window.h index 7b12156..fae32c1 100644 --- a/src/window/window.h +++ b/src/window/window.h @@ -18,6 +18,8 @@ typedef struct { extern int honey_window_info_ref; extern int honey_window_resize_callback_ref; extern int honey_window_resize_callback_data_ref; +extern int honey_window_focus_callback_ref; +extern int honey_window_focus_callback_data_ref; /** @brief Push the various honey.window table to the stack. * @@ -74,4 +76,24 @@ int honey_window_resize_bind(lua_State* L); */ int honey_window_resize_unbind(lua_State* L); +/** @brief Bind a callback to the window changing focus. + * + * The supplied callback function should be of the form + * function(boolean, data). The boolean is true if the window + * is gaining focus, and false if it is losing focus. The data is + * just the data parameter passed to this function. + * + * @param callback The callback function to call on a window resize. + * @param data Data to send to the callback. + * + * @returns Nothing. + */ +int honey_window_focus_bind(lua_State* L); + +/** @brief Unbind any callback that may be attached to the window focus. + * + * @returns Nothing. + */ +int honey_window_focus_unbind(lua_State* L); + #endif -- cgit v1.2.1