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
7373end
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
96109end
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
105131ToolbarDemo = defclass (ToolbarDemo , widgets .Panel )
106132ToolbarDemo .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
117139function 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 }
123145end
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
144176end
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+
146223local 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
152233local 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
158243local 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
164253local 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 )
200294end
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 = {
262356local 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
271365end
272366
0 commit comments