|
|
@ -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
|
|
|
|