-
Notifications
You must be signed in to change notification settings - Fork 498
Refactor button widgets; add widgets.RadioButton
#5781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
bcc0d46
6367685
8badbf4
f7debea
d7fb882
84c33aa
0fdc3b7
3fb5af1
d25d438
ac925d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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') | ||
|
|
@@ -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 | ||
|
|
||
|
|
@@ -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, | ||
|
Comment on lines
+35
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like moving the pens into I'm not so sure about allowing instances, even subclassed instances, to override it's fine. |
||
| } | ||
|
|
||
| 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 | ||
| 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. subclassing there ought to be an abstract class used as the base of |
||
|
|
||
| HelpButton.ATTRS{ | ||
| frame={t=0, r=1, w=3, h=1}, | ||
| command=DEFAULT_NIL, | ||
| pen_center=help_pen_center, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the overriding not worth holding up the merge over a quibble. |
||
| } | ||
|
|
||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if line 26 is redundant, then this is as well. but harmless. |
||
| end | ||
|
|
||
| return HelpButton | ||
| 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('[')} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not believe the |
||
| 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 | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no getter function for the toggle state? are users supposed to probe an instance's yeah, that's what the new documenation says. hm. I don't like that. are there other widgets that similarly require looking inside them for state info? also, no callbacks? I guess a user could catch the |
||
| return RadioButton | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not Bumber's work here, but I think this code is more than a bit strange.
first,
curry()cannot return falsey; it either throws an error or returns a function. accordingly, theor nilclauses don't ever execute.second, that
curry()is used at all. if I understand this construction,tp.control_panel()will be called to get the relevant texpos each time the pen is drawn instead of adding the texture once at module load time with e.g.tile=tp.control_panel(10). I do not know very much about textures, but I would be extremely surprised if the texpos for a control panel texture changes dynamically.and third, that three individual pens are used instead of a three-tile table.I now see that a three-tile Label is created in the postinit stage.myk checked this in a651f64 and he certainly knows more about textures than I do.
anyway, not directly relevant to the PR.