Difference between revisions of "LuaAPI/gui/example"
(Example of creating a custom GUI2 dialog from Lua; probably needs some work but is basically complete and functional) |
(→The Implementation: Update to synchronize the dialog result) |
||
Line 218: | Line 218: | ||
end | end | ||
local dialog_wml = wml.load "character_select.cfg" | local dialog_wml = wml.load "character_select.cfg" | ||
− | if -1 == gui.show_dialog(wml.get_child(dialog_wml, 'resolution'), pre_show, post_show) then | + | wml.variables.selected_character = wesnoth.sync.evaluate_single(function() |
− | + | local result = false | |
− | + | if -1 == gui.show_dialog(wml.get_child(dialog_wml, 'resolution'), pre_show, post_show) then | |
− | + | result = characters[selection].id | |
− | end | + | end |
+ | return {selected = result} | ||
+ | end).selected | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 23:38, 5 July 2021
Using the gui.show_dialog function, you can create pretty much any custom dialog you want using the standard GUI2 markup that constructs most of Wesnoth's built-in UIs. This page is dedicated to a fully-working example that demonstrates some of the intricacies of the system.
We're going to create a character selection dialog, similar to the tutorial dialog, but with more than two choices. Since there will be several choices, we'll use a listbox. In order to be as user-friendly as possible, we'll register an ActionWML tag that calls the dialog and stores an ID in a variable.
The Dialog WML
First, you need to write your GUI2 WML. We recommend putting the WML in a .cfg file, in a [resolution] tag. Though the resolution tag is not required, using it means you could have multiple versions of the dialog in the same file (for example, a different layout for small screens) and choose between them, if the API is updated to support this in the future (which is likely).
The remainder of this example will assume this code is pasted into a file called "Your_Addon/character_select.cfg".
#textdomain wesnoth-gui-example
{gui/macros} # Built-in macros that are useful for GUI WML; not used in this example
[resolution]
definition = "default"
automatic_placement = true
vertical_placement = "center"
horizontal_placement = "center"
maximum_width = 800
maximum_height = 600
[linked_group]
id = "image"
fixed_width = true
[/linked_group]
[linked_group]
id = "item"
fixed_width = true
[/linked_group]
[tooltip]
id = "tooltip"
[/tooltip]
[helptip]
id = "tooltip"
[/helptip]
[grid]
[row]
grow_factor = 0
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
id = "title"
definition = "title"
[/label]
[/column]
[/row]
[row]
grow_factor = 0
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
[scroll_label]
id = "message"
definition = "default"
[/scroll_label]
[/column]
[/row]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = true
vertical_grow = true
border = "all"
border_size = 5
[listbox]
id = "characters"
definition = "default"
[list_definition]
[row]
[column]
vertical_grow = true
horizontal_grow = true
[toggle_panel]
definition = "default"
return_value_id = "ok"
[grid]
[row]
[column]
grow_factor = 0
horizontal_grow = false
border = "all"
border_size = 5
[image]
id = "image"
definition = "default"
linked_group = "image"
[/image]
[/column]
[column]
grow_factor = 0
horizontal_grow = false
border = "all"
border_size = 5
[label]
id = "item"
definition = "default"
linked_group = "item"
[/label]
[/column]
[column]
grow_factor = 1
horizontal_grow = true
border = "all"
border_size = 5
[label]
id = "description"
definition = "default"
linked_group = "item"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
[/column]
[/row]
[row]
grow_factor = 0
[column]
horizontal_alignment = "right"
[grid]
[row]
grow_factor = 0
[column]
border = "all"
border_size = 5
horizontal_alignment = "right"
[button]
id = "ok"
definition = "default"
label = _ "OK"
[/button]
[/column]
[column]
border = "all"
border_size = 5
horizontal_alignment = "right"
[button]
id = "cancel"
definition = "default"
label = _ "Cancel"
[/button]
[/column]
[/row]
[/grid]
[/column]
[/row]
[/grid]
[/resolution]
The Implementation
local _ = wesnoth.textdomain "wesnoth-gui-example"
-- Some sample data for the dialog
local characters = {
{
id = "konrad",
name = _ "Konrad",
image = "units/konrad-fighter.png",
description = _ "A bright young prince, skilled with the sword!"
},
{
id = "lisar",
name = _ "Li'sar",
image = "units/human-princess.png~RC(magenta>red)",
description = _ "A bright young princess, skilled with the sword!"
},
{
id = "delfador",
name = _ "Delfador",
image = "units/human-magi/elder-mage.png~RC(magenta>red)",
description = _ "A jaded old mage, wields powerful lightning magic!"
},
{
id = "kalenz",
name = _ "Kalenz",
image = "units/elves-wood/high-lord.png~RC(magenta>green)",
description = _ "A jaded old mage, wields powerful lightning magic!"
},
-- Add more characters here, if you want!
}
function wesnoth.wml_actions.select_character(cfg)
-- If you uncomment this line you can specify the character options directly in the WML tag.
-- Just add a [character] subtag for each character with id, name, image, and description.
--local characters = wml.child_array(cfg, 'character')
local selection = 1
function pre_show(self)
-- Set the title and text.
-- Normally you'd do this in the WML if they're static text, but for this example we show how you can update them dynamically if needed.
self.title.label = _ "Select a Character"
self.message.label = _ "Before you get started, you need to select a character."
-- Look up the list box by its ID
local listbox = self.characters
for i, character in ipairs(characters) do
-- Add a new blank item to the list
local new_item = listbox:add_item()
-- The new item has "image" and "item" subwidgets,
-- so set their values appropriately
new_item.image.label = character.image
new_item.item.label = character.name
new_item.description.label = character.description
end
listbox.selected_index = selection
end
function post_show(self)
selection = self.characters.selected_index
end
local dialog_wml = wml.load "character_select.cfg"
wml.variables.selected_character = wesnoth.sync.evaluate_single(function()
local result = false
if -1 == gui.show_dialog(wml.get_child(dialog_wml, 'resolution'), pre_show, post_show) then
result = characters[selection].id
end
return {selected = result}
end).selected
end