on_gui_click, press/release posibility?

Place to get help with not working mods / modding interface.
robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

on_gui_click, press/release posibility?

Post by robertpaulson »

Hi, the on_gui_click activates when the mb is released (since the click is complete on the release), is it possible to trigger something on gui button pressed?

I'm trying to avoid using two buttons or clicking same one twice(also don't want to use a letter key- i know i'm picky). I would like to trigger something if gui button (I would compromised for a letter key here) is held 3seconds, and do something different if its just clicked.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13175
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: on_gui_click, press/release posibility?

Post by Rseding91 »

There's currently no way to do that.

Also I'm quite sure that the event is fired on mouse down in 0.15 not mouse up.
If you want to get ahold of me I'm almost always on Discord.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

Rseding91 wrote:There's currently no way to do that.

Also I'm quite sure that the event is fired on mouse down in 0.15 not mouse up.
I see, I might do double click then or something like that.

Also I checked just now- v15.31 - gui buttons react on mouse release not mouse pressed... which is working correctly (on click)

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

Re: on_gui_click, press/release posibility?

Post by eradicator »

If you just want to have a button with two functions you might consider left/right/middle click or alt/shift/control modifiers as a workaround: http://lua-api.factorio.com/latest/even ... _gui_click (thanks again for that rsed)

Also I wrote a feature request some time ago that might make KeyDown and KeyUp available as a side effect. Feel free to push/extend it :P viewtopic.php?f=28&t=52065
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.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

eradicator wrote:If you just want to have a button with two functions you might consider left/right/middle click or alt/shift/control modifiers as a workaround: http://lua-api.factorio.com/latest/even ... _gui_click (thanks again for that rsed)

Also I wrote a feature request some time ago that might make KeyDown and KeyUp available as a side effect. Feel free to push/extend it :P viewtopic.php?f=28&t=52065
Thanks so much! The key modifiers might be really helpful. I have also bumped your post since implementing the drag/drop will be awesome.

P.s. kinda derailing this but is it possible to put a button inside a frame or a in the table that's inside a frame? allowing to sort/expand/collapse the content of the frame would be so nice

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

Re: on_gui_click, press/release posibility?

Post by eradicator »

robertpaulson wrote:P.s. kinda derailing this but is it possible to put a button inside a frame or a in the table that's inside a frame? allowing to sort/expand/collapse the content of the frame would be so nice
Flows, frames, tables and scroll-panes can be arbitrarily nested into each other. Without that GUIs wouldn't really be possible. For example the base game gui is (guessing from it's appearance) a flow (invisible) with three frames (inventory, logistic slots, crafting). And e.g. the inventory frame contains a table of buttons, where each button is an inventory "slot".

There are no pre-implemented sort/expand/collapse functions. So any functionality like that you'd have to implement yourself. Gui elements always appear in the order they were created so sorting them would most of the time require you to destroy and recreate them. The only exception would be sprite-button where you can just reassign a new sprite.
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.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

eradicator wrote:
robertpaulson wrote:P.s. kinda derailing this but is it possible to put a button inside a frame or a in the table that's inside a frame? allowing to sort/expand/collapse the content of the frame would be so nice
Flows, frames, tables and scroll-panes can be arbitrarily nested into each other. Without that GUIs wouldn't really be possible. For example the base game gui is (guessing from it's appearance) a flow (invisible) with three frames (inventory, logistic slots, crafting). And e.g. the inventory frame contains a table of buttons, where each button is an inventory "slot".

There are no pre-implemented sort/expand/collapse functions. So any functionality like that you'd have to implement yourself. Gui elements always appear in the order they were created so sorting them would most of the time require you to destroy and recreate them. The only exception would be sprite-button where you can just reassign a new sprite.
That's great and makes complete sense as for GUI. As you can tell i have very little experience with it. I will look into some mods with complex gui's to understand it better. I have a feeling this will delay again the mod I'm working on :P but it will make it much nicer and easy to use.

thanks for your help.

Too bad about the key press/release functionality not being supported by the base logic.... yet, somehow I have a hard time believing that :P

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

Re: on_gui_click, press/release posibility?

Post by eradicator »

GUIs may seem daunting but creating them is actually quite easy, they're just a stack of boxes after all. Imagine stacking rectangular toy blocks into each other. Every one a tiny bit smaller than the last one. Interacting with them is easy too, they're just like a table with many subtables.
I wouln't recommend looking at "complex" guis tho as then you'll be stuck trying to understand the mods internal struckture more than the actual gui design. I don't play many mods tho, so i wouldn't know any good examples. And the only published mod with gui i have on the modportal is outdated :roll:

I also find it greatly helps to draw yourself a diagram of the gui structure before implementing it:
Diagram Example
What are you trying to make btw?
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.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

eradicator wrote:
What are you trying to make btw?

I currently have a button on a left top that when clicked displays details of the mod in the same corner of the screen. 1st I will make the info collapsible to improve the visibility. But now I'm thinking about buttons that will trigger the mod functions, and add one that will abort the action. abort should not be a problem, but the trigger itself might require changing/adding a stack onto the cursor and the trigger will happen when the item is placed, the event requires a location and that's how it currently functions... but I might spin it around and first place the item->acquire the location and then choose the appropriate type of action with the buttons in the GUI...( I'm no sure if you are familiar with Ion Cannon mod but basically I use its mechanics, I asked Supercheese and he gave an OK to use his mod)

btw: is there a way to add those info bubbles that show up when you mouse over a button/text field? The same as for the rocket silo button ("toggle rocket silo frame"), and all the buttons above the mini-map. I can't find appropriate setting on LuaGuiElement page

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

Re: on_gui_click, press/release posibility?

Post by eradicator »

Info bubbles? Sure: Tooltip. Your face: :oops: My face: 8-)

For switching mod options on/off check-box is better suited than button imho (unless you want to go through the trouble of defining proper custom button styles to make the buttons stay debossed.)

For getting positions there's events.defines.on_put_item for "position" and if you want to mark an area you can define a custom "selection-tool" prototype. (I only know Ion Cannon namewise but i bet it uses on_put_item...unless it uses a custom grenade or something. So many possibilities.)

When interacting with the cursor_stack be sure to check for .valid_for_read and .valid. The cursor is never "empty"(nil) internally. When there's no items on it it becomes an empty stack which is .valid_for_read==true but .valid=false. Also ofc you have to deal with there being actual items on the cursor which need to be put pack into the inventory - which in turn might be full :P.

Also be aware that GUI elements are displayed in the order they are added. So if there's other mods before you your button might not actually be in the corner anymore.
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.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

eradicator wrote:Info bubbles? Sure: Tooltip. Your face: :oops: My face: 8-)
haha indeed... this is great, it will allow me to remove the clunkyness of my mod. I was using different items for different modes, now i will just have one. thanks for all your help! hopefully i will get it finished by mid next week... if i don't find another thing worth improving lol

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

eradicator wrote:GUIs may seem daunting but creating them is actually quite easy, they're just a stack of boxes after all. Imagine stacking rectangular toy blocks into each other. Every one a tiny bit smaller than the last one. Interacting with them is easy too, they're just like a table with many subtables.
I wouln't recommend looking at "complex" guis tho as then you'll be stuck trying to understand the mods internal struckture more than the actual gui design. I don't play many mods tho, so i wouldn't know any good examples. And the only published mod with gui i have on the modportal is outdated :roll:

I also find it greatly helps to draw yourself a diagram of the gui structure before implementing it:
Diagram Example
What are you trying to make btw?
quick question about your diagram.... what is the reasons behind flow/frame and table, i can't find details on wiki... I was trying to put a table inside a table, or table inside a flow and i get nil error for that inner table when trying to add labels to it.... like it wasn't properly created

i'm trying to get two labels on left side and one button that's two lines tall on the right... if i put it all inside one table i get the firsl row double spaced and it looks odd, so i wanted to keep the first column single spaced while having a tall button in the second row:


Image

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7351
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by bobingabout »

try adding another table for those two text boxes, then you can align the button with the table.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

Bilka
Factorio Staff
Factorio Staff
Posts: 3123
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: on_gui_click, press/release posibility?

Post by Bilka »

robertpaulson wrote: Image
Your "what I want image" shows what you need to do rather nicely. To the table going around the two texts and the button, add two things: a flow with a max height of the height of the button, and a button. To the flow you then add the two texts:
Gui_example.png
Gui_example.png (5.64 KiB) Viewed 4479 times
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

Bilka wrote:
Your "what I want image" shows what you need to do rather nicely.
it does show it nicely altho the problem is with implementation. I have tried switching that inner-table into a flow but I am getting same results.... here is the simplified code:

Code: Select all

frame = player.gui.left.add{type="frame", name="mainframe", direction="vertical"} ----CREATED A FRAME (holder of everything)

frame.add{type="table", colspan=1, name="table1"} -- FIRST TABLE FOR FIRST 2 lines of text
frame["table1"].add{type = "label", caption={"text1"}} -- 1st line
frame["table1"].add{type = "label", caption = {"text2"}} --2nd line

frame.add{type="table", colspan=2, name="table2"} -- 2nd table for two lines (left) and button (right)
frame["table2"].add{type="flow", name="in-flow", direction="vertical"} -- putting flow into 1st column

frame["table2"].add{type="button", name="table-button", style="button-style"} ---BUTTON BETA


frame["in-flow"].add{type = "label", caption = {"text3"}} -- putting 1st label into the flow (ERROR attempt to index field 'in-flow' (a nil value)
same error happens if that flow is a table

edit: I feel really stupid right now, I forgot these are nested.... sorry every1

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5148
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by Klonan »

robertpaulson wrote:
Bilka wrote:
Your "what I want image" shows what you need to do rather nicely.
it does show it nicely altho the problem is with implementation. I have tried switching that inner-table into a flow but I am getting same results.... here is the simplified code:

Code: Select all

frame = player.gui.left.add{type="frame", name="mainframe", direction="vertical"} ----CREATED A FRAME (holder of everything)

frame.add{type="table", colspan=1, name="table1"} -- FIRST TABLE FOR FIRST 2 lines of text
frame["table1"].add{type = "label", caption={"text1"}} -- 1st line
frame["table1"].add{type = "label", caption = {"text2"}} --2nd line

frame.add{type="table", colspan=2, name="table2"} -- 2nd table for two lines (left) and button (right)
frame["table2"].add{type="flow", name="in-flow", direction="vertical"} -- putting flow into 1st column

frame["table2"].add{type="button", name="table-button", style="button-style"} ---BUTTON BETA


frame["in-flow"].add{type = "label", caption = {"text3"}} -- putting 1st label into the flow (ERROR attempt to index field 'in-flow' (a nil value)
same error happens if that flow is a table

edit: I feel really stupid right now, I forgot these are nested.... sorry every1
Looking at the way you format it, i'm not surprised you got some things confused

I rewrote your code into the style I use, which i hope makes things more readable

Code: Select all

function add_gui(gui)
  
  local frame = gui.add{type = "frame"} --Ok so this holds all your junk
  local table_1 = frame.add{type = "table", colspan = 1}
  table_1.add{type = "label", caption = "text 1 which can be long"}
  table_1.add{type = "label", caption = "text 2 which might also be lengthy"}
  
  local inner_table = table_1.add{type = "table", colspan = 2}
  local inner_flow = inner_table.add{type = "flow", direction = "vertical"}
  inner_flow.add{type = "label", caption = "text 3 describing this"}
  inner_flow.add{type = "label", caption = "text 4 describing that"}
  inner_table.add{type = "button", caption = "button 1"}
  
  table_1.add{type = "label", caption = "Okay back to normal labels"}

end
The result

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

Re: on_gui_click, press/release posibility?

Post by eradicator »

As the more specific question seem to have already been answered. I'll just add a more generic answer. On a sidenode though you should probably name your "mainframe" something more unique like "mymodname-mainframe" so to not collide with other mods. @Klonan seems to be using unnamed containers in his example... honestly i have no clue how that works out (didn't even know one could do that :P).
robertpaulson wrote:quick question about your diagram.... what is the reasons behind flow/frame and table, i can't find details on wiki...
"flow", "frame" and "scroll-pane" are containers that form a single line of all the elements added to them. In direction="horizontal" the objects will be ordered (in order of addition) left-to-right, in direction="vertical" top to bottom. "flow" and "scroll-pane" are invisible while "frame" renders a border and background for the container (The border takes space inside the container, so if you're managing element height/width yourself you need to consider this). When auto-sizing the height/width will be the one of the largest element for horizontal/vertical mode.

"scroll-pane" allows the contained element(s) to be larger than itself and displays scroll bars according to "vertical/horizontal_scroll_policy".

"table" is almost the same as "frame" with direction="vertical" except that after n'th element (colspan=n) it will not add the next element to the right but instead start a new row. Each row/column will have the height/width of the heighest/widest element it contains. No element can be larger than one cell (this was your problem) so to make the "table" format two elements in the space of one cell you have to first "reserve" a table cell with an empty container (any container will work) and then add the things you want to display in a single cell to that container.


Summary:

"frame":
  • visible
  • ✖ one row or column depending on "direction"
  • ✖ content can't be larger than container
"flow":
  • ✖ invisible
  • ✖ one row or column depending on "direction"
  • ✖ content can't be larger than container
"scroll-pane":
  • ✖ invisible
  • ✖ one row or one column depending on "direction"
  • ✔ content can be larger than container
  • ✖ size must be manually specified
"table":
  • ✖ invisible
  • multiple rows and "colspan=n" columns
  • ✖ content can't be larger than container
  • ✖ each "cell" is as high as the highest element in the row
  • ✖ each "cell" is as wide as the widest element in the column
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.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by robertpaulson »

Klonan wrote:
Looking at the way you format it, i'm not surprised you got some things confused

I rewrote your code into the style I use, which i hope makes things more readable
Thanks so much, I will try to re-organize things. Your way seems much cleaner especially for big guis, I will see how big mine will get.
eradicator wrote:As the more specific question seem to have already been answered. I'll just add a more generic answer.
The breakdown helps a TON. Thank you very much. It will definitely help with the follow up mod I have in mind!

Regarding Klonans unnamed variables, this is just a guess, but I think as long as you have a reference for the object it will work. Since all his containers are assigned to variables he doesn't need to name them. And it will throw an error if you want to reference to them via name and not the variable since the name is nil(or is it a number ordered by creation order?).... like a "key" in a table I would imagine... and via name you can only reference a child and not the parent (same as I was not using "mainframe" but frame var to look up my initial frame...
now the question is: is the "name" reference more efficient than variable reference? and the real problem will come from the nameless button... I mean how do you define action on gui.click for that rouge button? inner_table[2]? :P

nonetheless, thank you all for helping me out! very much appreciated!

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

Re: on_gui_click, press/release posibility?

Post by eradicator »

I can imagine just fine how creating elements without a string-name would work. The problems arise - as you noticed yourself - when you need to actually access the guis elements. Even if you store a pointer to the element you then have to store that pointer somewhere safe. Which means you have to store them in global because guis are persistent through save/load. I personally certainly don't like the idea of storing pointers to all relevant gui elements in global. I'd be far to concerned about increasing load time. So usually i only store a pointer to what you called "mainframe", i.e. the topmost element of each players instance of my mods gui.
robertpaulson wrote: now the question is: is the "name" reference more efficient than variable reference? and the real problem will come from the nameless button... I mean how do you define action on gui.click for that rouge button? inner_table[2]? :P
As said above, realistically you don't. Even if you stored a pointer in global you'd then have to somehow compare it to the element from the on_gui_click event. Direct comparision of pointers would probably not work. Name might work, but if you're already comparing names might as well use a fixed one.
So anything that is not purely for display (labels, sprites) and needs to be accessed later should have an easily readable and probably unique name. So any button, checkbox or textfield should have a name.

I'm paranoid so i usually define my button names at the top of the file and use a "constant" in the actual code. That way it's easy to change the actual name later. (Also i find it easier to read that way.)

Code: Select all

local MENU_FRAME = 'mymodname_menu_frame'
local OK_BUTTON = 'mymodname_menu_ok_button'

script.on_event{defines.events.on_player_created,function(event)
  local ok_button = game.players[event.player_index].gui.top
     .add{type='frame', name=MENU_FRAME}
     .add{type=button, name=OK_BUTTON_NAME}
  --dostuff
  end)

script.on_event{defines.events.on_gui_click,function(event)
  if event.element.name == OK_BUTTON then
    game.players[event.player_index].gui.top[MENU_FRAME].destroy()
    --dostuff
    end
  end)

--this code is written from memory and might contain errors :P
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
Klonan
Factorio Staff
Factorio Staff
Posts: 5148
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: on_gui_click, press/release posibility?

Post by Klonan »

eradicator wrote:
robertpaulson wrote: now the question is: is the "name" reference more efficient than variable reference? and the real problem will come from the nameless button... I mean how do you define action on gui.click for that rouge button? inner_table[2]? :P
As said above, realistically you don't. Even if you stored a pointer in global you'd then have to somehow compare it to the element from the on_gui_click event. Direct comparision of pointers would probably not work. Name might work, but if you're already comparing names might as well use a fixed one.
So anything that is not purely for display (labels, sprites) and needs to be accessed later should have an easily readable and probably unique name. So any button, checkbox or textfield should have a name.
Comparing the objects is no problem, such as:

Code: Select all

global.my_gui_element = game.players[1].gui.center.add{type = "button", caption = "Push me"}

on_gui_click(event)
  if event.element == global.my_gui_element then
    game.print("Nice")
  end
end
Nameless elements can also be accessed through their parent, such as

Code: Select all

my_gui = player.gui.center.children[1]
Really nameless elements are best for things like labels, frames, flows, holding tables, things that you don't have to listen for directly in events

Post Reply

Return to “Modding help”