Skip to content

Commit

Permalink
Merge pull request #1201 from myk002/myk_interface_max
Browse files Browse the repository at this point in the history
behave properly on scaled interface widths
  • Loading branch information
myk002 authored Jun 21, 2024
2 parents 834b9e2 + 13ad4a9 commit d092a30
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 71 deletions.
7 changes: 4 additions & 3 deletions confirm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ ConfirmOverlay.ATTRS{
desc='Detects dangerous actions and prompts with confirmation dialogs.',
default_pos={x=1,y=1},
default_enabled=true,
overlay_only=true, -- not player-repositionable
hotspot=true, -- need to unpause when we're not in target contexts
full_interface=true, -- not player-repositionable
hotspot=true, -- need to reset pause when we're not in target contexts
overlay_onupdate_max_freq_seconds=300,
viewscreens=get_contexts(),
}
Expand All @@ -66,7 +66,8 @@ function ConfirmOverlay:init()
end

function ConfirmOverlay:preUpdateLayout()
self.frame.w, self.frame.h = dfhack.screen.getWindowSize()
local interface_rect = gui.get_interface_rect()
self.frame.w, self.frame.h = interface_rect.width, interface_rect.height
-- reset frames if any of them have been pushed out of position
for id, conf in pairs(specs.REGISTRY) do
if conf.intercept_frame then
Expand Down
2 changes: 1 addition & 1 deletion gui/design.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ DimensionsOverlay.ATTRS{
desc='Adds a tooltip that shows the selected dimensions when drawing boxes.',
default_pos={x=1,y=1},
default_enabled=true,
overlay_only=true, -- not player-repositionable
fullscreen=true, -- not player-repositionable
viewscreens={
'dwarfmode/Designate',
'dwarfmode/Burrow/Paint',
Expand Down
27 changes: 25 additions & 2 deletions gui/gm-editor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,37 @@ function search_relevance(search, candidate)
return ret
end

local RESIZE_MIN = {w=30, h=20}

local function sanitize_frame(frame)
local w, h = dfhack.screen.getWindowSize()
local min = RESIZE_MIN
if frame.t and h - frame.t - (frame.b or 0) < min.h then
frame.t = h - min.h
frame.b = 0
end
if frame.b and h - frame.b - (frame.t or 0) < min.h then
frame.b = h - min.h
frame.t = 0
end
if frame.l and w - frame.l - (frame.r or 0) < min.w then
frame.l = w - min.w
frame.r = 0
end
if frame.r and w - frame.r - (frame.l or 0) < min.w then
frame.r = w - min.w
frame.l = 0
end
return frame
end

GmEditorUi = defclass(GmEditorUi, widgets.Window)
GmEditorUi.ATTRS{
frame=copyall(config.data.frame or {}),
frame=sanitize_frame(copyall(config.data.frame or {})),
frame_title="GameMaster's editor",
frame_inset=0,
resizable=true,
resize_min={w=30, h=20},
resize_min=RESIZE_MIN,
read_only=(config.data.read_only or false)
}

Expand Down
18 changes: 18 additions & 0 deletions gui/launcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,24 @@ function LauncherUI:init()
new_frame[k] = 0
end
end
local w, h = dfhack.screen.getWindowSize()
local min = MainPanel.ATTRS.resize_min
if new_frame.t and h - new_frame.t - (new_frame.b or 0) < min.h then
new_frame.t = h - min.h
new_frame.b = 0
end
if new_frame.b and h - new_frame.b - (new_frame.t or 0) < min.h then
new_frame.b = h - min.h
new_frame.t = 0
end
if new_frame.l and w - new_frame.l - (new_frame.r or 0) < min.w then
new_frame.l = w - min.w
new_frame.r = 0
end
if new_frame.r and w - new_frame.r - (new_frame.l or 0) < min.w then
new_frame.r = w - min.w
new_frame.l = 0
end
end
end
main_panel.frame = new_frame
Expand Down
124 changes: 80 additions & 44 deletions gui/overlay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,12 @@ DraggablePanel.ATTRS{
draggable=true,
drag_anchors={frame=true, body=true},
drag_bound='body',
widget=DEFAULT_NIL,
}

function DraggablePanel:onInput(keys)
if keys._MOUSE_L then
local rect = self.frame_rect
local x,y = self:getMousePos(gui.ViewRect{rect=rect})
if x then
self.on_click()
end
if keys._MOUSE_L and self:getMousePos() then
self.on_click()
end
return DraggablePanel.super.onInput(self, keys)
end
Expand All @@ -72,16 +69,16 @@ function DraggablePanel:postUpdateLayout()
local frame = self.frame
local matcher = {t=not not frame.t, b=not not frame.b,
l=not not frame.l, r=not not frame.r}
local parent_rect, frame_rect = self.frame_parent_rect, self.frame_rect
if frame_rect.y1 <= parent_rect.y1 then
frame.t, frame.b = frame_rect.y1-parent_rect.y1, nil
elseif frame_rect.y2 >= parent_rect.y2 then
frame.t, frame.b = nil, parent_rect.y2-frame_rect.y2
local parent_rect, frame_rect = self.widget.frame_parent_rect, self.frame_body
if frame_rect.y1-1 <= parent_rect.y1 then
frame.t, frame.b = frame_rect.y1-parent_rect.y1-1, nil
elseif frame_rect.y2+1 >= parent_rect.y2 then
frame.t, frame.b = nil, parent_rect.y2-frame_rect.y2-1
end
if frame_rect.x1 <= parent_rect.x1 then
frame.l, frame.r = frame_rect.x1-parent_rect.x1, nil
elseif frame_rect.x2 >= parent_rect.x2 then
frame.l, frame.r = nil, parent_rect.x2-frame_rect.x2
if frame_rect.x1-1 <= parent_rect.x1 then
frame.l, frame.r = frame_rect.x1-parent_rect.x1-1, nil
elseif frame_rect.x2+1 >= parent_rect.x2 then
frame.l, frame.r = nil, parent_rect.x2-frame_rect.x2-1
end
self.frame_style = make_highlight_frame_style(self.frame)
if not not frame.t ~= matcher.t or not not frame.b ~= matcher.b
Expand All @@ -92,7 +89,7 @@ function DraggablePanel:postUpdateLayout()
end

function DraggablePanel:onRenderFrame(dc, rect)
if self:getMousePos(gui.ViewRect{rect=self.frame_rect}) then
if self:getMousePos() then
self.frame_background = to_pen{
ch=32, fg=COLOR_LIGHTGREEN, bg=COLOR_LIGHTGREEN}
else
Expand All @@ -105,13 +102,14 @@ end
-- OverlayConfig --
-------------------

OverlayConfig = defclass(OverlayConfig, gui.Screen)
OverlayConfig = defclass(OverlayConfig, gui.Screen) -- not a ZScreen since we want to freeze the underlying UI

function OverlayConfig:init()
-- prevent hotspot widgets from reacting
overlay.register_trigger_lock_screen(self)

local contexts = dfhack.gui.getFocusStrings(dfhack.gui.getDFViewscreen(true))
local interface_width_pct = df.global.init.display.max_interface_percentage

local main_panel = widgets.Window{
frame={w=DIALOG_WIDTH, h=LIST_HEIGHT+15},
Expand All @@ -124,19 +122,25 @@ function OverlayConfig:init()
frame={t=0, l=0},
text={
'Current contexts: ',
{text=table.concat(contexts, ', '), pen=COLOR_CYAN}
{text=table.concat(contexts, ', '), pen=COLOR_CYAN},
}},
widgets.Label{
frame={t=2, l=0},
text={
'Interface width percent: ',
{text=interface_width_pct, pen=COLOR_CYAN},
}},
widgets.CycleHotkeyLabel{
view_id='filter',
frame={t=2, l=0},
frame={t=4, l=0},
key='CUSTOM_CTRL_O',
label='Showing:',
label='Showing',
options={{label='overlays for the current contexts', value='cur'},
{label='all overlays', value='all'}},
on_change=self:callback('refresh_list')},
widgets.FilteredList{
view_id='list',
frame={t=4, b=7},
frame={t=6, b=7},
on_select=self:callback('highlight_selected'),
},
widgets.HotkeyLabel{
Expand All @@ -156,11 +160,25 @@ function OverlayConfig:init()
widgets.WrappedLabel{
frame={b=0, l=0},
scroll_keys={},
text_to_wrap='When repositioning a widget, touch an edge of the'..
' screen to anchor the widget to that edge.',
text_to_wrap='When repositioning a widget, touch a boundary edge'..
' to anchor the widget to that edge.',
},
}

self:addviews{
widgets.Divider{
view_id='left_border',
frame={l=0, w=1},
frame_style=gui.FRAME_THIN,
},
widgets.Divider{
view_id='right_border',
frame={r=0, w=1},
frame_style=gui.FRAME_THIN,
},
main_panel,
}
self:addviews{main_panel}

self:refresh_list()
end

Expand All @@ -184,7 +202,11 @@ function OverlayConfig:refresh_list(filter)
for _,name in ipairs(state.index) do
local db_entry = state.db[name]
local widget = db_entry.widget
if widget.overlay_only then goto continue end
if widget.fullscreen or widget.full_interface or
widget.frame.w == 0 or widget.frame.h == 0
then
goto continue
end
if (not widget.hotspot or #widget.viewscreens > 0) and filter ~= 'all' then
for _,vs in ipairs(overlay.normalize_list(widget.viewscreens)) do
if dfhack.gui.matchFocusString(overlay.simplify_viewscreen_name(vs), scr) then
Expand All @@ -194,20 +216,23 @@ function OverlayConfig:refresh_list(filter)
goto continue
end
::matched::
local panel = nil
panel = DraggablePanel{
frame=make_highlight_frame(widget.frame),
frame_style=SHADOW_FRAME,
on_click=make_on_click_fn(#choices+1),
name=name}
local panel = DraggablePanel{
frame=make_highlight_frame(widget.frame),
frame_style=SHADOW_FRAME,
on_click=make_on_click_fn(#choices+1),
name=name,
widget=widget,
}
panel.on_drag_end = function(success)
if (success) then
local frame = panel.frame
local posx = frame.l and tostring(frame.l+2)
or tostring(-(frame.r+2))
local posy = frame.t and tostring(frame.t+2)
or tostring(-(frame.b+2))
overlay.overlay_command({'position', name, posx, posy},true)
local frame_rect = panel.frame_rect
local frame_parent_rect = panel.frame_parent_rect
local posx = frame.l and tostring(frame_rect.x1+2)
or tostring(frame_rect.x2-frame_parent_rect.width-1)
local posy = frame.t and tostring(frame_rect.y1+2)
or tostring(frame_rect.y2-frame_parent_rect.height-1)
overlay.overlay_command({'position', name, posx, posy}, true)
end
self.reposition_panel = nil
end
Expand All @@ -222,7 +247,7 @@ function OverlayConfig:refresh_list(filter)
end})
table.insert(choices,
{text=tokens, enabled=cfg.enabled, name=name, panel=panel,
search_key=name})
widget=widget, search_key=name})
::continue::
end
local old_filter = list:getFilter()
Expand Down Expand Up @@ -259,21 +284,31 @@ function OverlayConfig:reposition(_, obj)
end

function OverlayConfig:reset()
local idx,obj = self.subviews.list:getSelected()
local _,obj = self.subviews.list:getSelected()
if not obj or not obj.panel then return end
overlay.overlay_command({'position', obj.panel.name, 'default'}, true)
self:refresh_list(self.subviews.filter:getOptionValue())
self:updateLayout()
end

function OverlayConfig:onDismiss()
view = nil
end

function OverlayConfig:preUpdateLayout(parent_rect)
local interface_rect = gui.get_interface_rect()
local left, right = self.subviews.left_border, self.subviews.right_border
left.frame.l = interface_rect.x1 - 1
left.visible = left.frame.l >= 0
right.frame.r = nil
right.frame.l = interface_rect.x2 + 1
right.visible = right.frame.l < parent_rect.width
end

function OverlayConfig:postUpdateLayout()
local rect = gui.ViewRect{rect=gui.get_interface_rect()}
for _,choice in ipairs(self.subviews.list:getChoices()) do
if choice.panel then
choice.panel:updateLayout(self.frame_parent_rect)
end
choice.panel:updateLayout(rect)
end
end

Expand Down Expand Up @@ -302,17 +337,18 @@ function OverlayConfig:onInput(keys)
end
end

function OverlayConfig:onRenderFrame(dc, rect)
function OverlayConfig:onRenderFrame()
self:renderParent()
local interface_area_painter = gui.Painter.new(gui.ViewRect{rect=gui.get_interface_rect()})
for _,choice in ipairs(self.subviews.list:getVisibleChoices()) do
local panel = choice.panel
if panel and panel ~= self.selected_panel then
panel:render(dc)
panel:render(interface_area_painter)
end
end
if self.selected_panel then
self.render_selected_panel = function()
self.selected_panel:render(dc)
self.selected_panel:render(interface_area_painter)
end
else
self.render_selected_panel = nil
Expand Down
2 changes: 1 addition & 1 deletion internal/advtools/convo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ end
AdvRumorsOverlay = defclass(AdvRumorsOverlay, overlay.OverlayWidget)
AdvRumorsOverlay.ATTRS{
desc='Adds keywords to conversation entries.',
overlay_only=true,
default_enabled=true,
viewscreens='dungeonmode/Conversation',
frame={w=0, h=0},
}

function AdvRumorsOverlay:render()
Expand Down
3 changes: 1 addition & 2 deletions internal/caravan/pedestal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,6 @@ PedestalOverlay.ATTRS{
default_enabled=true,
viewscreens='dwarfmode/ViewSheets/BUILDING/DisplayFurniture',
frame={w=23, h=1},
frame_background=gui.CLEAR_PEN,
}

local function is_valid_building()
Expand All @@ -681,7 +680,7 @@ function PedestalOverlay:init()
self:addviews{
widgets.TextButton{
frame={t=0, l=0},
label='DFHack assign items',
label='DFHack assign',
key='CUSTOM_CTRL_T',
visible=is_valid_building,
on_activate=function() AssignItemsModal{}:show() end,
Expand Down
2 changes: 1 addition & 1 deletion internal/confirm/specs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ end

local function trade_agreement_items_any_selected()
local diplomacy = mi.diplomacy
for _, tab in ipairs(diplomacy.environment.meeting.sell_requests.priority) do
for _, tab in ipairs(diplomacy.environment.dipev.sell_requests.priority) do
for _, priority in ipairs(tab) do
if priority ~= 0 then
return true
Expand Down
11 changes: 8 additions & 3 deletions open-legends.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,19 @@ function LegendsManager:init()

self:addviews{
widgets.Panel{
view_id='done_mask',
frame={t=1, r=1, w=9, h=3},
frame=gui.get_interface_frame(),
subviews={
widgets.Panel{
view_id='done_mask',
frame={t=1, r=1, w=9, h=3},
},
},
},
}
end

function LegendsManager:onInput(keys)
if keys.LEAVESCREEN or (keys._MOUSE_L and self.subviews.done_mask:getMousePos()) then
if keys.LEAVESCREEN or keys._MOUSE_R or (keys._MOUSE_L and self.subviews.done_mask:getMousePos()) then
if self.no_autoquit then
self:dismiss()
else
Expand Down
Loading

0 comments on commit d092a30

Please sign in to comment.