From 1934014659816b0b7704799638f0d7afeccbdfe6 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 4 Jan 2023 13:36:46 -0800 Subject: [PATCH] framework for passthru, z-order swapping windows --- library/LuaApi.cpp | 12 ++++++ library/LuaTools.cpp | 22 +++++++++-- library/include/modules/Screen.h | 1 + library/lua/gui.lua | 66 +++++++++++++++++++++++++++++++- library/lua/gui/widgets.lua | 5 +-- library/modules/Screen.cpp | 4 ++ 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 2f1d612b2..303a319c9 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2456,6 +2456,17 @@ static int screen_findGraphicsTile(lua_State *L) } } +static int screen_raise(lua_State *L) { + df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, false); + + // remove screen from the stack so it doesn't get returned as an output + lua_remove(L, 1); + + Screen::raise(screen); + + return 0; +} + static int screen_hideGuard(lua_State *L) { df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, false); luaL_checktype(L, 2, LUA_TFUNCTION); @@ -2574,6 +2585,7 @@ static const luaL_Reg dfhack_screen_funcs[] = { { "paintString", screen_paintString }, { "fillRect", screen_fillRect }, { "findGraphicsTile", screen_findGraphicsTile }, + CWRAP(raise, screen_raise), CWRAP(hideGuard, screen_hideGuard), CWRAP(show, screen_show), CWRAP(dismiss, screen_dismiss), diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp index 084e5a21b..c76c65651 100644 --- a/library/LuaTools.cpp +++ b/library/LuaTools.cpp @@ -131,6 +131,9 @@ void DFHack::Lua::GetVector(lua_State *state, std::vector &pvec) } } +static bool trigger_inhibit_l_down = false; +static bool trigger_inhibit_r_down = false; +static bool trigger_inhibit_m_down = false; static bool inhibit_l_down = false; static bool inhibit_r_down = false; static bool inhibit_m_down = false; @@ -161,17 +164,17 @@ void DFHack::Lua::PushInterfaceKeys(lua_State *L, if (!inhibit_l_down && df::global::enabler->mouse_lbut_down) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_L_DOWN"); - inhibit_l_down = true; + trigger_inhibit_l_down = true; } if (!inhibit_r_down && df::global::enabler->mouse_rbut_down) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_R_DOWN"); - inhibit_r_down = true; + trigger_inhibit_r_down = true; } if (!inhibit_m_down && df::global::enabler->mouse_mbut_down) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_M_DOWN"); - inhibit_m_down = true; + trigger_inhibit_m_down = true; } if (df::global::enabler->mouse_lbut) { lua_pushboolean(L, true); @@ -2148,6 +2151,19 @@ void DFHack::Lua::Core::Reset(color_ostream &out, const char *where) lua_settop(State, 0); } + if (trigger_inhibit_l_down) { + trigger_inhibit_l_down = false; + inhibit_l_down = true; + } + if (trigger_inhibit_r_down) { + trigger_inhibit_r_down = false; + inhibit_r_down = true; + } + if (trigger_inhibit_m_down) { + trigger_inhibit_m_down = false; + inhibit_m_down = true; + } + if (!df::global::enabler->mouse_lbut) inhibit_l_down = false; if (!df::global::enabler->mouse_rbut) diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 347df1011..bc8a406a0 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -222,6 +222,7 @@ namespace DFHack DFHACK_EXPORT void dismiss(df::viewscreen *screen, bool to_first = false); DFHACK_EXPORT bool isDismissed(df::viewscreen *screen); DFHACK_EXPORT bool hasActiveScreens(Plugin *p); + DFHACK_EXPORT void raise(df::viewscreen *screen); /// Retrieve the string representation of the bound key. DFHACK_EXPORT std::string getKeyDisplay(df::interface_key key); diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 1742ee342..27484541f 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -484,6 +484,10 @@ function View:getMousePos(view_rect) end end +function View:getMouseFramePos() + return self:getMousePos(ViewRect{rect=self.frame_rect}) +end + function View:computeFrame(parent_rect) return mkdims_wh(0,0,parent_rect.width,parent_rect.height) end @@ -681,9 +685,67 @@ function Screen:onRender() self:render(Painter.new()) end ------------------------- +----------------------------- +-- Z-order swapping screen -- +----------------------------- + +ZScreen = defclass(ZScreen, Screen) + +function ZScreen:onIdle() + if self._native and self._native.parent then + self._native.parent:logic() + end +end + +function ZScreen:render(dc) + self:renderParent() + ZScreen.super.render(self, dc) +end + +local function zscreen_is_top(self) + return dfhack.gui.getCurViewscreen(true) == self._native +end + +function ZScreen:onInput(keys) + if not zscreen_is_top(self) then + if keys._MOUSE_L_DOWN and self:isMouseOver() then + self:raise() + else + self:sendInputToParent(keys) + return + end + end + + if ZScreen.super.onInput(self, keys) then + return + end + if keys.LEAVESCREEN or keys._MOUSE_R_DOWN then + self:dismiss() + return + end + + if not keys._MOUSE_L or not self:isMouseOver() then + self:sendInputToParent(keys) + end +end + +-- move this viewscreen to the top of the stack (if it's not there already) +function ZScreen:raise() + if self:isDismissed() or zscreen_is_top(self) then + return + end + dscreen.raise(self) +end + +-- subclasses should override this and return whether the mouse is over an +-- owned screen element +function ZScreen:isMouseOver() + return false +end + +-------------------------- -- Framed screen object -- ------------------------- +-------------------------- -- Plain grey-colored frame. GREY_FRAME = { diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index c3d89c49b..e95410fb2 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -87,7 +87,7 @@ Panel.ATTRS { function Panel:init(args) if not self.drag_anchors then - self.drag_anchors = {title=true, frame=false, body=false} + self.drag_anchors = {title=true, frame=false, body=true} end if not self.resize_anchors then self.resize_anchors = {t=false, l=true, r=true, b=true} @@ -303,8 +303,7 @@ function Panel:onInput(keys) return true end if not keys._MOUSE_L_DOWN then return end - local rect = self.frame_rect - local x,y = self:getMousePos(gui.ViewRect{rect=rect}) + local x,y = self:getMouseFramePos() if not x then return end if self.resizable and y == 0 then diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index e7f6cea93..65817aa93 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -502,6 +502,10 @@ bool Screen::hasActiveScreens(Plugin *plugin) return false; } +void Screen::raise(df::viewscreen *screen) { + Hide swapper(screen, Screen::Hide::RESTORE_AT_TOP); +} + namespace DFHack { namespace Screen { Hide::Hide(df::viewscreen* screen, int flags) :