LuaGuiElement frame with a close [X] button

Place to post guides, observations, things related to modding that are not mods themselves.
Post Reply
User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

LuaGuiElement frame with a close [X] button

Post by DaveMcW »

If you set the LuaGuiElement.caption property on a frame, it will create a title bar similar to the ingame one, but without a close button.

If you want to have a close button, you need to skip the caption and build your own title bar. I found a couple examples of how to do this, but they did not match the game. Here is my title bar code that creates an exact match to the ingame title bar.

Code: Select all

function add_titlebar(gui, caption, close_button_name)
  local titlebar = gui.add{type = "flow"}
  titlebar.drag_target = gui
  titlebar.add{
    type = "label",
    style = "frame_title",
    caption = caption,
    ignored_by_interaction = true,
  }
  local filler = titlebar.add{
    type = "empty-widget",
    style = "draggable_space",
    ignored_by_interaction = true,
  }
  filler.style.height = 24
  filler.style.horizontally_stretchable = true
  titlebar.add{
    type = "sprite-button",
    name = close_button_name,
    style = "frame_action_button",
    sprite = "utility/close_white",
    hovered_sprite = "utility/close_black",
    clicked_sprite = "utility/close_black",
    tooltip = {"gui.close-instruction"},
  }
end
sample-gui.jpg
sample-gui.jpg (25.73 KiB) Viewed 2080 times

And here is an example script that calls it. Note that you have to handle a click on the X button yourself.

Code: Select all

/c
gui = game.player.gui.screen.add{type = "frame", name = "my-mod-gui", direction = "vertical"}
gui.auto_center = true
add_titlebar(gui, "Sample GUI", "my-mod-x-button")
gui.add{type = "label", caption = "Click the X button to close this gui."}
game.player.opened = gui
script.on_event(defines.events.on_gui_click, function(event)
  if event.element.name == "my-mod-x-button" then
    event.element.parent.parent.destroy()
  end
end)
script.on_event(defines.events.on_gui_closed, function(event)
  if event.element and event.element.valid and event.element.name == "my-mod-gui" then
    event.element.destroy()
  end
end)

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

Re: LuaGuiElement frame with a close [X] button

Post by eradicator »

I build my title bars according to Raiguards Style Guide and they look very vanilla-like.
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.

BlackOverlord
Manual Inserter
Manual Inserter
Posts: 3
Joined: Fri Aug 20, 2021 5:00 pm
Contact:

Re: LuaGuiElement frame with a close [X] button

Post by BlackOverlord »

Is there a proper way to make such frame closing with regular hotkeys (F or ESC)? So that the tooltip on the screenshot wouldn't lie.
By "proper" I mean not defining a separate input for it. I tried using CustomInput with linked_game_control which sounds like what is needed here, but unfortunately it's either also pops up the standard UI (consuming="none") or completely blocks it (consuming="game-only").

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: LuaGuiElement frame with a close [X] button

Post by robot256 »

BlackOverlord wrote:
Mon Jan 02, 2023 2:40 am
Is there a proper way to make such frame closing with regular hotkeys (F or ESC)?
AFAIK, this is done by setting player.opened to your LuaGui root object when you make it visible, and/or responding to the events for on_gui_closed and on_gui_confirmed.

Post Reply

Return to “Modding discussion”