![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | grymjack |
I have a large series of OptionButtons. I can load in a saved state which sets the displayed text values on the option buttons. However, after the load, if the user presses on the OptionButton to change the selection, the list that displays always shows the default ‘0’ position as the one being selected, regardless of the text value displayed. Is there an easy way to align the selected index value of the OptionButton with the displayed text of that option? Thank you
I haven’t tested it, but I assume simply setting the selected
property of each button appropriately (from your saved state) should do what you want. Have you tried that?
jgodfrey | 2022-12-09 18:00
The saved state just saves the text value of the OptionButton, not the index position. The reason for this being the contents of the OptionButtons can shift, so the index numbers can also change. The selected property requires an index number.
item_selected ( int index )
Emitted when the current item has been changed by the user. The index of the item selected is passed as argument.
grymjack | 2022-12-09 19:55
Looking at the OptionButton docs, I see a few things that, when used together, should get you what you need:
- You can specify an
id
for each item as it’s added (add_item()
) - You can get an item’s
index
from itsid
(get_item_index()
) - You can set the selected item via its
index
(select()
)
Armed with that, I’d do something like this:
-
As items are added to the
OptionButton
, assign (and remember) a uniqueid
. -
When you save your state, record the
id
as appropriate -
When you restore your save state,
select
the previously selected item viaget_item_index()
andselect()
- based on the storedid
jgodfrey | 2022-12-09 20:04
Hmmmmm…I am terrible at explaining these things. There are two steps involved. First, when the screen is first opened. That’s when the OptionButtons are first loaded. The player can then chose (not required) to ‘Load’ a previously saved design rather that work on a new one.
The OptionButtons are fed from a SQLite database. As the player advances in the game, they will have access to more and more entries that will appear in the different OptionButton lists. Below is example code where I use ‘additem’ to populate the OptionButton control (1 of 27). Are you saying that when I do the initial ‘additem’ that populates the OptionButtons, I should track the ‘index’ created at that time and then cross reference if they chose to ‘Load’ a saved design?
# load other vessel components
sql_string = "SELECT * FROM componentsvessel order by componenttitle ASC;"
result = funct.executesqlstring(sql_string)
for row in range(0, result.size()):
# testing for component that should be displayed here
if (component_display_test(result[row]['componenttitle']) == true):
# testing for owner technology for this component to be on the list
if (funct.test_player_technology(owner_number, result[row]['componentcode']) == true):
component1_option_button.add_item(result[row]['componenttitle'])
grymjack | 2022-12-09 22:55
The only way I have been able to think of is after loading the ‘Saved’ design to step through all of the OptionButtons and find the entry that corresponds to the text value and then ‘select’ that entry based on its ‘index’. That way the selected entry will correspond with the text value of the control. I appreciate you sticking with me here.
grymjack | 2022-12-09 23:02
First, I haven’t tried any of this… My suggestions are only from a quick look at the docs.
- To select an item programmatically (which is what you ultimately need to do here I think…), you need it’s INDEX (
select(index)
). - You’ve said that the indices can change, so that’s not a stable mechanism to track a given item by.
- You can specify a unique ID for each item when you add it (
add_item("my item", 23)
) for example. - You can get an item’s Index from its ID (
get_item_index(id)
)
So, if you assign a unique ID to each item, and store that ID in your DB, you can can map it to that item’s INDEX in a given OptionButton
, and from there, you can select that item via code.
However, maybe there’s an easier way for you to do this based on the item’s TEXT value - which is apparently what you already have stored… Here’s an example:
func _ready():
$OptionButton.add_item("Item 1")
$OptionButton.add_item("Item 2")
$OptionButton.add_item("Item 3")
$OptionButton.add_item("Item 4")
$OptionButton.add_item("Item 5")
$OptionButton.add_item("Item 6")
var item_to_select = "Item 3"
for i in $OptionButton.get_item_count():
var text = $OptionButton.get_item_text(i)
if text == item_to_select:
$OptionButton.select(i)
break
The above code just iterates through all items in a given OptionButton
looking for one with a specific text string. Once that’s found, that item is selected via its index.
jgodfrey | 2022-12-09 23:33
Ah, I missed your above comment, but that’s exactly what the sample code is doing…
jgodfrey | 2022-12-09 23:47
But, to be clear, my original thought (which still seems valid) is to assign (and store) a unique ID with each item. Then, you can get from that ID to the item’s INDEX, and using that INDEX, select it…
jgodfrey | 2022-12-09 23:49
Further, if you opt to do the text-matching thing, I’d relegate all of that busy work to a dedicated function. Something like select_optionbutton_item_from_text(optionbutton, item_text)
.
Then, pass in the OptionButton
and text
of the item of interest and let it do its thing.
jgodfrey | 2022-12-09 23:52
Sounds like a plan. Thanks for the help! If you want t make your code chunk a separate answer I will upvote it!
grymjack | 2022-12-10 01:56