## GUI Compendium

The Lua scripting language allows you to give your plugin more advanced features.

Moderator: Plugin Moderators

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### GUI Compendium

Cover image by Bearbear76.

TheoTown features a powerful framework of user interface elements that are used throughout the whole game. The main goal within the past few weeks was to expose this functionality to plugins so that plugins can show fancy information dialog windows, offer tool options and so on. For information about specific commands please have a look at the GUI library documentation.

In order to use these functionalities you need at least version 1.9.30 of the game. Don't forget to set the min version attribute in the plugin upload process accordingly (to 1930) if you are using these features in your plugin. Alternatively you can check for the existence of individual GUI functions during runtime by ensuring that they are not nil.

1. Introduction
GUI refers to graphical user interface and generally refers to the windows, buttons and texts you see on the screen. Their primary goal is to offer some sort of interface between the user and the program. It is usually implemented in a hierarchical way that allows to nest objects into each other which offers great flexibility.
On the left side you see an example of what you would see on the screen. On the right side there's a potential hierarchical tree of objects for that screen outlined. We have one root object at the top that has every other object as a direct or indirect child below it. All objects share some common functionality like having a location (relative to its parent), size and potential children. The nesting of objects is not necessarily useful for all types of objects. For example there's usually no reason to put something into a label object.

The order of the children within an object matters since they are drawn and updated in that order. Because of that you can for example put a window into the foreground by changing its child index accordingly (higher index = drawn and updated later = on top of siblings that have a lower index). The order will also have an impact on the placement if the parent is a layout object.

Here's a small example of how nesting of objects may look like in your plugin code-wise :

Code: Select all    Reset

function script:buildCityGUI()
local root = GUI.getRoot()
x = 20,
y = 20,
width = 100,
height = 30
}
icon = Icon.OK,
text = 'OK!'
}
end
Interactive Lua editor
Here a panel would be added to the main root GUI object. After that, a button is added to that newly created panel.

By using Real-time script editing you can speed up the development process since you usually won't have to restart the whole game to see how changes to the script affect the game. However, you may have to revisit the stage/screen you're building something for in order to see an effect since the event functions won't be called automatically after reloading the script (however, you can implement it to do that manually; it's not done by default because the previous script may not have cleaned up up things like created GUI objects).

2. Lifecycle
You can only use the GUI library when it is setup. This is usually the case when the game is in a so called stage state. You can check if it is valid by checking if the GUI table is not nil. Most of the time you don't have to check for this manually since the flow of function calls implies its validity. In general you are safe to build your UI in script:enterStage(). If you want to build UI for the city stage (called GameStage in the game) you should rely on script:buildCityGUI() instead since the city stage (that is when a city is open) can cache the GUI hierarchy between stages for performance reasons. script:buildCityGUI will only be called after the GUI hierarchy for the city was (re-)built.

Technically your GUI objects are only valid if they are part of the currently active GUI hierarchy. However, because of the caching for the city stage they might become valid again which is why you may have to check if the GUI objects that you want to build already exist. You can do that for example by using Ids for your objects to find them in the hierarchy if they already exist or by only building city UI in the script:buildCityGUI event function.

3. Dialog
Dialog windows are commonly used to present a set of information for a limited time to the user. In the simplest case a dialog window just features an icon, a title, a text and some buttons to interact with it.

Code: Select all    Reset

function script:buildCityGUI()
local dialog = GUI.createDialog{
icon = Icon.SETTINGS,   -- Icon of the dialog
title = 'Title',        -- Title of the dialog
text = 'Text',          -- Text for the inner area of the dialog
width = 180,            -- Width of the dialog, 300 by default
height = 100,           -- Height of the dialog, 160 by default
closeable = true,       -- Show close button, true by default
pause = true,           -- Pause game when dialog is open, true by default
onUpdate = function() end,   -- Called every frame
onCancel = function() end,   -- For closeable dialogs when close button is hit
onClose = function() end,    -- When the dialog gets closed

-- An array of actions that will be shown as buttons, nil by default
actions = {
{
icon = Icon.CANCEL, -- Icon on the button
text = Translation.control_cancel,  -- Text on the button
autoClose = true    -- Close the dialog when this button gets hit, true by default
},
{
id = '\$cmdCancel',  -- Id for the button
icon = Icon.OK,     -- Icon for the button
text = Translation.control_ok,      -- Text on the button
onClick = function() end,           -- Will be called when the button gets clicked
golden = true       -- Will make the button golden, false by default
}
}
}
end
Interactive Lua editor
Since dialog windows are composed of other GUI objects you can also do more complicated stuff with them, e.g. showing a list box with a bunch of options instead of a text in it. You can access this functionality by querying the table that is returned by GUI.createDialog{...}. The table contains the following entries:

Code: Select all

dialog.title    -- The label object that is used for the title of the dialog
dialog.text     -- The text frame object that is used for the inner text of the dialog
dialog.controls -- If an actions table was provided (even if empty) the dialog has a horizontal layout object at the bottom where you can add buttons or other GUI objects
dialog.close    -- A function that will call the dialog if you call it

4. GUI objects
GUI objects in general offer various functions to query or change their state. On top of that some objects allow you to provide callback functions that will be called by the object at certain events. The general pattern for creating new GUI objects is to call a function on the parent object and provide it with various arguments defined within a table (this is some sort of named arguments that allow you to specify only what you need). In most cases this looks like that

Code: Select all

parent:addXXX{...}
with parent being a parent GUI object, for example GUI.getRoot(), and XXX indicating what type of object to create, e.g. Label.
While some object types accept special arguments the following are accepted by all of them:

Code: Select all    Reset

parent:addPanel{
id = 'myid',       -- GUI objects can have an id to find them later using GUI.get(id)
x = 10,            -- The x location relative to the parent's inner area's left side; 0 by default; negative values are interpreted as distance to the right side of the inner area of the parent
y = 10,            -- Same as x but for y location; relative to parent's inner area's top side
width = -10,       -- The width of the new object; by default the remaining space in the inner area of the parent; negative values are interpreted as distance to the right side of the parent area
height = -10,      -- Same as width for but for the height of the new object
onUpdate = function(self) print('called every frame') end  -- A function that will be called every frame, nil by default
}
Interactive Lua editor
None of these parameters is required so that you can usually write way shorter code than that. See the examples mentioned below to get an impression of how the actual code will look like.

The following chapters will introduce various types of GUI objects and their functionality.

1. Labels
image.png (20.48 KiB) Viewed 1812 times
Labels are one of the most simple GUI object types that are available. They render a provided line of text into their area. You can set an alignment for the text by using :setAlignment(x,y) with 0, 0.5 being the default alignment (aligned to the left and to the center vertically). If there's not enough horizontal space available to draw the text it will be compressed to match the area's width.

Code: Select all    Reset

local lbl = parent:addLabel{
text = 'Hello World!'
}
lbl:setAlignment(0, 0)       -- Set alignment to the top left corner
lbl:setText('Another text')  -- Set another text
print(lbl:getText())         -- Print the current content of the label
lbl:setColor(0, 0, 100)      -- Set the color to blue
lbl:setFont(Font.BIG)        -- Set a big font
Interactive Lua editor

2. Icons
image.png (5.62 KiB) Viewed 1812 times
As simple as labels are icons. For them you provide a frame that will be drawn in the area of the object.

Code: Select all    Reset

local icon = parent:addIcon{
icon = Icon.OK,
width = 26,
height = 26
}
Interactive Lua editor
By default, the actual frame will be drawn in the center of the icon object. If the icon object's area is too small to display the whole frame it will be scaled down uniformly to match the given area. You can alter the alignment of the frame within the object by using

Code: Select all

icon:setAlignment(0, 0)
The parameters of this function range from 0 to 1 meaning left to right respectively. The default alignment therefore is 0.5, 0.5. You can change the icon afterwards by using

Code: Select all

icon:setIcon(Icon.CANCEL)

3. Buttons
When it comes to user interaction you usually use buttons since they are easy to create and the user usually knows how to use them.

Code: Select all    Reset

local button = parent:addButton{
icon = Icon.CANCEL,
text = 'Test',
width = 0,
frameDefault = NinePatch.BLUE_BUTTON,
frameDown = NinePatch.BLUE_BUTTON_PRESSED,
onClick = function(self) Debug.toast('woah') end
}
Interactive Lua editor
If you don't provide an icon the text will be centered on the button. Otherwise it will be aligned to the left side of the button where also the icon will be displayed. If you provide a width smaller than the actual width of the button (e.g. width = 0) the button will automatically resize so that it matches the width that is needed to display its content. This behavior is special since most objects don't alter their own size.

By providing an isPressed callback function you can let the game know whether the button should be drawn as pressed right now (that is when the callback returns the value true). This can for example be used to implement a toggle button:

Code: Select all    Reset

local state = true
text = 'Switch',
onClick = function() state = not state end,
isPressed = function() return state end
}
Interactive Lua editor
You can skin the button by providing nine patch identifiers for the frameDefault and framePressed attributes. By providing the golden = true attribute you can tell the game to render the button in a golden fashion.

4. Canvas
The canvas object type is the most versatile GUI object type that's available. Not only does it allow you to draw the object on your own - if you don't it will be invisible - it also offers facilities to react to user input by providing an onClick callback function or by querying the canvas:getTouchPoint() function on it.

Code: Select all    Reset

local canvas = parent:addCanvas{
onDraw = function(self, x, y, w, h)
Drawing.setColor(0, 0, 0)
Drawing.drawRect(x, y, w, h)
Drawing.setColor(255, 255, 255)
Drawing.drawText('hello', x, y)
Drawing.reset()
end,
onClick = function(self)
Debug.toast('You clicked on me')
end
}
Interactive Lua editor
By using

Code: Select all

canvas:setTouchThrough(false)
you can disable event catching of the canvas which will effectively allow the user to still interact with GUI/the city that is behind the canvas. Since clicks on the canvas will still be reported to the onClick callback function this could be used to detect if the the user taps outside of a panel that is located within a transparent canvas that's filling the whole screen.

In fact other GUI objects that will be presented here were implemented using canvas objects because of its great flexibility. This includes the icon, slider and panel objects.

5. Panel
image.png (12.52 KiB) Viewed 1813 times
Panels are basically canvas objects whose onDraw function is already implemented so that it draws the default panel graphics (a nine patch image) of the game. It's equivalent to

Code: Select all    Reset

parent:addCanvas{
onDraw = function(self, x, y, w, h)
Drawing.drawNinePatch(NinePatch.PANEL, x, y, w, h)
end
}
Interactive Lua editor

6. Slider
Sliders are useful for easy input of numerical values. Sliders are implemented so that they don't hold the numerical value state on their own. Instead, you provide two callback functions getValue and setValue that will be used to query/set the value. This allows you for example to limit the allowed values to integers only by applying a rounding function in setValue. You provide the minimal/maximal value of the slider using the minValue/maxValue attribute respectively.

Code: Select all    Reset

local value = 0.5
minValue = 0,
maxValue = 10,
getValue = function() return value end,
setValue = function(v) value = v end
}
Interactive Lua editor
If you provide a function getText it will be used to transform the current numerical value into a text rather than displaying it as a percentage. The default implementation of getText looks like

Code: Select all    Reset

getText = function(value)
return ''..math.floor(100 * value + 0.5)..'%'
end
Interactive Lua editor

7. List box
A list box is a scrollable list of GUI objects. The objects are children of the list box object and automatically placed in a vertical way similar to the behavior of the layout object that is presented below. The background of the child objects gets automatically drawn to show a zebra pattern for better readability. By using mainly transparent child objects, e.g. canvases without a onDraw function, you can make that pattern visible.

Code: Select all    Reset

local listBox = parent:addListBox{
x = 10,
y = 10,
width = -10,
height = -10
}
for i = 0, 10 do
text = 'This is entry '..i,
width = -30
}
x = -35,
width = 30,
icon = Icon.OK,
onClick = function()
Debug.toast('Clicked on entry '..i)
end
}
end
Interactive Lua editor
Due to how this is implemented the child objects may not receive as many touch point event data as regular GUI objects would receive. However, clicks on touch sensitive objects should work as before which means that you can use buttons in a list box.

8. Text frame
The text frame can be used to display text like a label. However, text frames can display multi-line texts and wrap lines that are too long into the next line. If the text is too long/high to fit into the text frame it will be scrollable similar to a list box.

Code: Select all    Reset

local textFrame = parent:addTextFrame{
text = [[This is a long text
that can even span over multiple lines
This will scroll
if it
is long enough.]]
}
Interactive Lua editor
9. Text field
Text fields can be used to let the player enter textual information. It features a single line of text where the user can enter something. You can get and set the text of a text field by using textField:getText() and textField:setText() respectively.

Code: Select all    Reset

local textField = parent:addTextField{
text = 'Hello World',
height = 20
}
textField:setText('ok')
Debug.toast(textField:getText())
Interactive Lua editor
On some platforms the text field will use the native text field functionalities of the system. This is for example the case on Android. For that reason it may be displayed on top of everything else and still react to user input even if hierarchically hidden by another GUI object (e.g. a dialog). Because of that you have to ensure that you hide the text field manually using textField:setVisible(false) when it should not be displayed. Later you can make it visible again using true as parameter for the setVisible function.

It is recommended to use a height between 20 and 30 for the text field to ensure that it is compatible with the native implementations that may be used.

By providing an attribute password = true to the addTextField function you can indicate that the text of the text field is a password. Usually the text will then be displayed in a disguised way.

10. Layout
A layout object is an invisible GUI object whose purpose is the positioning of its children objects in a linear way. It can align them either in a horizontal (default) or vertical way (vertical = true). They are for example used by the game for the line of buttons in dialog windows that can be accessed by dialog.actions.

Code: Select all    Reset

local layout = parent:addLayout{
height = 30
}
layout:getFirstPart():addButton{text = 'A', width = 30}
layout:getFirstPart():addButton{text = 'B', width = 30}
layout:getCenterPart():addButton{text = 'C', width = 30}
layout:getLastPart():addButton{text = 'D', width = 30}
layout:getLastPart():addButton{text = 'E', width = 30}
Interactive Lua editor
A layout offers the methods :getFirstPart(), :getCenterPart() and :getLastPart(). Depending on which part you append children to the alignment will differ. For example in a dialog actions line you would append buttons that should be on the left side to the first part and buttons that should be placed on the right side to the last part. In this specific case (that is when adding objects) you can omit :getFirstPart() for convenience.

When using a layout you usually cannot omit the width/height specification for child objects in the direction of the alignment since the inner area size of the layout doesn't take occupied space into account.

Menus are an easy way to offer a set of actions to the user at a certain event, e.g. when the user pressed a button. In that case you would create the menu in the onClick function of that button and provide the button as source of the menu.

Code: Select all    Reset

GUI.createMenu{
source = parent,          -- Spawn the menu from this object, e.g. useful if a button should trigger the menu visually

-- A table that contains the set of actions that should be offered in the menu
actions = {
{
icon = Icon.OK,       -- An icon for the menu entry
text = 'A',           -- The text for the menu entry
onClick = function()  -- A function that will be called when the menu items gets clicked
Debug.toast('yo')
end
},
{
icon = Icon.CANCEL,
text = 'B',
enabled = false       -- This entry is disabled and can therefore not be clicked
},
{},                     -- This is a separator for grouping of actions
{
icon = Icon.CLOSE,
text = 'Close',
onClick = ...
}
}
}
Interactive Lua editor
If you don't have a source GUI object you can alternatively specify a rectangle using the attributes x, y, width, height. The menu will then be located in a position so that it looks as if that area has spawned the menu.

5. Resources
The game features some tables to make access to certain resources like images and fonts of the game easier.

1. Icon
The Icon table is a table that contains various images that are used by the game. You can use them e.g. like that:

Code: Select all    Reset

Drawing.drawImage(Icon.OK, 0, 0)
GUI.createDialog{ icon = Icon.CITY, ... }
parent:addIcon{ icon = Icon.CANCEL, ... }
Interactive Lua editor
See the GUI example below for a list of all available keys in the Icon table.

2. Font
The game features 3 different fonts. You can use them like that:

Code: Select all    Reset

Drawing.drawText('Hello', 0, 0, Font.SMALL)
label:setFont(Font.BIG)
Interactive Lua editor

3. NinePatch
image.png (14.46 KiB) Viewed 1810 times
A nine patch is a set of 9 images that belong together and are used to fill a rectangle of arbitrary size. For that, the corner frames are drawn unscaled while the edge and center frames are scaled so that there are no gaps. A nine patch is usually specified by the first frame of the collection. You can define your own nine patches by loading the 9 frames in the correct order and using the first frame to draw it.
You can use Drawing.drawNinePatch(frame, ...) to draw a nine patch.
See the GUI example below for available nine patches in the game. They can be accessed via the NinePatch table:

Code: Select all

Drawing.drawNinePatch(NinePatch.PANEL, x, y, w, h)

4. Translation
For convenience you can access localized strings of the game. For example

Code: Select all

Translation.control_ok
would return the translated "ok" string for the current language. The Translation.key expression is basically an alias for TheoTown.translate('key'). See the public translation files for available keys. Your plugin can define its own, custom translations, see here on how to do that.

6. Special cases
This chapter sheds some lights on special places where you may want to integrate some own UI.

1. City creation screen

Code: Select all    Reset

function script:enterStage(name)
if name:startsWith('CreateCityStage') then
local line = GUI.get('pageControl')
w = 0,
text = 'My plugin button',
icon = Icon.SETTINGS,
onClick = function()
Debug.toast('Would open a dialog now ')
end
}
cmd:setChildIndex(1)
end
end
Interactive Lua editor
By listening for specific stage names in the script:enterStage function you can detect whether the user e.g. just entered a region or city creation screen. You can then access the bottom line of the screen (where the buttons are) by its id "pageControl" and for example add your own buttons to it. In the example code above I use cmd:setChildIndex(1) to place the child before the existing button "Continue" (which will then have child index 2 instead of 1).

As of right now the names for the create region/city stages are "CreateCityStageX;region=Y" with X being 1 or 2 depending on which page the user is on right now and Y being true for regions and false for cities. This approach will also work for other "page" based screens in the game. You can find out their names by Debug.toast'ing the names provided to script:enterStage(name).

2. Adding a button to the sidebar
image.png (16.18 KiB) Viewed 1752 times
Since the sidebar layout object can be found by its id "sidebarLine" you can append your own buttons to it.

Code: Select all    Reset

function script:buildCityGUI()
-- Let's append the button to the sidebar line
local sidebar = GUI.get('sidebarLine')
local size = sidebar:getFirstPart():getChild(2):getWidth()
width = size,
height = size,
icon = Icon.OK,
frameDefault = Icon.NP_BLUE_BUTTON,
frameDown = Icon.NP_BLUE_BUTTON_PRESSED,
onClick = function(self) Debug.toast('Clicked!') end
}
end
Interactive Lua editor

3. Altering the tile information dialog window
If you want to alter the information dialog window that's displayed when the player taps on something, e.g. a building, you can do that by implementing the script:finishInformationDialog(...) function.

Code: Select all    Reset

function script:finishInformationDialog(x, y, _, dialog)
dialog.controls:getLastPart():addButton{    -- Add a button to the controls layout of the dialog
icon = Icon.TREE,
text = 'Select trees (X)',
width = 0,        -- Adjust button size to content
onClick = function(self)
-- Do something, e.g. show another dialog
end
}
end
Interactive Lua editor

7. Examples
This chapter presents some example plugins you can use for reference when starting your own plugins featuring GUI

1. Tree Planter Tool
image.png (19.09 KiB) Viewed 1810 times
The tree planter tool is a plugin that is integrated into the game. The code of it is open source and can be used for reference for creating your own tools/UI.

2. Plugin Creator Tools GUI Example
The Plugin Creator Tools plugin (you can find it in the plugin store) features this plugin tool that offers a wide range of GUI objects. Have a look at the implementation of the GUI tool to learn how it works.
=^._.^= ∫

LobbyFan
TheoTown Councillor
Reactions:
Posts: 5
Joined: Mon Feb 01, 2016 10:15
Plugins: Show

### Re: GUI Compendium

Hast du well done

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

These will change the whole game

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

How can i made Sliders be Whole number? Caused i want it to be a quantity value

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

Excerpt from the tree tool:

Code: Select all    Reset

  line = layout:addCanvas{h=lh}
x=lw,
minValue=minBrushSize,
maxValue=maxBrushSize,
getValue=function() return brushSize end,
setValue=function(v) brushSize = math.floor(v+0.5) end,
getText=function(v) return ''..math.floor(v+0.5) end
}
Interactive Lua editor
math.floor will round the number down, so math.floor(v+0.5) will round down only if the fraction was below 0.5
=^._.^= ∫

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

Btw @Lobby how do i get the center part of ListBox Label?also the center part of the GUI parent.
I want to display Listbox label at the center of its canvas,im afraid to use X and Y because i think it will change in different resolution.

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

What exactly do you mean with center part of ListBox Label? Maybe sketch something for better understanding
=^._.^= ∫

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

If i defined x and y axis for positioning labels inside ListBox "listbox:addLabel{x=x,y=y,text=""}" it will remain the same position in different screen resolution?

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

When you add something to a listbox all it should have is a height because positioning will be handled by the listbox (so that it can be scrolled). What you may want to do is to put a panel or canvas with a specific height into the listbox first and then adding your label to that panel/canvas. Yes, the position will be independent of screen resolution, as long as you use numbers for you sizes and locations.
=^._.^= ∫

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

Thanks btw how can i close panels from your script :

Code: Select all    Reset

parent:addCanvas{
onDraw = function(self, x, y, w, h)
Drawing.drawNinePatch(NinePatch.PANEL, x, y, w, h)
end
}
Interactive Lua editor
?

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

What do you mean by close? Do you want to add a close button that removes the dialog when pressed? That can be done by placing a button manually on the panel.
=^._.^= ∫

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

Ah yeah but my thought was, it will closed when users tap in any part of the panel

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

you can do that by doing the following:

Code: Select all    Reset

  local root = GUI.getRoot()
x = 20,
y = 20,
width = 100,
height = 30,
onClick = function(p) p:delete() end
}
Interactive Lua editor
=^._.^= ∫

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

Lovely

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

@Löbby is there any way to change the parent color of the GUI
.createDialog{}? i'd experementing to put onDraw function but it's not work a i thougth XD and if i use the main Gui root i gonna have conflict about the casting of it specially the coordinates in some other resolution.

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

ian
Supporter
Reactions:
Posts: 88
Joined: Sat Apr 04, 2020 17:36
Location: Indonesien
Plugins: Show
Version: Beta

### Re: GUI Compendium

rjroldan1 wrote:
Wed Dec 02, 2020 6:55
@Löbby is there any way to change the parent color of the GUI
.createDialog{}? i'd experementing to put onDraw function but it's not work a i thougth XD and if i use the main Gui root i gonna have conflict about the casting of it specially the coordinates in some other resolution.
I think you can't change the default dialog color, because the onDraw function is already set.

To set the coordinates to still centered, you can use the width or height of the root gui.

GUI.getRoot():getWidth() [or height] / 2 - Width [or height] of your dialog / 2

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

Yeah, you would have to implement your own dialog or try to add a GUI object that covers it and draws something else. An easier option would probably be to use privileged placing features to change look of dialogs in general.
=^._.^= ∫

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

Lobby wrote:
Thu Dec 03, 2020 23:29
Yeah, you would have to implement your own dialog or try to add a GUI object that covers it and draws something else. An easier option would probably be to use privileged placing features to change look of dialogs in general.
What are the Coordinates? Btw belated happy birthday, i didn't know we have the same birthday

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation

Lobby
Developer
Reactions:
Posts: 3631
Joined: Sun Oct 26, 2008 12:34
Plugins: Show
Version: Beta

### Re: GUI Compendium

Thanks!

Although it's kind of a hack you can actually get the GUI object of the dialog window by calling dialog.content:getParent()

Here's how it would look like to add a color to a dialog:

Code: Select all    Reset

local function decorateDialog(dialog)
local panelRoot = dialog.content:getParent()
local pl, pt, pr, pb = panelRoot:getPadding()   -- Extract padding information to place overlay panel correctly

local panelOverlay = panelRoot:addPanel{onDraw = function(self, x, y, w, h)
Drawing.setColor(100, 255, 200)
Drawing.drawNinePatch(NinePatch.PANEL, x, y, w, h)  -- Here the drawing of the overlay happens
end}

panelOverlay:setChildIndex(1)                   -- Ensure that the overlay is drawn directly on top of the window before other stuff
panelOverlay:setPosition(-pl, -pt)
panelOverlay:setSize(panelOverlay:getWidth()+pl+pr, panelOverlay:getHeight()+pt+pb)
end

function script:buildCityGUI()
local dialog = GUI.createDialog{
icon = Icon.SETTINGS,
title = 'Title',
text = 'Text',
width = 180,
height = 100,
closable = true,
pause = true,
actions = {
{icon = Icon.CANCEL, text = Translation.control_cancel},
{icon = Icon.OK, text = Translation.control_ok, golden = true}
}
}

decorateDialog(dialog)
end
Interactive Lua editor
The result:
=^._.^= ∫`

rjroldan1
Inhabitant of a Megalopolis
Reactions:
Posts: 644
Joined: Mon Jul 17, 2017 16:16
Location: Philippines
Plugins: Show
Contact:

### Re: GUI Compendium

<..>

thanks so perfect 100%

.╔═╗─────────────╔╗────────
║╬║─╔╗╔╦╗╔═╗╔╗─╔╝║╔═╗─╔═╦╗
║╗╣─╠╣║╔╝║╬║║╚╗║╬║║╬╚╗║║║║
╚╩╝╔╝║╚╝─╚═╝╚═╝╚═╝╚══╝╚╩═╝
───╚═╝────────────────────
T.P.C.
Theotown Philippine Corporation