Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,12 @@ Template for new versions:
## Fixes

## Misc Improvements
- ``widgets.HelpButton``: Now derives from ``widgets.ConfigureButton`` instead of using redundant code

## Documentation

## API
- ``widgets.RadioButton``: New button widget resembling those used in ``gui/control-panel``

## Lua

Expand Down
33 changes: 25 additions & 8 deletions docs/dev/Lua API.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6346,12 +6346,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`` option is rendered in green.

ConfigureButton class
---------------------

A 3x1 tile button with a gear symbol on it, intended to represent a configure
icon. Clicking on the icon will run the given callback. The graphics can also
be overridden to create custom buttons.

It has the following attributes:

:on_click: The function to run when the icon is clicked.
:pen_left: Pen or function returning a pen to overwrite the left tile of the button.
:pen_center: As above, but for the center tile (gear symbol).
:pen_right: As above, but for the right tile.

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.
Subclass of ConfigureButton; 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:

Expand All @@ -6361,15 +6376,17 @@ It also sets the ``frame`` attribute so the button appears in the upper right
corner of the parent, but you can override this to your liking if you want a
different position.

ConfigureButton class
---------------------
RadioButton 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.
Subclass of ConfigureButton; a 3x1 tile button that resembles a radio button
(or check box in ASCII mode), identical to the ones found in
`gui/control-panel`. Clicking on the button will toggle its enabled state.
This state is represented by the boolean value ``toggle_state``.

It has the following attributes:

:on_click: The function on run when the icon is clicked.
:initial_state: Start in the ``true`` or ``false`` state. Defaults to ``true``.

BannerPanel class
-----------------
Expand Down
3 changes: 2 additions & 1 deletion library/lua/gui/widgets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ Label = require('gui.widgets.labels.label')
Scrollbar = require('gui.widgets.scrollbar')
WrappedLabel = require('gui.widgets.labels.wrapped_label')
TooltipLabel = require('gui.widgets.labels.tooltip_label')
HelpButton = require('gui.widgets.buttons.help_button')
ConfigureButton = require('gui.widgets.buttons.configure_button')
HelpButton = require('gui.widgets.buttons.help_button')
RadioButton = require('gui.widgets.buttons.radio_button')
BannerPanel = require('gui.widgets.containers.banner_panel')
TextButton = require('gui.widgets.buttons.text_button')
CycleHotkeyLabel = require('gui.widgets.labels.cycle_hotkey_label')
Expand Down
40 changes: 29 additions & 11 deletions library/lua/gui/widgets/buttons/configure_button.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
-- A 3x1 tile button with a gear symbol on it. Clicking on it will run a callback

local textures = require('gui.textures')
local Panel = require('gui.widgets.containers.panel')
local Label = require('gui.widgets.labels.label')
Expand All @@ -6,17 +8,20 @@ local to_pen = dfhack.pen.parse

local button_pen_left = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 7) or nil, ch=string.byte('[')}
local button_pen_center = to_pen{
tile=curry(textures.tp_control_panel, 10) or nil, ch=15} -- gear/masterwork symbol
local button_pen_right = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 8) or nil, ch=string.byte(']')}
local configure_pen_center = to_pen{
tile=curry(textures.tp_control_panel, 10) or nil, ch=15} -- gear/masterwork symbol

---------------------
-- ConfigureButton --
---------------------

---@class widgets.ConfigureButton.attrs: widgets.Panel.attrs
---@field on_click? function
---@field pen_left dfhack.pen|fun(): dfhack.pen
---@field pen_center dfhack.pen|fun(): dfhack.pen
---@field pen_right dfhack.pen|fun(): dfhack.pen

---@class widgets.ConfigureButton.attrs.partial: widgets.ConfigureButton.attrs

Expand All @@ -27,27 +32,40 @@ local configure_pen_center = to_pen{
ConfigureButton = defclass(ConfigureButton, Panel)

ConfigureButton.ATTRS{
frame={t=0, l=0, w=3, h=1},
on_click=DEFAULT_NIL,
pen_left=button_pen_left,
pen_center=button_pen_center,
pen_right=button_pen_right,
}

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.frame.h = self.frame.h or 1
self.frame.w = self.frame.w or 3

self:addviews{
Label{
view_id='label',
frame={t=0, l=0, w=3, h=1},
text={
{tile=button_pen_left},
{tile=configure_pen_center},
{tile=button_pen_right},
{tile=self.pen_left},
{tile=self.pen_center},
{tile=self.pen_right},
},
on_click=self.on_click,
},
}
end

function ConfigureButton:postinit()
local l = self.subviews.label

l.on_click = self.on_click
l.pen_left = self.pen_left
l.pen_center = self.pen_center
l.pen_right = self.pen_right

l:setText({{tile=self.pen_left}, {tile=self.pen_center}, {tile=self.pen_right}})
end

return ConfigureButton
40 changes: 11 additions & 29 deletions library/lua/gui/widgets/buttons/help_button.lua
Original file line number Diff line number Diff line change
@@ -1,53 +1,35 @@
-- A 3x1 tile button with a question mark on it. Clicking on it will show help text for a command

local textures = require('gui.textures')
local Panel = require('gui.widgets.containers.panel')
local Label = require('gui.widgets.labels.label')
local ConfigureButton = require('gui.widgets.buttons.configure_button')

local to_pen = dfhack.pen.parse
local help_pen_center = dfhack.pen.parse{
tile=curry(textures.tp_control_panel, 9) or nil, ch=string.byte('?')}

----------------
-- HelpButton --
----------------

---@class widgets.HelpButton.attrs: widgets.Panel.attrs
---@class widgets.HelpButton.attrs: widgets.ConfigureButton.attrs
---@field command? string

---@class widgets.HelpButton.attrs.partial: widgets.HelpButton.attrs

---@class widgets.HelpButton: widgets.Panel, widgets.HelpButton.attrs
---@field super widgets.Panel
---@class widgets.HelpButton: widgets.ConfigureButton, widgets.HelpButton.attrs
---@field super widgets.ConfigureButton
---@field ATTRS widgets.HelpButton.attrs|fun(attributes: widgets.HelpButton.attrs.partial)
---@overload fun(init_table: widgets.HelpButton.attrs.partial): self
HelpButton = defclass(HelpButton, Panel)
HelpButton = defclass(HelpButton, ConfigureButton)

HelpButton.ATTRS{
frame={t=0, r=1, w=3, h=1},
command=DEFAULT_NIL,
pen_center=help_pen_center,
}

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('?')}

function HelpButton:init()
self.frame.w = self.frame.w or 3
self.frame.h = self.frame.h or 1

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,
},
}
self.on_click = function() dfhack.run_command('gui/launcher', command) end
end

return HelpButton
49 changes: 49 additions & 0 deletions library/lua/gui/widgets/buttons/radio_button.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- A 3x1 tile button that toggles state when clicked

local textures = require('gui.textures')
local ConfigureButton = require('gui.widgets.buttons.configure_button')

local to_pen = dfhack.pen.parse

local enabled_pen_left = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 1), ch=string.byte('[')}
local enabled_pen_center = to_pen{fg=COLOR_LIGHTGREEN,
tile=curry(textures.tp_control_panel, 2) or nil, ch=251} -- check
local enabled_pen_right = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 3) or nil, ch=string.byte(']')}
local disabled_pen_left = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 4) or nil, ch=string.byte('[')}
local disabled_pen_center = to_pen{fg=COLOR_RED,
tile=curry(textures.tp_control_panel, 5) or nil, ch=string.byte('x')}
local disabled_pen_right = to_pen{fg=COLOR_CYAN,
tile=curry(textures.tp_control_panel, 6) or nil, ch=string.byte(']')}

-----------------
-- RadioButton --
-----------------

---@class widgets.RadioButton.attrs: widgets.ConfigureButton.attrs
---@field initial_state boolean

---@class widgets.RadioButton.attrs.partial: widgets.RadioButton.attrs

---@class widgets.RadioButton: widgets.ConfigureButton, widgets.RadioButton.attrs
---@field super widgets.ConfigureButton
---@field ATTRS widgets.RadioButton.attrs|fun(attributes: widgets.RadioButton.attrs.partial)
---@overload fun(init_table: widgets.RadioButton.attrs.partial): self
RadioButton = defclass(RadioButton, ConfigureButton)

RadioButton.ATTRS{
initial_state=true,
}

function RadioButton:init()
self.toggle_state = self.initial_state

self.on_click = function() self.toggle_state = not self.toggle_state end
self.pen_left = function() return self.toggle_state and enabled_pen_left or disabled_pen_left end
self.pen_center = function() return self.toggle_state and enabled_pen_center or disabled_pen_center end
self.pen_right = function() return self.toggle_state and enabled_pen_right or disabled_pen_right end
end

return RadioButton
Loading