[solved] GUI: textbox.state_focussed
Moderator: Forum Moderators
-
- Posts: 1207
- Joined: August 26th, 2018, 11:46 pm
- Location: A country place, far outside the Wire
[solved] GUI: textbox.state_focussed
This is a stupid little example, just for learning. I have a slider and a textbox, and I want each to update the other when they are changed. The slider works (text box updates when slider moves), but I have some issues with the textbox.
At first, I just used
that worked more or less, but it moved the slider every time I made ANY change to the text box. For instance, if I typed in 9999, the slider would move to 9, then 99, and then do nothing because 999>gold.
What I want is to let the user finish typing in the text_box, then evaluate the input, then move the slider (or popup an error) as necessary. The only thing I could find that looked like it might work was to check for focus. In hindsight, this may not make any sense, as you may not be able to fire on_modified unless the tb is focused (or focussed, never seen that spelling before). Anyway, devdocs says state_focussed is valid for text_box, but "error scripting/lua: invalid property of 'N4gui28text_boxE' widget :state_focussed"
1) Is text_box.state_focussed valid?
2) Does this approach make any sense, and/or is there a better way to do this (wait to update the slider until user is finished with input and input is validated).
3) I'm not sure about my approach to checking if input is a number (tonumber, then check the result???). Minimal testing seems to look okay, but I'm suspicious. assert(type(dialog.gold_tb.text) == "number") perhaps? Never used assert, but it looks promising.
4) Any comments on my attempt to use short circuit evaluation like this?
Code: Select all
function wesnoth.wml_actions.current_test_gui()
local dialogDefinition = {
wml.tag.tooltip { id = "tooltip_large" },
wml.tag.helptip { id = "helptip_large" },
wml.tag.grid {
wml.tag.row {
wml.tag.column {
wml.tag.label { label = _"How much gold will you pay for this old rusty sword?" }
}
},
wml.tag.row {
wml.tag.column {
horizontal_grow = true,
grow_factor = 1,
wml.tag.slider {
id = "gold_sl",
right_offset = 120,
minimum_value = 0,
maximum_value = wesnoth.sides[wesnoth.current.side].gold,
value = math.floor(wesnoth.sides[wesnoth.current.side].gold/2)
}
}
},
wml.tag.row {
wml.tag.column {
wml.tag.text_box {
id = "gold_tb",
label = tostring(math.floor(wesnoth.sides[wesnoth.current.side].gold/2))
}
}
},
wml.tag.row {
wml.tag.column {
wml.tag.text_box {
id = "gold_tb",
label = tostring(math.floor(wesnoth.sides[wesnoth.current.side].gold/2))
}
}
},
wml.tag.row {
wml.tag.column {
wml.tag.button {
id = "ok",
label = _"OK"
}
}
}
}
}
local function preshow(dialog)
local function show_input()
wesnoth.interface.add_chat_message(_"You chose " .. dialog.gold_sl.value .. _" with the slider")
wesnoth.interface.add_chat_message(_"You entered " .. tostring(dialog.gold_tb.text) .. _" in the text_box")
end
dialog.ok.on_button_click = show_input
dialog.gold_sl.on_modified=function()dialog.gold_tb.text = tostring(dialog.gold_sl.value)end
local function text2string()
--if dialog.gold_tb.state_focussed then return nil end
local input = tonumber(dialog.gold_tb.text)
if type(input) ~= "number" then
wesnoth.message("NO!!!")
else
if input > 0 and input <= wesnoth.sides[wesnoth.current.side].gold then
dialog.gold_sl.value=input
end
end
end
--dialog.gold_tb.on_modified = text2string() -- core dumps bfw
--dialog.gold_tb.on_modified = text2string -- works, but kludgy
if wesnoth.current_version() >= wesnoth.version "1.17.0" then
wesnoth.print_attributes(dialog.gold_sl)
gui.show_lua_console()
end
end
gui.show_dialog(dialogDefinition,preshow)
end
Code: Select all
dialog.gold_tb.on_modified = text2string
What I want is to let the user finish typing in the text_box, then evaluate the input, then move the slider (or popup an error) as necessary. The only thing I could find that looked like it might work was to check for focus. In hindsight, this may not make any sense, as you may not be able to fire on_modified unless the tb is focused (or focussed, never seen that spelling before). Anyway, devdocs says state_focussed is valid for text_box, but "error scripting/lua: invalid property of 'N4gui28text_boxE' widget :state_focussed"
1) Is text_box.state_focussed valid?
2) Does this approach make any sense, and/or is there a better way to do this (wait to update the slider until user is finished with input and input is validated).
3) I'm not sure about my approach to checking if input is a number (tonumber, then check the result???). Minimal testing seems to look okay, but I'm suspicious. assert(type(dialog.gold_tb.text) == "number") perhaps? Never used assert, but it looks promising.
4) Any comments on my attempt to use short circuit evaluation like this?
Code: Select all
dialog.gold_tb.on_modified = function()return not dialog.gold_tb.state_focussed and text2string() end
Last edited by white_haired_uncle on January 19th, 2024, 10:35 am, edited 1 time in total.
Speak softly, and carry Doombringer.
Re: GUI: textbox.state_focussed
No the only attributes you can set/set via the lua widget objects are described in https://wiki.wesnoth.org/LuaAPI/types/widgetwhite_haired_uncle wrote: ↑January 18th, 2024, 7:25 pm
that worked more or less, but it moved the slider every time I made ANY change to the text box. For instance, if I typed in 9999, the slider would move to 9, then 99, and then do nothing because 999>gold.
What I want is to let the user finish typing in the text_box, then evaluate the input, then move the slider (or popup an error) as necessary. The only thing I could find that looked like it might work was to check for focus. In hindsight, this may not make any sense, as you may not be able to fire on_modified unless the tb is focused (or focussed, never seen that spelling before). Anyway, devdocs says state_focussed is valid for text_box, but "error scripting/lua: invalid property of 'N4gui28text_boxE' widget :state_focussed"
1) Is text_box.state_focussed valid?
I don't think that is possible currently. could file a feature request for more callbacks, but you'd need to know what exactly do you want, meaning when exactly do you want the slider to update, also since we are more or less in a feature freeze for 1.17 it probably won't happen soon.white_haired_uncle wrote: ↑January 18th, 2024, 7:25 pm 2) Does this approach make any sense, and/or is there a better way to do this (wait to update the slider until user is finished with input and input is validated).
assert looks even more wrong for this, assert only gives an error when the condition is wrong, its a debug tool not something for control progam flow.white_haired_uncle wrote: ↑January 18th, 2024, 7:25 pm 3) I'm not sure about my approach to checking if input is a number (tonumber, then check the result???). Minimal testing seems to look okay, but I'm suspicious. assert(type(dialog.gold_tb.text) == "number") perhaps? Never used assert, but it looks promising.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
- Celtic_Minstrel
- Developer
- Posts: 2235
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: GUI: textbox.state_focussed
The properties documented in the devdocs mainly describe the WML format for defining a widget. It means that you can put awhite_haired_uncle wrote: ↑January 18th, 2024, 7:25 pm Anyway, devdocs says state_focussed is valid for text_box, but "error scripting/lua: invalid property of 'N4gui28text_boxE' widget :state_focussed"
[state_focused]
tag in your textbox definition, but doesn't mean anything with respect to the Lua API.There's no reason to usewhite_haired_uncle wrote: ↑January 18th, 2024, 7:25 pm 3) I'm not sure about my approach to checking if input is a number (tonumber, then check the result???). Minimal testing seems to look okay, but I'm suspicious. assert(type(dialog.gold_tb.text) == "number") perhaps? Never used assert, but it looks promising.
assert
, as that raises an error that terminates the script entirely, (or if pcall
was used, winding back to that point in the script). Your description of the approach is fine, however. The tonumber
function returns nil
if the input is not a number, so one approach would be:Code: Select all
local n = tonumber(dialog.gold_tb.text)
if n then
dialog.gold_sl.value = n
end
type
function however will not work, as dialog.gold_tb.text
is always a string even if it happens to be numerical.Even ignoring the fact thatwhite_haired_uncle wrote: ↑January 18th, 2024, 7:25 pm 4) Any comments on my attempt to use short circuit evaluation like this?Code: Select all
dialog.gold_tb.on_modified = function()return not dialog.gold_tb.state_focussed and text2string() end
state_focussed
is not a valid attribute, what you're doing here makes no sense. I'm not 100% certain, as the documentation could be missing something, but I don't think on_modified
has a return value in the first place. So it would make more sense to write that as an if statement: if not dialog.whatever then text2string() end