From cc0ff6a93dd3635425e6c4604868eb739c5a8348 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 13 Jan 2023 12:16:49 -0800 Subject: [PATCH 1/3] raise trigger lock screens (if possible) so they don't get stuck under new viewscreens and become lost (and therefore overlay will be forever locked) --- plugins/lua/overlay.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/lua/overlay.lua b/plugins/lua/overlay.lua index 4fc375d72..42116735a 100644 --- a/plugins/lua/overlay.lua +++ b/plugins/lua/overlay.lua @@ -43,7 +43,12 @@ end local function triggered_screen_has_lock() if not trigger_lock_holder_screen then return false end - if trigger_lock_holder_screen:isActive() then return true end + if trigger_lock_holder_screen:isActive() then + if trigger_lock_holder_screen.raise then + trigger_lock_holder_screen:raise() + end + return true + end return register_trigger_lock_screen(nil, nil) end @@ -429,9 +434,8 @@ local function _update_viewscreen_widgets(vs_name, vs, now_ms) return now_ms end --- not subject to trigger lock since these widgets are already filtered by --- viewscreen function update_viewscreen_widgets(vs_name, vs) + if triggered_screen_has_lock() then return end local now_ms = _update_viewscreen_widgets(vs_name, vs, nil) _update_viewscreen_widgets('all', vs, now_ms) end From 6c6c4e159f9b86329459214c4da2fc08d3b70cec Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 13 Jan 2023 12:17:51 -0800 Subject: [PATCH 2/3] add reminder why we can't clear mouse_lbut --- library/lua/gui.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 8a2a406aa..a0412a3a8 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -725,6 +725,7 @@ function ZScreen:onInput(keys) if ZScreen.super.onInput(self, keys) then -- ensure underlying DF screens don't also react to handled clicks if keys._MOUSE_L_DOWN then + -- note we can't clear mouse_lbut here. otherwise we break dragging, df.global.enabler.mouse_lbut_down = 0 end if keys._MOUSE_R_DOWN then From 807f3f6327d9930078b1336869933fbc40677baa Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 13 Jan 2023 12:18:18 -0800 Subject: [PATCH 3/3] update behavior of hotspot menu - disappears on click outside its borders - disappears on r-click - mouse over the help panel counts as "over the menu" (so the menu doesn't close if the player moves the mouse to the help text) - menu panels appear next to the logo hotspot instead of over it, allowing players to avoid clicking on the wrong item if they intend to click on the logo --- plugins/lua/hotkeys.lua | 101 +++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 42 deletions(-) diff --git a/plugins/lua/hotkeys.lua b/plugins/lua/hotkeys.lua index 53885d8fa..2fb32a692 100644 --- a/plugins/lua/hotkeys.lua +++ b/plugins/lua/hotkeys.lua @@ -32,12 +32,7 @@ function HotspotMenuWidget:overlay_onupdate() end function HotspotMenuWidget:overlay_trigger() - local hotkeys, bindings = getHotkeys() - return MenuScreen{ - hotspot_frame=self.frame, - hotkeys=hotkeys, - bindings=bindings, - mouseover=self.mouseover}:show() + return MenuScreen{hotspot_frame=self.frame}:show() end local dscreen = dfhack.screen @@ -71,21 +66,17 @@ end -- register the menu hotspot with the overlay OVERLAY_WIDGETS = {menu=HotspotMenuWidget} --- ---------- -- --- MenuScreen -- --- ---------- -- +-- ---- -- +-- Menu -- +-- ---- -- local ARROW = string.char(26) local MAX_LIST_WIDTH = 45 local MAX_LIST_HEIGHT = 15 -MenuScreen = defclass(MenuScreen, gui.Screen) -MenuScreen.ATTRS{ - focus_path='hotkeys/menu', +Menu = defclass(MenuScreen, widgets.Panel) +Menu.ATTRS{ hotspot_frame=DEFAULT_NIL, - hotkeys=DEFAULT_NIL, - bindings=DEFAULT_NIL, - mouseover=false, } -- get a map from the binding string to a list of hotkey strings that all @@ -142,10 +133,11 @@ local function get_choices(hotkeys, bindings, is_inverted) return choices, max_width end -function MenuScreen:init() +function Menu:init() + local hotkeys, bindings = getHotkeys() + local is_inverted = not not self.hotspot_frame.b - local choices,list_width = get_choices(self.hotkeys, self.bindings, - is_inverted) + local choices,list_width = get_choices(hotkeys, bindings, is_inverted) local list_frame = copyall(self.hotspot_frame) list_frame.w = list_width + 2 @@ -156,9 +148,9 @@ function MenuScreen:init() list_frame.b = math.max(0, list_frame.b - 1) end if list_frame.l then - list_frame.l = math.max(0, list_frame.l - 1) + list_frame.l = math.max(0, list_frame.l + 5) else - list_frame.r = math.max(0, list_frame.r - 1) + list_frame.r = math.max(0, list_frame.r + 5) end local help_frame = {w=list_frame.w, l=list_frame.l, r=list_frame.r} @@ -207,11 +199,7 @@ function MenuScreen:init() end end -function MenuScreen:onDismiss() - cleanupHotkeys() -end - -function MenuScreen:onSelect(_, choice) +function Menu:onSelect(_, choice) if not choice or #self.subviews == 0 then return end local first_word = choice.command:trim():split(' +')[1] if first_word:startswith(':') then first_word = first_word:sub(2) end @@ -220,22 +208,21 @@ function MenuScreen:onSelect(_, choice) self.subviews.help_panel:updateLayout() end -function MenuScreen:onSubmit(_, choice) +function Menu:onSubmit(_, choice) if not choice then return end - dfhack.screen.hideGuard(self, dfhack.run_command, choice.command) - self:dismiss() + dfhack.screen.hideGuard(self.parent_view, dfhack.run_command, choice.command) + self.parent_view:dismiss() end -function MenuScreen:onSubmit2(_, choice) +function Menu:onSubmit2(_, choice) if not choice then return end - self:dismiss() + self.parent_view:dismiss() dfhack.run_script('gui/launcher', choice.command) end -function MenuScreen:onInput(keys) - if keys.LEAVESCREEN then - self:dismiss() - return true +function Menu:onInput(keys) + if keys.LEAVESCREEN or keys._MOUSE_R_DOWN then + return false elseif keys.STANDARDSCROLL_RIGHT then self:onSubmit2(self.subviews.list:getSelected()) return true @@ -246,19 +233,28 @@ function MenuScreen:onInput(keys) self:onSubmit2(list:getSelected()) return true end + if not self:getMouseFramePos() then + self.parent_view:dismiss() + return true + end end - return self:inputToSubviews(keys) + self:inputToSubviews(keys) + return true -- we're modal end -function MenuScreen:onRenderFrame(dc, rect) +function Menu:onRenderFrame(dc, rect) if self.initialize then self.initialize() self.initialize = nil end - self:renderParent() end -function MenuScreen:onRenderBody(dc) +function Menu:getMouseFramePos() + return self.subviews.list_panel:getMouseFramePos() or + self.subviews.help_panel:getMouseFramePos() +end + +function Menu:onRenderBody(dc) local panel = self.subviews.list_panel local list = self.subviews.list local idx = list:getIdxUnderMouse() @@ -267,14 +263,35 @@ function MenuScreen:onRenderBody(dc) -- selection, don't override the selection until the mouse moves to -- another item list:setSelected(idx) - self.mouseover = true self.last_mouse_idx = idx - elseif not panel:getMousePos(gui.ViewRect{rect=panel.frame_rect}) - and self.mouseover then + end + if self:getMouseFramePos() then + self.mouseover = true + elseif self.mouseover then -- once the mouse has entered the list area, leaving the frame should -- close the menu screen - self:dismiss() + self.parent_view:dismiss() end end +-- ---------- -- +-- MenuScreen -- +-- ---------- -- + +MenuScreen = defclass(MenuScreen, gui.ZScreen) +MenuScreen.ATTRS { + focus_path='hotkeys/menu', + hotspot_frame=DEFAULT_NIL, +} + +function MenuScreen:init() + self:addviews{ + Menu{hotspot_frame=self.hotspot_frame}, + } +end + +function MenuScreen:onDismiss() + cleanupHotkeys() +end + return _ENV