How to start creating a gui

Place to get help with not working mods / modding interface.
User avatar
SLywnow
Inserter
Inserter
Posts: 39
Joined: Sat Apr 25, 2020 7:37 pm
Contact:

How to start creating a gui

Post by SLywnow »

I want to make simple gui window, just sprite, which changes from a global variable
This gui must be opened when I click on some entity
I try to find how to do it, but I don't know where to start to learn how to make gui
Pi-C
Smart Inserter
Smart Inserter
Posts: 1759
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: How to start creating a gui

Post by Pi-C »

SLywnow wrote: Wed Aug 19, 2020 1:19 am I want to make simple gui window, just sprite, which changes from a global variable
This gui must be opened when I click on some entity
I've made something like that for minime -- a very basic GUI with one button that will open or close the actual menu, which is just a number of buttons arranged vertically.

For each player, the GUI needs to be defined first:

Code: Select all

local gui = player.gui.top

  ------------------------------------------------------------------------------------
  -- Define GUI
  gui.add{
    type = "flow",
    name = "minime_gui",
    enabled = true,
    direction = "vertical"
  }
Just to save some typing, I then redefine gui so it will be the top level of my mod's GUI (vs. the top level for all GUIs the player may have from other mods) and add a toggle button:

Code: Select all

  gui = gui["minime_gui"]

  ------------------------------------------------------------------------------------
  -- Toggle button
  gui.add{
    type = "sprite-button",
    name = "minime_toggle_list",
    caption = {"minime-GUI.gui-name"},
    tooltip = {"minime-GUI.gui-name-tooltip"},
    enabled = true,
    style = "minime_toggle_button"   
  }
I'm not quite sure right now why I've used "sprite-button", because the button doesn't display a sprite but just the localized text passed on as "caption". The style has to exist before you can use it, so I defined it in data stage (see at the end of this post).

Code: Select all

  ------------------------------------------------------------------------------------
  -- Frame
  gui.add{
    type = "frame",
    name = "minime_character_list",
    caption = {"minime-GUI.gui-name-tooltip"},
    direction = "vertical",
    visible = global.player_data[player.index].show_character_list,
  }
This probably is the most important part. It doesn't display anything useful yet, but it's the container for all the other buttons I'll need to create.

Code: Select all

  local buttons = gui["minime_character_list"]

  ------------------------------------------------------------------------------------
  -- If the player's character is not on our list, let's just assume it's a valid cha-
  -- racter and create a button with a warning as tooltip.
  if some_condition == true then
    buttons.add{
      type = "button",
      name = "minime_characters_" .. last_character,
      caption = minime.loc_name(player.character),
      enabled = true,
      style = "minime_button_on",
    }
  end
This is a special button I need in my particular setup. The other buttons are created similarly:

Code: Select all

  -- Create normal buttons for known characters from our list
  for char, loc_name in pairs(global.minime_characters) do
    buttons.add{
      type = "button",
      name = "minime_characters_" .. char,
      caption = loc_name,
      enabled = true,
      style = "minime_button_on",
    }
  end
After I've set up the GUI, I can then change the style of individual buttons, enable or disable them, hide them etc.:

Code: Select all

  -- Turn other buttons red if button for current character should be removed
  if some_condition == true  then
    for _, button in ipairs(buttons.children) do
      button.style = "minime_button_warning"
      button.tooltip = {"minime-GUI.remove-character-button-warning",
                        minime.loc_name(player.character)}
    end
  -- Turn button for current character off
  else
    for _, button in ipairs(buttons.children) do
      if other_condition == true then
        button.style = "minime_button_off"
        button.tooltip = table_size(global.minime_characters) == 2 and
                          {"minime-GUI.disabled-button-tooltip"} or
                          {"minime-GUI.disabled-button-tooltip-plural"}
        button.enabled = false
        break
      end
    end
  end
There's one thing to consider, though:

Code: Select all

local buttons = gui["minime_gui"]["minime_character_list"]
for _, button in pairs(buttons) do 
	…
end
won't work -- you'll need to use buttons.children to be able to access the properties of individual buttons! It took me quite a while to figure this out.

Finally an example of button-style definitions I use in data.lua:

Code: Select all

data.raw['gui-style'].default.minime_button_off = {
  type = "button_style",
  parent = "button",
  padding = 4,
}

data.raw['gui-style'].default.minime_button_on = {
  type = "button_style",
  parent = "green_button",
  padding = 4,
Looking at this, I wonder why it's called "default". I guess it would be cleaner to use another name. But as I don't have a lot of experience with making GUIs yet, I've looked at some code from another mod to get started.
I try to find how to do it, but I don't know where to start to learn how to make gui
I'm not aware of a "How to make a GUI" tutorial, but you should definitely have a look at the documentation of LuaGui and LuaGuiElement!
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
User avatar
SLywnow
Inserter
Inserter
Posts: 39
Joined: Sat Apr 25, 2020 7:37 pm
Contact:

Re: How to start creating a gui

Post by SLywnow »

Pi-C wrote: Wed Aug 19, 2020 7:22 am
Thank you very much!
Post Reply

Return to “Modding help”