pull the useful bits out of MenuOverlay

develop
Myk Taylor 2023-01-13 17:05:23 -08:00
parent 4f88d27e08
commit e450af74aa
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
1 changed files with 35 additions and 105 deletions

@ -286,6 +286,19 @@ function get_hotkey_target(key)
end end
end end
function getMapKey(keys)
for code in pairs(keys) do
if MOVEMENT_KEYS[code] or HOTKEY_KEYS[code]
or code == '_MOUSE_M_DOWN' or code == '_MOUSE_M'
or code == 'ZOOM_OUT' or code == 'ZOOM_IN' then
if not HOTKEY_KEYS[code] or get_hotkey_target(code) then
return true
end
return code
end
end
end
function Viewport:scrollByKey(key) function Viewport:scrollByKey(key)
local dx, dy, dz = get_movement_delta(key, 10, 20) local dx, dy, dz = get_movement_delta(key, 10, 20)
if dx then if dx then
@ -339,13 +352,9 @@ function DwarfOverlay:selectBuilding(building,cursor,viewport,gap)
end end
function DwarfOverlay:propagateMoveKeys(keys) function DwarfOverlay:propagateMoveKeys(keys)
for code,_ in pairs(keys) do local map_key = getMapKey(keys)
if MOVEMENT_KEYS[code] or HOTKEY_KEYS[code] then if map_key then
if not HOTKEY_KEYS[code] or get_hotkey_target(code) then self:sendInputToParent(map_key)
self:sendInputToParent(code)
end
return code
end
end end
end end
@ -414,124 +423,45 @@ function DwarfOverlay:onAboutToShow(parent)
end end
end end
MenuOverlay = defclass(MenuOverlay, DwarfOverlay)
MenuOverlay.ATTRS {
frame_inset = 0,
frame_background = gui.CLEAR_PEN,
-- if sidebar_mode is set, we will enter the specified sidebar mode on show
-- and restore the previous sidebar mode on dismiss. otherwise it is up to
-- the caller to ensure we are in a sidebar mode where the menu is visible.
sidebar_mode = DEFAULT_NIL,
}
function MenuOverlay:init()
if not dfhack.isMapLoaded() then
-- sidebar menus are only valid when a fort map is loaded
error('A fortress map must be loaded.')
end
if self.sidebar_mode then
self.saved_sidebar_mode = df.global.plotinfo.main.mode
-- what mode should we restore when this window is dismissed? ideally, we'd
-- restore the mode that the user has set, but we should fall back to
-- restoring the default mode if either of the following conditions are
-- true:
-- 1) enterSidebarMode doesn't support getting back into the current mode
-- 2) a dfhack viewscreen is currently visible. in this case, we can't trust
-- that the current sidebar mode was set by the user. it could just be a
-- MenuOverlay subclass that is currently being shown that has set the
-- sidebar mode for its own purposes.
if not SIDEBAR_MODE_KEYS[self.saved_sidebar_mode]
or dfhack.gui.getCurFocus(true):find('^dfhack/') then
self.saved_sidebar_mode = df.ui_sidebar_mode.Default
end
enterSidebarMode(self.sidebar_mode)
end
end
function MenuOverlay:computeFrame(parent_rect)
return self.df_layout.menu, gui.inset_frame(self.df_layout.menu, self.frame_inset)
end
function MenuOverlay:onAboutToShow(parent)
self:updateLayout()
if not self.df_layout.menu then
error("The menu panel of dwarfmode is not visible")
end
end
function MenuOverlay:onDismiss()
if self.saved_sidebar_mode then
enterSidebarMode(self.saved_sidebar_mode)
end
end
function MenuOverlay:render(dc)
self:renderParent()
local menu = self.df_layout.menu
if menu then
-- Paint signature on the frame.
dscreen.paintString(
{fg=COLOR_BLACK,bg=COLOR_DARKGREY},
menu.x1+1, menu.y2+1, "DFHack"
)
if self.frame_background then
dc:fill(menu, self.frame_background)
end
MenuOverlay.super.render(self, dc)
end
end
-- Framework for managing rendering over the map area. This function is intended -- Framework for managing rendering over the map area. This function is intended
-- to be called from a subclass's onRenderBody() function. -- to be called from a window's onRenderFrame() function.
-- --
-- get_overlay_char_fn takes a coordinate position and an is_cursor boolean and -- get_overlay_pen_fn takes a coordinate position and an is_cursor boolean and
-- returns the char to render at that position and, optionally, the foreground -- returns the pen (and optional char and tile) to render at that position. If
-- and background colors to use to draw the char. If nothing should be rendered -- nothing should be rendered at that position, the function should return nil.
-- at that position, the function should return nil. If no foreground color is
-- specified, it defaults to COLOR_GREEN. If no background color is specified,
-- it defaults to COLOR_BLACK.
-- --
-- bounds_rect has elements {x1, x2, y1, y2} in global map coordinates (not -- bounds_rect has elements {x1, x2, y1, y2} in global map coordinates (not
-- screen coordinates). The rect is intersected with the visible map viewport to -- screen coordinates). The rect is intersected with the visible map viewport to
-- get the range over which get_overlay_char_fn is called. If bounds_rect is not -- get the range over which get_overlay_char_fn is called. If bounds_rect is not
-- specified, the entire viewport is scanned. -- specified, the entire viewport is scanned.
-- --
-- example call from a subclass: -- example call:
-- function MyMenuOverlaySubclass:onRenderBody() -- function MyMapOverlay:onRenderFrame(dc, rect)
-- local function get_overlay_char(pos) -- local function get_overlay_pen(pos)
-- return safe_index(self.overlay_chars, pos.z, pos.y, pos.x), COLOR_RED -- if safe_index(self.overlay_map, pos.z, pos.y, pos.x) then
-- return COLOR_GREEN, 'X', dfhack.screen.findGraphicsTile('CURSORS', 4, 3)
-- end
-- end -- end
-- self:renderMapOverlay(get_overlay_char, self.overlay_bounds) -- guidm.renderMapOverlay(get_overlay_pen, self.overlay_bounds)
-- end -- end
function MenuOverlay:renderMapOverlay(get_overlay_char_fn, bounds_rect) function renderMapOverlay(get_overlay_pen_fn, bounds_rect)
local vp = self:getViewport() local vp = Viewport.get()
local rect = gui.ViewRect{rect=vp, local rect = gui.ViewRect{rect=vp,
clip_view=bounds_rect and gui.ViewRect{rect=bounds_rect} or nil} clip_view=bounds_rect and gui.ViewRect{rect=bounds_rect} or nil}
-- nothing to do if the viewport is completely separate from the bounds_rect -- nothing to do if the viewport is completely disjoint from the bounds_rect
if rect:isDefunct() then return end if rect:isDefunct() then return end
local dc = gui.Painter.new(self.df_layout.map)
local z = df.global.window_z local z = df.global.window_z
local cursor = getCursorPos() local cursor = getCursorPos()
for y=rect.clip_y1,rect.clip_y2 do for y=rect.clip_y1,rect.clip_y2 do
for x=rect.clip_x1,rect.clip_x2 do for x=rect.clip_x1,rect.clip_x2 do
local pos = xyz2pos(x, y, z) local pos = xyz2pos(x, y, z)
local overlay_char, fg_color, bg_color = get_overlay_char_fn( local overlay_pen, char, tile = get_overlay_pen_fn(pos, same_xy(cursor, pos))
pos, same_xy(cursor, pos)) if overlay_pen then
if not overlay_char then goto continue end local stile = vp:tileToScreen(pos)
local stile = vp:tileToScreen(pos) dscreen.paintTile(overlay_pen, stile.x, stile.y, char, tile, true)
dc:map(true):seek(stile.x, stile.y): end
pen(fg_color or COLOR_GREEN, bg_color or COLOR_BLACK):
char(overlay_char):map(false)
::continue::
end end
end end
end end