Is it possible to align a column of switches in a custom gui table?
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Is it possible to align a column of switches in a custom gui table?
I have a table of switches that i would like to align centered on the switch widget. But all i can get is an ugly zig-zag line of switches. I'm already using a custom style with custom table alignments.
Has anyone got an idea how to get rid of the zig-zag?
The problem seems to be that the switch widgets alignment center is based on the width of the whole widget including both labels.
Has anyone got an idea how to get rid of the zig-zag?
The problem seems to be that the switch widgets alignment center is based on the width of the whole widget including both labels.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Is it possible to align a column of switches in a custom gui table?
Haven't done anything with switches, so the first idea might not even work:
- give them a width of 116 and set horizontal_align to center
- wrap each switch in a flow with width 116 or horizontally_stretchable and horizontal_align = "center"
- give them a width of 116 and set horizontal_align to center
- wrap each switch in a flow with width 116 or horizontally_stretchable and horizontal_align = "center"
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Is it possible to align a column of switches in a custom gui table?
Nope, setting width produces complete garbage :D.
The main problem seems to be that creating a switch actually creates a flow, containing {label, switch-button, label}. But at runtime it's impossible to access the labels or the flow, everything directly affects the switch button alone. I also tried using a data-stage style that defines a fixed width for the labels, but while the style is applied indeed, the switch creation itself overwrites the minimal_width for the labels (which to me seems buggy - if i'm explicitly specifying width i don't want it overwritten.
Style Pictures
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Is it possible to align a column of switches in a custom gui table?
Just a thought. Does the "anchor" option allow an absolute switch element to be set and the labels relative to that?
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Is it possible to align a column of switches in a custom gui table?
No, GuiAnchor is for a completely different purpose. Also the beauty of using the switch'es built-in labels is that it automatically manages the label style when it changes from left to right. I know i could just create a label-free switch and manage the styles manually, but i was hoping for a solution that avoids that code overhead.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Is it possible to align a column of switches in a custom gui table?
No I meant the option in LuaGuiElement when adding the switch child. I may be misunderstanding it, but it certainly reads as though children can be anchored within the parent with this option.eradicator wrote: ↑Fri Dec 11, 2020 4:14 pmNo, GuiAnchor is for a completely different purpose. Also the beauty of using the switch'es built-in labels is that it automatically manages the label style when it changes from left to right. I know i could just create a label-free switch and manage the styles manually, but i was hoping for a solution that avoids that code overhead.
PS. I've looked for this option being used in other mods, but so far nothing has turned up. It is something that I had planned to use at some point, but I'm rather raw with that side of things. If anyone can make what I think it says it does, that'll be you
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Is it possible to align a column of switches in a custom gui table?
Squelch wrote: ↑Fri Dec 11, 2020 4:38 pm No I meant the option in LuaGuiElement when adding the switch child.
Yes, I read the doc, not sure if you did too. My gui is not in LuaGui.relative, and even if it was that's just not what "anchor" does. Please don't just post wild guesses.ApiDoc wrote:anchor :: GuiAnchor (optional): Where to position the child element when in the relative element.
I've seen Even Distribution use it.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Is it possible to align a column of switches in a custom gui table?
Then I apologise for trying to help you. I'll refrain in future.
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Is it possible to align a column of switches in a custom gui table?
Thank you for trying to help. As you may have noticed i did look into your suggestion and even tried to explain why i think it's not what i need. And it seems to me that you ... how to say this diplomatically ... don't know that much about creating modded guis. I do have some experience with them so i was hoping for help from someone who knows more than me. And as i am also a bit frustrated that such a seemingly simple thing as aligning buttons doesn't work, my capacity for ... diplomatic answers ... is reduced. It was simply meant as a neutral statement. But people these days just seem to take any non-positive answer as an insult *sigh*.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Is it possible to align a column of switches in a custom gui table?
I hoped that my own acknowledgment of that fact would have been enough, so throwing it back at me was received as an insult I'm afraid.eradicator wrote: ↑Sat Dec 12, 2020 5:15 pm...And it seems to me that you ... how to say this diplomatically ... don't know that much about creating modded guis.
The quoted line from the docs, that I did in fact read, is not exactly comprehensive, so my interpretation was that the switch element could be anchored within the parent. I did guess (Wildly, is rather overstating it) that the labels would then be aligned with the anchored switch element which could be intuitively inferred.
I do have some experience with them so i was hoping for help from someone who knows more than me.
Also acknowledged and I think you'll find I even complimented you on that. Maybe that was lost in translation?
I'm afraid that your response did come across as rather abrasive. I sense your frustration, and accept that you might have been having a bad day. We all have them, and on those days our skin might not be so thick.And as i am also a bit frustrated that such a seemingly simple thing as aligning buttons doesn't work, my capacity for ... diplomatic answers ... is reduced. It was simply meant as a neutral statement. But people these days just seem to take any non-positive answer as an insult *sigh*.
The lesson I have learned is not to try and interpret the docs without the experience of implementing anything. I merely wanted to suggest that it appeared to be possible.
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Is it possible to align a column of switches in a custom gui table?
Dunno, it work'ed for me :D. I also usually click all the links to the data types to see what they actually are. That makes it much easier to understand for me.
Duly noted, thank you.
______________
As the thread is kinda derailed now *cough*... and nobody seemes to have any working ideas anyway *sigh*... i went ahead and walked the manual route. It's annoying as expected and i found at least 3 things that i think are engine bugs (reports coming up soon). And then of course i also hit some limitations, like ... modded labels can't have a click sound apparently, but the native switch labels have. Maybe I'll write an exact explanation next week, but the gist is: I re-implement all switch behavior on the lua side. Create a table with {label, switch, label} and then update the label style manually... and also detect clicks on the labels.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Is it possible to align a column of switches in a custom gui table?
OK, so after writing not one but four bug reports related to this little endeavor i might as well also write down how i ended up implementing it manually as best as currently possible. (Unless i'm really missing something blatantly obvious here.)
As stated above each switch is created as "table" type gui element that contains three children: two labels and one switch.
I tried using a horizontal flow first, but that didn't work out due to this bug. I could've written even more workarounds for that but just using a table seemed easier. The table alignments and size here do the main problem-solving magic. They force each label to an exact width so that different content width doesn't disalign the switch button.
Because a normal switch style also contains the label styles i had to copy those too to make them accessible during runtime.
When the player clicks any of the tree components i call a proxy update function. It checks which component the player clicked, and if that click results in a change to the switches state, and then updates the label styles and plays a sound. And then passes the click on to the real click handler - the one that would have been called if i had used a native switch gui element.
So for something as simple as changing the width of a label... this is way too much code. Hopefully any future readers now better understand why i really didn't want to go this route. And may it help other modders if they encounter similar problems.
As stated above each switch is created as "table" type gui element that contains three children: two labels and one switch.
Code: Select all
function ScreenshotGui:add_aligned_switch(opts, args, ...)
if not opts.width then error('aligned switch needs width') end
--
local switch_table = opts.parent.add{
name = args.name, -- element name
type = 'table',
column_count = 3,
style = 'er:screenshot-gui-aligned-switch-table',
}
switch_table.style.width = opts.width
--
self:add_element({
parent = switch_table,
update = 'on_player_clicked_aligned_switch',
},{
type = 'label',
style = 'er:screenshot-gui-aligned-switch-inactive-label',
caption = args.left_label_caption,
},{
})
self:add_element({
name = opts.name, -- storage name
parent = switch_table,
update = 'on_player_clicked_aligned_switch',
},{
type = 'switch',
name = 'aligned-switch',
switch_state = CONST.GUI.DUMMY_SWITCH_STATE,
allow_none_state = args.allow_none_state,
})
self:add_element({
parent = switch_table,
update = 'on_player_clicked_aligned_switch',
},{
type = 'label',
style = 'er:screenshot-gui-aligned-switch-inactive-label',
caption = args.right_label_caption,
},{
})
if opts.update then
set_gui_element_update_handler(switch_table, opts.update)
end
return switch_table
end
I tried using a horizontal flow first, but that didn't work out due to this bug. I could've written even more workarounds for that but just using a table seemed easier. The table alignments and size here do the main problem-solving magic. They force each label to an exact width so that different content width doesn't disalign the switch button.
Code: Select all
styles['er:screenshot-gui-aligned-switch-table'] = {
type = 'table_style',
parent = nil,
column_widths = {
{column = 1, width = 54},
-- {column = 2, width = 20}, -- width of the switch itself is untouched
{column = 3, width = 54},
},
column_alignments = {
{column = 1, alignment = 'middle-right' },
{column = 2, alignment = 'middle-center'},
{column = 3, alignment = 'middle-left' },
}
}
Because a normal switch style also contains the label styles i had to copy those too to make them accessible during runtime.
Code: Select all
-- Create stand-alone names for vanilla switch labels.
styles['er:screenshot-gui-aligned-switch-inactive-label'] =
util.table.deepcopy(styles['switch'].inactive_label)
styles['er:screenshot-gui-aligned-switch-active-label'] =
util.table.deepcopy(styles['switch'].active_label)
When the player clicks any of the tree components i call a proxy update function. It checks which component the player clicked, and if that click results in a change to the switches state, and then updates the label styles and plays a sound. And then passes the click on to the real click handler - the one that would have been called if i had used a native switch gui element.
Code: Select all
function ScreenshotGui:on_player_clicked_aligned_switch(elm, e)
-- triggers for clicks on any of the three components!
local switch_table = e.element.parent
if switch_table == e.element then return end
local left_label = switch_table.children[1]
local switch = switch_table.children[2]
local right_label = switch_table.children[3]
--
local function switch_if_changed(side)
if switch.switch_state ~= side then
-- "gui_click" is not the correct sound for switches, but playing
-- custom sounds does not currently work at high zoom-out @factorio 1.1
self.player.play_sound {path = 'utility/gui_click'}
-- self.player.play_sound {path = 'er:gui-switch-click'}
switch.switch_state = side
end
end
if e.element == left_label then
switch_if_changed 'left'
elseif e.element == right_label then
switch_if_changed 'right'
else
-- switch.switch_state = 'none'
end
--
self:update_aligned_switch_labels()
--
local update_handler_name = get_gui_element_update_handler(switch_table)
if update_handler_name then
e.element = switch_table
self:on_player_clicked_something(e)
end
end
function ScreenshotGui:update_aligned_switch_labels()
local _styles = {
[true ] = 'er:screenshot-gui-aligned-switch-active-label' ,
[false] = 'er:screenshot-gui-aligned-switch-inactive-label',
}
for _, elm in pairs(self.elements) do
if elm.name == 'aligned-switch' then
-- 1,2,3 -> left-label, switch, right-label
local switch_table = elm.parent
local switch_state = switch_table.children[2].switch_state
switch_table.children[1].style = _styles['left' == switch_state]
switch_table.children[3].style = _styles['right' == switch_state]
end
end
end
So for something as simple as changing the width of a label... this is way too much code. Hopefully any future readers now better understand why i really didn't want to go this route. And may it help other modders if they encounter similar problems.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.