add standard HelpButton and ConfigureButton classes

and use them across the overlays that need them
develop
Myk Taylor 2023-10-16 03:27:08 -07:00
parent 50454825fc
commit a651f6461b
No known key found for this signature in database
8 changed files with 149 additions and 75 deletions

@ -75,6 +75,7 @@ Template for new versions:
## Misc Improvements ## Misc Improvements
- `overlay`: allow ``overlay_onupdate_max_freq_seconds`` to be dynamically set to 0 for a burst of high-frequency updates - `overlay`: allow ``overlay_onupdate_max_freq_seconds`` to be dynamically set to 0 for a burst of high-frequency updates
- Help icons added to several complex overlays. clicking the icon runs `gui/launcher` with the help text in the help area
- `orders`: ``recheck`` command now only resets orders that have conditions that can be rechecked - `orders`: ``recheck`` command now only resets orders that have conditions that can be rechecked
- `sort`: added help button for squad assignment search/filter/sort - `sort`: added help button for squad assignment search/filter/sort
- `zone`: animals trained for war or hunting are now labeled as such in animal assignment screens - `zone`: animals trained for war or hunting are now labeled as such in animal assignment screens

@ -5207,6 +5207,27 @@ This is a specialized subclass of CycleHotkeyLabel that has two options:
``On`` (with a value of ``true``) and ``Off`` (with a value of ``false``). The ``On`` (with a value of ``true``) and ``Off`` (with a value of ``false``). The
``On`` option is rendered in green. ``On`` option is rendered in green.
HelpButton class
----------------
A 3x1 tile button with a question mark on it, intended to represent a help
icon. Clicking on the icon will launch `gui/launcher` with a given command
string, showing the help text for that command.
It has the following attributes:
:command: The command to load in `gui/launcher`.
ConfigureButton class
---------------------
A 3x1 tile button with a gear mark on it, intended to represent a configure
icon. Clicking on the icon will run the given callback.
It has the following attributes:
:on_click: The function on run when the icon is clicked.
BannerPanel class BannerPanel class
----------------- -----------------

@ -19,11 +19,11 @@ periodically scan for appropriate items and attach them to the planned
building. Once all items are attached, the construction job will be unsuspended building. Once all items are attached, the construction job will be unsuspended
and a dwarf will come and build the building. If you have the `unsuspend` and a dwarf will come and build the building. If you have the `unsuspend`
overlay enabled (it is enabled by default), then buildingplan-suspended overlay enabled (it is enabled by default), then buildingplan-suspended
buildings will appear with a ``P`` marker on the main map, as opposed to the buildings will be tagged with a clock graphic in graphics mode or a ``P``
usual ``x`` marker for "regular" suspended buildings. If you have marker in ASCII mode, as opposed to the ``x`` marker for "regular" suspended
`suspendmanager` running, then buildings will be left suspended when their buildings. If you have `suspendmanager` running, then buildings will be left
items are all attached and ``suspendmanager`` will unsuspend them for suspended when their items are all attached and ``suspendmanager`` will
construction when it is safe to do so. unsuspend them for construction when it is safe to do so.
If you want to impose restrictions on which items are chosen for the buildings, If you want to impose restrictions on which items are chosen for the buildings,
buildingplan has full support for quality and material filters (see `below buildingplan has full support for quality and material filters (see `below
@ -45,10 +45,10 @@ from the buildingplan placement UI.
One way to integrate buildingplan into your gameplay is to create manager One way to integrate buildingplan into your gameplay is to create manager
workorders to ensure you always have a few blocks/doors/beds/etc. available. You workorders to ensure you always have a few blocks/doors/beds/etc. available. You
can then place as many of each building as you like. Produced items will be used can then place as many of each building as you like. Items will be used to
to build the planned buildings as they are produced, with minimal space build the planned buildings as they are produced, with minimal space dedicated
dedicated to stockpiles. The DFHack `orders` library can help with setting to stockpiles. The DFHack `orders` library can help with setting these manager
these manager workorders up for you. workorders up for you.
If you don't want to use the ``buildingplan`` interface for the building you're If you don't want to use the ``buildingplan`` interface for the building you're
currently trying to place, you can hit :kbd:`Alt`:kbd:`M` or click on the currently trying to place, you can hit :kbd:`Alt`:kbd:`M` or click on the
@ -125,16 +125,17 @@ tiles selected in the construction area are not appropriate for building. For
example, if you want to fill an area with flooring, you can select the entire example, if you want to fill an area with flooring, you can select the entire
area, and any tiles with existing buildings or walls will simply be skipped. area, and any tiles with existing buildings or walls will simply be skipped.
For weapon and spike traps, you can choose how many weapons will be included Some building types will have other options available as well, such as a
on this panel. selector for how many weapons you want in weapon traps or whether you want your
built cages to not have any occupants.
Setting quality and material filters Setting quality and material filters
++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++
If you want to set restrictions on the items chosen to complete the planned If you want to set restrictions on the items chosen to complete the planned
building, you can click on the "filter" button next to the item name or select building, you can click on the "[any material]" link next to the item name or
the item with the :kbd:`*` and :kbd:`/` keys and hit :kbd:`f` to bring up the select the item with the :kbd:`q` or :kbd:`Q` keys and hit :kbd:`f` to bring up
filter dialog. the filter dialog.
You can select whether the item must be decorated, and you can drag the ends of You can select whether the item must be decorated, and you can drag the ends of
the "Item quality" slider to set your desired quality range. Note that blocks, the "Item quality" slider to set your desired quality range. Note that blocks,
@ -147,32 +148,33 @@ You can click on specific materials to allow only items of those materials when
building the current type of building. You can also allow or disallow entire building the current type of building. You can also allow or disallow entire
categories of materials by clicking on the "Type" options on the left. Note categories of materials by clicking on the "Type" options on the left. Note
that it is perfectly fine to choose materials that currently show zero quantity. that it is perfectly fine to choose materials that currently show zero quantity.
`buildingplan` will patiently watch for items made of materials you have `buildingplan` will patiently wait for items made of materials you have
selected. selected to become available.
Choosing specific items Choosing specific items
+++++++++++++++++++++++ +++++++++++++++++++++++
If you want to choose specific items, click on the "Choose from items" toggle If you want to choose specific items instead of using the filters, click on the
or hit :kbd:`i` before placing the building. When you click to place the "Choose items" selector or hit :kbd:`z` before placing the building. You can
building, a dialog will come up that allows you choose which items to use. The choose to be prompted for every item ("Manually") or you can have it
list is sorted by most recently used materials for that building type by automatically select the type of item that you last chose for this building
default, but you can change to sort by name or by available quantity by type. The list you are prompted with is sorted by most recently used materials
clicking on the "Sort by" selector or hitting :kbd:`R`. The configuration for for that building type by default, but you can change to sort by name or by
whether you would like to choose specific items is saved per building type and available quantity by clicking on the "Sort by" selector or hitting :kbd:`R`.
will be restored when you plan more of that building type. The configuration for whether you would like to choose specific items is saved
per building type and will be restored when you plan more of that building type.
You can select the maximum quantity of a specified item by clicking on the item You can select the maximum quantity of a specified item by clicking on the item
name or selecting it with the arrow keys and hitting :kbd:`Enter`. You can name or selecting it with the arrow keys and hitting :kbd:`Enter`. You can
instead select items one at a time by Ctrl-clicking (:kbd:`Shift`:kbd:`Right`) instead select items one at a time by Ctrl-clicking (:kbd:`Shift`:kbd:`Right`)
to increment or Ctrl-Shift-clicking (:kbd:`Shift`:kbd:`Left`) to decrement. to increment or Ctrl-Shift-clicking (:kbd:`Shift`:kbd:`Left`) to decrement.
Once you are satisfied with your choices, click on the "Confirm" button or hit Once you are satisfied with your choices, click on the large green button or hit
:kbd:`C` to continue building. Note that you don't have to select all the items :kbd:`C` to continue building. Note that you don't have to select all the items
that the building needs. Any remaining items will be automatically chosen from that the building needs. Any remaining items will be automatically chosen from
other available items (or future items if not all items are available yet). If other available items (or from items produced in the future if not all items
there are multiple item types to choose for the current building, one dialog are available yet). If there are multiple item types to choose for the current
will appear per item type. building, one dialog will appear per item type.
Building status Building status
--------------- ---------------
@ -180,7 +182,8 @@ Building status
When viewing a planned building, a separate `overlay` widget appears on the When viewing a planned building, a separate `overlay` widget appears on the
building info sheet, showing you which items have been attached and which items building info sheet, showing you which items have been attached and which items
are still pending. For a pending item, you can see its position in the are still pending. For a pending item, you can see its position in the
fulfillment queue. If there is a particular building that you need built ASAP, fulfillment queue. You need to manufacture these items for them to be attached
to the building. If there is a particular building that you need built ASAP,
you can click on the "make top priority" button (or hit :kbd:`Ctrl`:kbd:`T`) to you can click on the "make top priority" button (or hit :kbd:`Ctrl`:kbd:`T`) to
bump the items for this building to the front of their respective queues. bump the items for this building to the front of their respective queues.

@ -4,6 +4,7 @@ local _ENV = mkmodule('gui.widgets')
local gui = require('gui') local gui = require('gui')
local guidm = require('gui.dwarfmode') local guidm = require('gui.dwarfmode')
local textures = require('gui.textures')
local utils = require('utils') local utils = require('utils')
local getval = utils.getval local getval = utils.getval
@ -1110,7 +1111,7 @@ end
-- returns it (in parsed pen form) -- returns it (in parsed pen form)
local function make_hpen(pen, hpen) local function make_hpen(pen, hpen)
if not hpen then if not hpen then
pen = dfhack.pen.parse(pen) pen = to_pen(pen)
-- Swap the foreground and background -- Swap the foreground and background
hpen = dfhack.pen.make(pen.bg, nil, pen.fg + (pen.bold and 8 or 0)) hpen = dfhack.pen.make(pen.bg, nil, pen.fg + (pen.bold and 8 or 0))
@ -1119,7 +1120,7 @@ local function make_hpen(pen, hpen)
-- text_hpen needs a character in order to paint the background using -- text_hpen needs a character in order to paint the background using
-- Painter:fill(), so let's make it paint a space to show the background -- Painter:fill(), so let's make it paint a space to show the background
-- color -- color
local hpen_parsed = dfhack.pen.parse(hpen) local hpen_parsed = to_pen(hpen)
hpen_parsed.ch = string.byte(' ') hpen_parsed.ch = string.byte(' ')
return hpen_parsed return hpen_parsed
end end
@ -1504,6 +1505,77 @@ function HotkeyLabel:onInput(keys)
end end
end end
----------------
-- HelpButton --
----------------
HelpButton = defclass(HelpButton, Panel)
HelpButton.ATTRS{
command=DEFAULT_NIL,
}
local button_pen_left = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 7) or nil, ch=string.byte('[')}
local button_pen_right = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 8) or nil, ch=string.byte(']')}
local help_pen_center = to_pen{
tile=curry(textures.tp_control_panel, 9) or nil, ch=string.byte('?')}
local configure_pen_center = dfhack.pen.parse{
tile=curry(textures.tp_control_panel, 10) or nil, ch=15} -- gear/masterwork symbol
function HelpButton:preinit(init_table)
init_table.frame = init_table.frame or {}
init_table.frame.h = init_table.frame.h or 1
init_table.frame.w = init_table.frame.w or 3
end
function HelpButton:init()
local command = self.command .. ' '
self:addviews{
Label{
frame={t=0, l=0, w=3, h=1},
text={
{tile=button_pen_left},
{tile=help_pen_center},
{tile=button_pen_right},
},
on_click=function() dfhack.run_command('gui/launcher', command) end,
},
}
end
---------------------
-- ConfigureButton --
---------------------
ConfigureButton = defclass(ConfigureButton, Panel)
ConfigureButton.ATTRS{
on_click=DEFAULT_NIL,
}
function ConfigureButton:preinit(init_table)
init_table.frame = init_table.frame or {}
init_table.frame.h = init_table.frame.h or 1
init_table.frame.w = init_table.frame.w or 3
end
function ConfigureButton:init()
self:addviews{
Label{
frame={t=0, l=0, w=3, h=1},
text={
{tile=button_pen_left},
{tile=configure_pen_center},
{tile=button_pen_right},
},
on_click=self.on_click,
},
}
end
----------------- -----------------
-- BannerPanel -- -- BannerPanel --
----------------- -----------------

@ -358,10 +358,10 @@ function PlannerOverlay:init()
} }
local minimized_panel = widgets.Panel{ local minimized_panel = widgets.Panel{
frame={t=0, r=1, w=17, h=1}, frame={t=0, r=1, w=20, h=1},
subviews={ subviews={
widgets.Label{ widgets.Label{
frame={t=0, r=0, h=1}, frame={t=0, r=3, h=1},
text={ text={
{text=' show Planner ', pen=pens.MINI_TEXT_PEN, hpen=pens.MINI_TEXT_HPEN}, {text=' show Planner ', pen=pens.MINI_TEXT_PEN, hpen=pens.MINI_TEXT_HPEN},
{text='['..string.char(31)..']', pen=pens.MINI_BUTT_PEN, hpen=pens.MINI_BUTT_HPEN}, {text='['..string.char(31)..']', pen=pens.MINI_BUTT_PEN, hpen=pens.MINI_BUTT_HPEN},
@ -370,7 +370,7 @@ function PlannerOverlay:init()
on_click=self:callback('toggle_minimized'), on_click=self:callback('toggle_minimized'),
}, },
widgets.Label{ widgets.Label{
frame={t=0, r=0, h=1}, frame={t=0, r=3, h=1},
text={ text={
{text=' hide Planner ', pen=pens.MINI_TEXT_PEN, hpen=pens.MINI_TEXT_HPEN}, {text=' hide Planner ', pen=pens.MINI_TEXT_PEN, hpen=pens.MINI_TEXT_HPEN},
{text='['..string.char(30)..']', pen=pens.MINI_BUTT_PEN, hpen=pens.MINI_BUTT_HPEN}, {text='['..string.char(30)..']', pen=pens.MINI_BUTT_PEN, hpen=pens.MINI_BUTT_HPEN},
@ -378,6 +378,10 @@ function PlannerOverlay:init()
visible=self:callback('is_not_minimized'), visible=self:callback('is_not_minimized'),
on_click=self:callback('toggle_minimized'), on_click=self:callback('toggle_minimized'),
}, },
widgets.HelpButton{
frame={t=0, r=0},
command='buildingplan',
}
}, },
} }

@ -122,7 +122,7 @@ function OrdersOverlay:init()
} }
local minimized_panel = widgets.Panel{ local minimized_panel = widgets.Panel{
frame={t=0, r=0, w=3, h=1}, frame={t=0, r=4, w=3, h=1},
subviews={ subviews={
widgets.Label{ widgets.Label{
frame={t=0, l=0, w=1, h=1}, frame={t=0, l=0, w=1, h=1},
@ -149,6 +149,11 @@ function OrdersOverlay:init()
self:addviews{ self:addviews{
main_panel, main_panel,
minimized_panel, minimized_panel,
widgets.HelpButton{
frame={t=0, r=1},
command='orders',
visible=function() return not self.minimized end,
},
} }
end end

@ -944,23 +944,11 @@ function SquadAssignmentOverlay:init()
}, },
} }
local button_pen_left = dfhack.pen.parse{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 7) or nil, ch=string.byte('[')}
local button_pen_right = dfhack.pen.parse{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 8) or nil, ch=string.byte(']')}
local help_pen_center = dfhack.pen.parse{
tile=curry(textures.tp_control_panel, 9) or nil, ch=string.byte('?')}
self:addviews{ self:addviews{
main_panel, main_panel,
widgets.Label{ widgets.HelpButton{
frame={t=0, r=1, w=3}, frame={t=0, r=1},
text={ command='sort',
{tile=button_pen_left},
{tile=help_pen_center},
{tile=button_pen_right},
},
on_click=function() dfhack.run_command('gui/launcher', 'sort ') end,
}, },
} }
end end

@ -4,7 +4,6 @@ local argparse = require('argparse')
local gui = require('gui') local gui = require('gui')
local logistics = require('plugins.logistics') local logistics = require('plugins.logistics')
local overlay = require('plugins.overlay') local overlay = require('plugins.overlay')
local textures = require('gui.textures')
local widgets = require('gui.widgets') local widgets = require('gui.widgets')
local STOCKPILES_DIR = 'dfhack-config/stockpiles' local STOCKPILES_DIR = 'dfhack-config/stockpiles'
@ -477,15 +476,6 @@ function StockpilesOverlay:init()
}, },
} }
local button_pen_left = dfhack.pen.parse{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 7) or nil, ch=string.byte('[')}
local button_pen_right = dfhack.pen.parse{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 8) or nil, ch=string.byte(']')}
local help_pen_center = dfhack.pen.parse{
tile=curry(textures.tp_control_panel, 9) or nil, ch=string.byte('?')}
local configure_pen_center = dfhack.pen.parse{
tile=curry(textures.tp_control_panel, 10) or nil, ch=15} -- gear/masterwork symbol
self:addviews{ self:addviews{
main_panel, main_panel,
MinimizeButton{ MinimizeButton{
@ -493,23 +483,13 @@ function StockpilesOverlay:init()
get_minimized_fn=function() return self.minimized end, get_minimized_fn=function() return self.minimized end,
on_click=self:callback('toggleMinimized'), on_click=self:callback('toggleMinimized'),
}, },
widgets.Label{ widgets.ConfigureButton{
frame={t=0, r=5, w=3}, frame={t=0, r=5},
text={
{tile=button_pen_left},
{tile=configure_pen_center},
{tile=button_pen_right},
},
on_click=function() ConfigModal{on_close=self:callback('on_custom_config')}:show() end, on_click=function() ConfigModal{on_close=self:callback('on_custom_config')}:show() end,
}, },
widgets.Label{ widgets.HelpButton{
frame={t=0, r=1, w=3}, frame={t=0, r=1},
text={ command='stockpiles',
{tile=button_pen_left},
{tile=help_pen_center},
{tile=button_pen_right},
},
on_click=function() dfhack.run_command('gui/launcher', 'stockpiles ') end,
}, },
} }
end end