Merge pull request #2599 from myk002/myk_hotspot_hotfoot

update behavior of hotspot menu
develop
Myk 2023-01-14 01:09:35 -08:00 committed by GitHub
commit 2a84bb61db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 45 deletions

@ -725,6 +725,7 @@ function ZScreen:onInput(keys)
if ZScreen.super.onInput(self, keys) then if ZScreen.super.onInput(self, keys) then
-- ensure underlying DF screens don't also react to handled clicks -- ensure underlying DF screens don't also react to handled clicks
if keys._MOUSE_L_DOWN then 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 df.global.enabler.mouse_lbut_down = 0
end end
if keys._MOUSE_R_DOWN then if keys._MOUSE_R_DOWN then

@ -32,12 +32,7 @@ function HotspotMenuWidget:overlay_onupdate()
end end
function HotspotMenuWidget:overlay_trigger() function HotspotMenuWidget:overlay_trigger()
local hotkeys, bindings = getHotkeys() return MenuScreen{hotspot_frame=self.frame}:show()
return MenuScreen{
hotspot_frame=self.frame,
hotkeys=hotkeys,
bindings=bindings,
mouseover=self.mouseover}:show()
end end
local dscreen = dfhack.screen local dscreen = dfhack.screen
@ -71,21 +66,17 @@ end
-- register the menu hotspot with the overlay -- register the menu hotspot with the overlay
OVERLAY_WIDGETS = {menu=HotspotMenuWidget} OVERLAY_WIDGETS = {menu=HotspotMenuWidget}
-- ---------- -- -- ---- --
-- MenuScreen -- -- Menu --
-- ---------- -- -- ---- --
local ARROW = string.char(26) local ARROW = string.char(26)
local MAX_LIST_WIDTH = 45 local MAX_LIST_WIDTH = 45
local MAX_LIST_HEIGHT = 15 local MAX_LIST_HEIGHT = 15
MenuScreen = defclass(MenuScreen, gui.Screen) Menu = defclass(MenuScreen, widgets.Panel)
MenuScreen.ATTRS{ Menu.ATTRS{
focus_path='hotkeys/menu',
hotspot_frame=DEFAULT_NIL, 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 -- 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 return choices, max_width
end end
function MenuScreen:init() function Menu:init()
local hotkeys, bindings = getHotkeys()
local is_inverted = not not self.hotspot_frame.b local is_inverted = not not self.hotspot_frame.b
local choices,list_width = get_choices(self.hotkeys, self.bindings, local choices,list_width = get_choices(hotkeys, bindings, is_inverted)
is_inverted)
local list_frame = copyall(self.hotspot_frame) local list_frame = copyall(self.hotspot_frame)
list_frame.w = list_width + 2 list_frame.w = list_width + 2
@ -156,9 +148,9 @@ function MenuScreen:init()
list_frame.b = math.max(0, list_frame.b - 1) list_frame.b = math.max(0, list_frame.b - 1)
end end
if list_frame.l then 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 else
list_frame.r = math.max(0, list_frame.r - 1) list_frame.r = math.max(0, list_frame.r + 5)
end end
local help_frame = {w=list_frame.w, l=list_frame.l, r=list_frame.r} local help_frame = {w=list_frame.w, l=list_frame.l, r=list_frame.r}
@ -207,11 +199,7 @@ function MenuScreen:init()
end end
end end
function MenuScreen:onDismiss() function Menu:onSelect(_, choice)
cleanupHotkeys()
end
function MenuScreen:onSelect(_, choice)
if not choice or #self.subviews == 0 then return end if not choice or #self.subviews == 0 then return end
local first_word = choice.command:trim():split(' +')[1] local first_word = choice.command:trim():split(' +')[1]
if first_word:startswith(':') then first_word = first_word:sub(2) end 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() self.subviews.help_panel:updateLayout()
end end
function MenuScreen:onSubmit(_, choice) function Menu:onSubmit(_, choice)
if not choice then return end if not choice then return end
dfhack.screen.hideGuard(self, dfhack.run_command, choice.command) dfhack.screen.hideGuard(self.parent_view, dfhack.run_command, choice.command)
self:dismiss() self.parent_view:dismiss()
end end
function MenuScreen:onSubmit2(_, choice) function Menu:onSubmit2(_, choice)
if not choice then return end if not choice then return end
self:dismiss() self.parent_view:dismiss()
dfhack.run_script('gui/launcher', choice.command) dfhack.run_script('gui/launcher', choice.command)
end end
function MenuScreen:onInput(keys) function Menu:onInput(keys)
if keys.LEAVESCREEN then if keys.LEAVESCREEN or keys._MOUSE_R_DOWN then
self:dismiss() return false
return true
elseif keys.STANDARDSCROLL_RIGHT then elseif keys.STANDARDSCROLL_RIGHT then
self:onSubmit2(self.subviews.list:getSelected()) self:onSubmit2(self.subviews.list:getSelected())
return true return true
@ -246,19 +233,28 @@ function MenuScreen:onInput(keys)
self:onSubmit2(list:getSelected()) self:onSubmit2(list:getSelected())
return true return true
end end
if not self:getMouseFramePos() then
self.parent_view:dismiss()
return true
end
end end
return self:inputToSubviews(keys) self:inputToSubviews(keys)
return true -- we're modal
end end
function MenuScreen:onRenderFrame(dc, rect) function Menu:onRenderFrame(dc, rect)
if self.initialize then if self.initialize then
self.initialize() self.initialize()
self.initialize = nil self.initialize = nil
end end
self:renderParent()
end 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 panel = self.subviews.list_panel
local list = self.subviews.list local list = self.subviews.list
local idx = list:getIdxUnderMouse() local idx = list:getIdxUnderMouse()
@ -267,14 +263,35 @@ function MenuScreen:onRenderBody(dc)
-- selection, don't override the selection until the mouse moves to -- selection, don't override the selection until the mouse moves to
-- another item -- another item
list:setSelected(idx) list:setSelected(idx)
self.mouseover = true
self.last_mouse_idx = idx self.last_mouse_idx = idx
elseif not panel:getMousePos(gui.ViewRect{rect=panel.frame_rect}) end
and self.mouseover then if self:getMouseFramePos() then
self.mouseover = true
elseif self.mouseover then
-- once the mouse has entered the list area, leaving the frame should -- once the mouse has entered the list area, leaving the frame should
-- close the menu screen -- close the menu screen
self:dismiss() self.parent_view:dismiss()
end end
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 return _ENV

@ -43,7 +43,12 @@ end
local function triggered_screen_has_lock() local function triggered_screen_has_lock()
if not trigger_lock_holder_screen then return false end 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) return register_trigger_lock_screen(nil, nil)
end end
@ -429,9 +434,8 @@ local function _update_viewscreen_widgets(vs_name, vs, now_ms)
return now_ms return now_ms
end end
-- not subject to trigger lock since these widgets are already filtered by
-- viewscreen
function update_viewscreen_widgets(vs_name, vs) 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) local now_ms = _update_viewscreen_widgets(vs_name, vs, nil)
_update_viewscreen_widgets('all', vs, now_ms) _update_viewscreen_widgets('all', vs, now_ms)
end end