Skip to content

Commit ae11d39

Browse files
committed
# This is a combination of 2 commits.
# This is the 1st commit message: adapt to gui.dflayout overhaul
1 parent eef4fc5 commit ae11d39

File tree

2 files changed

+202
-117
lines changed

2 files changed

+202
-117
lines changed

devel/dflayout.lua

+185-91
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ end
5757
--
5858
-- Note: The returned function does not return a separate body rect; subviews
5959
-- will be able to overwrite the normal UI-drawn frame!
60-
---@param toolbar DFLayout.Toolbar
60+
---@param el DFLayout.DynamicUIElement
6161
---@param dy_fn fun(): integer
6262
---@return function
63-
local function get_computeFrame_fn(toolbar, dy_fn)
63+
local function get_computeFrame_fn(el, dy_fn)
6464
return function(self, parent_rect)
6565
local ir = gui.get_interface_rect()
66-
local frame = toolbar.frame(ir)
66+
local frame = el.frame_fn(ir)
6767
return gui.mkdims_wh(
6868
ir.x1 + frame.l,
6969
ir.y1 + frame.t + dy_fn(),
@@ -72,93 +72,182 @@ local function get_computeFrame_fn(toolbar, dy_fn)
7272
end
7373
end
7474

75-
---@param buttons DFLayout.Toolbar.NamedButtons
76-
local function buttons_string(buttons)
77-
local sorted = {}
78-
for _, button in pairs(buttons) do
79-
utils.insert_sorted(sorted, button, 'offset')
75+
---@param buttons DFLayout.Toolbar.Layout
76+
local function buttons_tokens(buttons)
77+
local sorted_buttons = {}
78+
for button_name, button in pairs(buttons) do
79+
utils.insert_sorted(sorted_buttons, {
80+
name = button_name,
81+
offset = button.offset,
82+
width = button.width,
83+
}, 'offset')
8084
end
81-
-- For a one-column button, use | to indicate the button's position.
82-
-- For wider buttons, use shapes like /\ or /--\ to illustrate the
83-
-- button's position and width.
84-
local str = ''
85-
for i, o in ipairs(sorted) do
86-
if o.offset > #str then
87-
str = str .. (' '):rep(o.offset - #str)
88-
end
89-
if o.width == 1 then
90-
str = str .. '|'
91-
elseif o.width > 1 then
92-
str = str .. '/' .. ('-'):rep(o.width - 2) .. '\\'
85+
local offset = 0
86+
local sorted_button_names = {}
87+
local tokens_by_name = {}
88+
for _, button_info in ipairs(sorted_buttons) do
89+
table.insert(sorted_button_names, button_info.name)
90+
local token = { gap = button_info.offset - offset, width = button_info.width }
91+
if button_info.width == 1 then
92+
-- For a one-column button, use | to indicate the button's position.
93+
token.text = '|'
94+
elseif button_info.width > 1 then
95+
-- For wider buttons, use shapes like /\ or /--\ to illustrate the
96+
-- button's position and width.
97+
token.text = '/' .. ('-'):rep(button_info.width - 2) .. '\\'
9398
end
99+
offset = button_info.offset + button_info.width
100+
tokens_by_name[button_info.name] = token
94101
end
95-
return str
102+
return sorted_button_names, tokens_by_name
103+
end
104+
105+
local normal_frame_style = function(...)
106+
local style = gui.FRAME_THIN(...)
107+
style.signature_pen = false
108+
return style
96109
end
97110

111+
local hover_frame_style = function(...)
112+
local style = gui.FRAME_BOLD(...)
113+
style.signature_pen = false
114+
return style
115+
end
116+
117+
---@class ToolbarDemo.ToolbarInfo
118+
---@field el DFLayout.DynamicUIElement
119+
---@field buttons DFLayout.Toolbar.Layout
120+
---@field button_els table<string, DFLayout.DynamicUIElement>
121+
---@field demo_dy fun(): integer
122+
98123
---@class ToolbarDemo.attrs: widgets.Panel.attrs
99124
---@class ToolbarDemo.attrs.partial: widgets.Panel.attrs.partial
100-
---@class ToolbarDemo.initTable: ToolbarDemo.attrs.partial, { toolbar?: DFLayout.Toolbar, toolbar_dy?: fun(): integer }
125+
---@field toolbar_info? ToolbarDemo.ToolbarInfo
126+
---@class ToolbarDemo.initTable: ToolbarDemo.attrs.partial
101127
---@class ToolbarDemo: widgets.Panel
102128
---@field super widgets.Panel
103129
---@field ATTRS ToolbarDemo.attrs|fun(attributes: ToolbarDemo.attrs.partial)
104130
---@overload fun(init_table: ToolbarDemo.initTable): self
105131
ToolbarDemo = defclass(ToolbarDemo, widgets.Panel)
106132
ToolbarDemo.ATTRS{
107-
frame_style = function(...)
108-
local style = gui.FRAME_THIN(...)
109-
style.signature_pen = false
110-
return style
111-
end,
133+
frame_style = normal_frame_style,
112134
visible = fort_toolbars_visible,
113135
frame_background = { ch = 32, bg = COLOR_BLACK },
114136
}
115137

116138
---@param args ToolbarDemo.initTable
117139
function ToolbarDemo:init(args)
118140
self.label = widgets.Label{ frame = { l = 0 } }
119-
if args.toolbar and args.toolbar_dy then
120-
self:update_to_toolbar(args.toolbar, args.toolbar_dy)
141+
if args.toolbar_info then
142+
self:update_to_toolbar(args.toolbar_info)
121143
end
122144
self:addviews{ self.label }
123145
end
124146

125-
---@param toolbar DFLayout.Toolbar
126-
---@param dy fun(): integer
127-
---@return unknown
128-
function ToolbarDemo:update_to_toolbar(toolbar, dy)
129-
-- set button representation string
130-
local text = buttons_string(toolbar.buttons)
131-
local l_inset = 0
132-
if text:sub(1, 1) == ' ' then
133-
-- don't overwrite the left border edge with a plain space
134-
l_inset = 1
135-
text = text:sub(2)
147+
---@param toolbar_info ToolbarDemo.ToolbarInfo
148+
---@return ToolbarDemo
149+
function ToolbarDemo:update_to_toolbar(toolbar_info)
150+
local order, named_tokens = buttons_tokens(toolbar_info.buttons)
151+
function set_button_text(lit_button_name)
152+
local lit = false
153+
local tokens = {}
154+
for _, name in ipairs(order) do
155+
local token = copyall(named_tokens[name])
156+
if name == lit_button_name then
157+
lit = true
158+
token.pen = { fg = COLOR_BLACK, bg = COLOR_BLUE }
159+
end
160+
table.insert(tokens, token)
161+
end
162+
self.label:setText(tokens)
163+
return lit
136164
end
137-
self.label.frame.l = l_inset
138-
self.label:setText(text)
165+
166+
set_button_text()
139167

140168
-- track actual toolbar, but with a y offset
141-
self.computeFrame = get_computeFrame_fn(toolbar, dy)
169+
self.computeFrame = get_computeFrame_fn(toolbar_info.el, toolbar_info.demo_dy)
170+
171+
self.toolbar_el = toolbar_info.el
172+
self.button_els = toolbar_info.button_els
173+
self.set_button_text = set_button_text
142174

143175
return self
144176
end
145177

178+
-- capture computed locations of toolbar and buttons
179+
function ToolbarDemo:postUpdateLayout()
180+
local ir = gui.get_interface_rect()
181+
local function vr(el)
182+
local f = el.frame_fn(ir)
183+
return gui.ViewRect{ rect = gui.mkdims_wh(ir.x1 + f.l, ir.y1 + f.t, f.w, f.h) }
184+
end
185+
if self.toolbar_el then
186+
self.toolbar_vr = vr(self.toolbar_el)
187+
end
188+
if self.button_els then
189+
local vrs = {}
190+
for name, el in pairs(self.button_els) do
191+
vrs[name] = vr(el)
192+
end
193+
self.toolbar_button_vrs = vrs
194+
end
195+
end
196+
197+
function ToolbarDemo:render(...)
198+
if self.toolbar_vr then
199+
if self:getMousePos(self.toolbar_vr) then
200+
self.frame_style = hover_frame_style
201+
if self.toolbar_button_vrs then
202+
local lit = false
203+
for button_name, button_vr in pairs(self.toolbar_button_vrs) do
204+
if self:getMousePos(button_vr) then
205+
if self.set_button_text(button_name) then
206+
lit = true
207+
break
208+
end
209+
end
210+
end
211+
if not lit then
212+
self.set_button_text()
213+
end
214+
end
215+
else
216+
self.frame_style = normal_frame_style
217+
self.set_button_text()
218+
end
219+
end
220+
return ToolbarDemo.super.render(self, ...)
221+
end
222+
146223
local left_toolbar_demo = ToolbarDemo{
147224
frame_title = 'left toolbar',
148-
toolbar = layout.fort.toolbars.left,
149-
toolbar_dy = primary_toolbar_dy,
225+
toolbar_info = {
226+
el = layout.elements.fort.toolbars.left,
227+
buttons = layout.element_layouts.fort.toolbars.left.buttons,
228+
button_els = layout.elements.fort.toolbar_buttons.left,
229+
demo_dy = primary_toolbar_dy,
230+
},
150231
}
151232

152233
local center_toolbar_demo = ToolbarDemo{
153234
frame_title = 'center toolbar',
154-
toolbar = layout.fort.toolbars.center,
155-
toolbar_dy = primary_toolbar_dy,
235+
toolbar_info = {
236+
el = layout.elements.fort.toolbars.center,
237+
buttons = layout.element_layouts.fort.toolbars.center.buttons,
238+
button_els = layout.elements.fort.toolbar_buttons.center,
239+
demo_dy = primary_toolbar_dy,
240+
},
156241
}
157242

158243
local right_toolbar_demo = ToolbarDemo{
159244
frame_title = 'right toolbar',
160-
toolbar = layout.fort.toolbars.right,
161-
toolbar_dy = primary_toolbar_dy,
245+
toolbar_info = {
246+
el = layout.elements.fort.toolbars.right,
247+
buttons = layout.element_layouts.fort.toolbars.right.buttons,
248+
button_els = layout.elements.fort.toolbar_buttons.right,
249+
demo_dy = primary_toolbar_dy,
250+
}
162251
}
163252

164253
local secondary_toolbar_demo = ToolbarDemo{
@@ -187,7 +276,12 @@ local function update_fort_toolbars(secondary)
187276
local function dy()
188277
return -layout.SECONDARY_TOOLBAR_HEIGHT
189278
end
190-
secondary_toolbar_demo:update_to_toolbar(layout.fort.secondary_toolbars[secondary], dy)
279+
secondary_toolbar_demo:update_to_toolbar{
280+
el = layout.elements.fort.secondary_toolbars[secondary],
281+
buttons = layout.element_layouts.fort.secondary_toolbars[secondary].buttons,
282+
button_els = layout.elements.fort.secondary_toolbar_buttons[secondary],
283+
demo_dy = dy
284+
}
191285
updateLayout(secondary_toolbar_demo)
192286
secondary_visible = true
193287
else
@@ -199,56 +293,56 @@ local function update_fort_toolbars(secondary)
199293
updateLayout(center_toolbar_demo)
200294
end
201295

202-
local tool_from_designation = {
296+
local secondary_toolbar_from_designation = {
203297
-- df.main_designation_type.NONE -- not a tool
204-
[df.main_designation_type.DIG_DIG] = 'dig',
205-
[df.main_designation_type.DIG_REMOVE_STAIRS_RAMPS] = 'dig',
206-
[df.main_designation_type.DIG_STAIR_UP] = 'dig',
207-
[df.main_designation_type.DIG_STAIR_UPDOWN] = 'dig',
208-
[df.main_designation_type.DIG_STAIR_DOWN] = 'dig',
209-
[df.main_designation_type.DIG_RAMP] = 'dig',
210-
[df.main_designation_type.DIG_CHANNEL] = 'dig',
211-
[df.main_designation_type.CHOP] = 'chop',
212-
[df.main_designation_type.GATHER] = 'gather',
213-
[df.main_designation_type.SMOOTH] = 'smooth',
214-
[df.main_designation_type.TRACK] = 'smooth',
215-
[df.main_designation_type.ENGRAVE] = 'smooth',
216-
[df.main_designation_type.FORTIFY] = 'smooth',
298+
[df.main_designation_type.DIG_DIG] = 'DIG',
299+
[df.main_designation_type.DIG_REMOVE_STAIRS_RAMPS] = 'DIG',
300+
[df.main_designation_type.DIG_STAIR_UP] = 'DIG',
301+
[df.main_designation_type.DIG_STAIR_UPDOWN] = 'DIG',
302+
[df.main_designation_type.DIG_STAIR_DOWN] = 'DIG',
303+
[df.main_designation_type.DIG_RAMP] = 'DIG',
304+
[df.main_designation_type.DIG_CHANNEL] = 'DIG',
305+
[df.main_designation_type.CHOP] = 'CHOP',
306+
[df.main_designation_type.GATHER] = 'GATHER',
307+
[df.main_designation_type.SMOOTH] = 'SMOOTH',
308+
[df.main_designation_type.TRACK] = 'SMOOTH',
309+
[df.main_designation_type.ENGRAVE] = 'SMOOTH',
310+
[df.main_designation_type.FORTIFY] = 'SMOOTH',
217311
-- df.main_designation_type.REMOVE_CONSTRUCTION -- not used?
218-
[df.main_designation_type.CLAIM] = 'mass_designation',
219-
[df.main_designation_type.UNCLAIM] = 'mass_designation',
220-
[df.main_designation_type.MELT] = 'mass_designation',
221-
[df.main_designation_type.NO_MELT] = 'mass_designation',
222-
[df.main_designation_type.DUMP] = 'mass_designation',
223-
[df.main_designation_type.NO_DUMP] = 'mass_designation',
224-
[df.main_designation_type.HIDE] = 'mass_designation',
225-
[df.main_designation_type.NO_HIDE] = 'mass_designation',
312+
[df.main_designation_type.CLAIM] = 'ITEM_BUILDING',
313+
[df.main_designation_type.UNCLAIM] = 'ITEM_BUILDING',
314+
[df.main_designation_type.MELT] = 'ITEM_BUILDING',
315+
[df.main_designation_type.NO_MELT] = 'ITEM_BUILDING',
316+
[df.main_designation_type.DUMP] = 'ITEM_BUILDING',
317+
[df.main_designation_type.NO_DUMP] = 'ITEM_BUILDING',
318+
[df.main_designation_type.HIDE] = 'ITEM_BUILDING',
319+
[df.main_designation_type.NO_HIDE] = 'ITEM_BUILDING',
226320
-- df.main_designation_type.TOGGLE_ENGRAVING -- not used?
227-
[df.main_designation_type.DIG_FROM_MARKER] = 'dig',
228-
[df.main_designation_type.DIG_TO_MARKER] = 'dig',
229-
[df.main_designation_type.CHOP_FROM_MARKER] = 'chop',
230-
[df.main_designation_type.CHOP_TO_MARKER] = 'chop',
231-
[df.main_designation_type.GATHER_FROM_MARKER] = 'gather',
232-
[df.main_designation_type.GATHER_TO_MARKER] = 'gather',
233-
[df.main_designation_type.SMOOTH_FROM_MARKER] = 'smooth',
234-
[df.main_designation_type.SMOOTH_TO_MARKER] = 'smooth',
235-
[df.main_designation_type.DESIGNATE_TRAFFIC_HIGH] = 'traffic',
236-
[df.main_designation_type.DESIGNATE_TRAFFIC_NORMAL] = 'traffic',
237-
[df.main_designation_type.DESIGNATE_TRAFFIC_LOW] = 'traffic',
238-
[df.main_designation_type.DESIGNATE_TRAFFIC_RESTRICTED] = 'traffic',
239-
[df.main_designation_type.ERASE] = 'erase',
321+
[df.main_designation_type.DIG_FROM_MARKER] = 'DIG',
322+
[df.main_designation_type.DIG_TO_MARKER] = 'DIG',
323+
[df.main_designation_type.CHOP_FROM_MARKER] = 'CHOP',
324+
[df.main_designation_type.CHOP_TO_MARKER] = 'CHOP',
325+
[df.main_designation_type.GATHER_FROM_MARKER] = 'GATHER',
326+
[df.main_designation_type.GATHER_TO_MARKER] = 'GATHER',
327+
[df.main_designation_type.SMOOTH_FROM_MARKER] = 'SMOOTH',
328+
[df.main_designation_type.SMOOTH_TO_MARKER] = 'SMOOTH',
329+
[df.main_designation_type.DESIGNATE_TRAFFIC_HIGH] = 'TRAFFIC',
330+
[df.main_designation_type.DESIGNATE_TRAFFIC_NORMAL] = 'TRAFFIC',
331+
[df.main_designation_type.DESIGNATE_TRAFFIC_LOW] = 'TRAFFIC',
332+
[df.main_designation_type.DESIGNATE_TRAFFIC_RESTRICTED] = 'TRAFFIC',
333+
[df.main_designation_type.ERASE] = 'ERASE',
240334
}
241-
local tool_from_bottom = {
335+
local secondary_toolbar_from_bottom = {
242336
-- df.main_bottom_mode_type.NONE
243337
-- df.main_bottom_mode_type.BUILDING
244338
-- df.main_bottom_mode_type.BUILDING_PLACEMENT
245339
-- df.main_bottom_mode_type.BUILDING_PICK_MATERIALS
246340
-- df.main_bottom_mode_type.ZONE
247341
-- df.main_bottom_mode_type.ZONE_PAINT
248-
[df.main_bottom_mode_type.STOCKPILE] = 'stockpile',
249-
[df.main_bottom_mode_type.STOCKPILE_PAINT] = 'stockpile_paint',
342+
[df.main_bottom_mode_type.STOCKPILE] = 'MAIN_STOCKPILE_MODE',
343+
[df.main_bottom_mode_type.STOCKPILE_PAINT] = 'STOCKPILE_NEW',
250344
-- df.main_bottom_mode_type.BURROW
251-
[df.main_bottom_mode_type.BURROW_PAINT] = 'burrow_paint'
345+
[df.main_bottom_mode_type.BURROW_PAINT] = 'Add new burrow',
252346
-- df.main_bottom_mode_type.HAULING
253347
-- df.main_bottom_mode_type.ARENA_UNIT
254348
-- df.main_bottom_mode_type.ARENA_TREE
@@ -262,11 +356,11 @@ local tool_from_bottom = {
262356
local function active_secondary()
263357
local designation = df.global.game.main_interface.main_designation_selected
264358
if designation ~= df.main_designation_type.NONE then
265-
return tool_from_designation[designation]
359+
return secondary_toolbar_from_designation[designation]
266360
end
267361
local bottom = df.global.game.main_interface.bottom_mode_selected
268362
if bottom ~= df.main_bottom_mode_type.NONE then
269-
return tool_from_bottom[bottom]
363+
return secondary_toolbar_from_bottom[bottom]
270364
end
271365
end
272366

0 commit comments

Comments
 (0)