Is it possible to align a column of switches in a custom gui table?

Place to get help with not working mods / modding interface.
Post Reply
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

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?

align_plain.png
align_plain.png (7.03 KiB) Viewed 3077 times
align_table_style.png
align_table_style.png (88.81 KiB) Viewed 3077 times

The problem seems to be that the switch widgets alignment center is based on the width of the whole widget including both labels.

align_boxes.png
align_boxes.png (7.68 KiB) Viewed 3077 times
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.

Choumiko
Smart Inserter
Smart Inserter
Posts: 1352
Joined: Fri Mar 21, 2014 10:51 pm
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by Choumiko »

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"

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

Choumiko wrote:
Tue Dec 08, 2020 10:13 pm
- give them a width of 116 and set horizontal_align to center
Nope, setting width produces complete garbage :D.
width_style.png
width_style.png (14.83 KiB) Viewed 3015 times

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.

Squelch
Filter Inserter
Filter Inserter
Posts: 346
Joined: Sat Apr 23, 2016 5:31 pm
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by Squelch »

Just a thought. Does the "anchor" option allow an absolute switch element to be set and the labels relative to that?

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

Squelch wrote:
Fri Dec 11, 2020 3:01 pm
Does the "anchor" option allow an absolute switch element to be set and the labels relative to that?
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.

Squelch
Filter Inserter
Filter Inserter
Posts: 346
Joined: Sat Apr 23, 2016 5:31 pm
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by Squelch »

eradicator wrote:
Fri Dec 11, 2020 4:14 pm
Squelch wrote:
Fri Dec 11, 2020 3:01 pm
Does the "anchor" option allow an absolute switch element to be set and the labels relative to that?
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.
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.

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 :D

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

Squelch wrote:
Fri Dec 11, 2020 4:38 pm
No I meant the option in LuaGuiElement when adding the switch child.
ApiDoc wrote:anchor :: GuiAnchor (optional): Where to position the child element when in the relative element.
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.
Squelch wrote:
Fri Dec 11, 2020 4:38 pm
PS. I've looked for this option being used in other mods,
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.

Squelch
Filter Inserter
Filter Inserter
Posts: 346
Joined: Sat Apr 23, 2016 5:31 pm
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by Squelch »

eradicator wrote:
Fri Dec 11, 2020 6:57 pm
Please don't just post wild guesses.
Then I apologise for trying to help you. I'll refrain in future.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

Squelch wrote:
Fri Dec 11, 2020 8:09 pm
eradicator wrote:
Fri Dec 11, 2020 6:57 pm
Please don't just post wild guesses.
Then I apologise for trying to help you. I'll refrain in future.
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.

Squelch
Filter Inserter
Filter Inserter
Posts: 346
Joined: Sat Apr 23, 2016 5:31 pm
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by Squelch »

eradicator wrote:
Sat Dec 12, 2020 5:15 pm
Squelch wrote:
Fri Dec 11, 2020 8:09 pm
eradicator wrote:
Fri Dec 11, 2020 6:57 pm
Please don't just post wild guesses.
Then I apologise for trying to help you. I'll refrain in future.
...And it seems to me that you ... how to say this diplomatically ... don't know that much about creating modded guis.
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.

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?
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*.
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.

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.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

Squelch wrote:
Sat Dec 12, 2020 6:02 pm
The quoted line from the docs, that I did in fact read, is not exactly comprehensive
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.
Squelch wrote:
Sat Dec 12, 2020 6:02 pm
Also acknowledged and I think you'll find I even complimented you on that. Maybe that was lost in translation?
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.
screenshot_001h_06m_20s.png
screenshot_001h_06m_20s.png (31.97 KiB) Viewed 2813 times
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.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Is it possible to align a column of switches in a custom gui table?

Post by eradicator »

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.

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.

Post Reply

Return to “Modding help”