Ren'Py [SOLVED] How to make it so textbutton isn't permanently highlighted/selected after click?

Mukashi

Food Truck Story
Game Developer
Jan 29, 2021
100
878
Hello!
I am looking to create a textbutton in my Options menu that resets all player preferences to default upon click.
Python:
textbutton _("Reset To Default"):
    action [SetVariable("preferenceX", "True"), SetVariable("preferenceY", "True")]
This textbutton works to reset the preference values, but upon clicking once it becomes permanently highlighted.
I would like it so even after clicking, the textbutton will still change colors when hovering/unhovering to indicate it can be clicked again.

Is there something having to do with 'selected' or 'sensitive' expressions I need? Or does it have to do with style?
I'm still very beginner level at learning Ren'Py, so I apologize in advance if there is a very easy solution I'm missing.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
Yes. As you suspected, it's to do with selected, specifically probably selected_idle.

If you check the documentation, you'll see that part of it reads as:

Code:
selected
   An expression that determines whether the button is selected or not.
   This expression is evaluated at least once per interaction.
   If not provided, the action will be used to determine selectedness.

It's that final line that matters here.
Because you haven't specifically stated a function/expression to be evaluated (and you probably shouldn't), RenPy has done it's own thing.
In this case, "it's own thing" depends on the action taken.
Now this is where it become a bit of a leap of faith, because if there's any documentation covering it... I've never found it.
But... action SetVariable() is flagged as selected if ANY of the variables being set are already those values (I just tested it, any single variable that matches - flags it as selected).

At that point, you're locked into whatever the style implicitly or explicitly specifies.

I tested a quick script with this code:

Python:
default unk_variable_1 = 0
default unk_variable_2 = 0

screen screen2():
    modal True

    textbutton "Set unknown variable #1":
        style "screen2_button"
        action [SetVariable("unk_variable_1", 6), SetVariable("unk_variable_2", 8)]


style screen2_button_text:
    idle_color "#880000"   # dark red
    hover_color "#FF0000"   # bright red
    selected_idle_color "#006600"   # dark green
    selected_hover_color "#00FF00"   # bright green

Then a quick script to launch my test screen.

The end result is that if the action SetVariable() is mismatched, the color alternates between dark and bright red. If any values match, then it uses dark and bright green.

I suspect the answer you're going to want to use is to override the style so the selected_idle_color and selected_hover_color are the same as the idle_color and hover_color.

Edit: Though now I see it, Anne's solution is a much better solution to your problem.
 
Last edited:
  • Like
Reactions: Mukashi

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,284
At that point, you're locked into whatever the style implicitly or explicitly specifies.
Is he really ?

The button property works as a boolean expression, and overwrite the decision made by action. If the expression is True the button is shown as selected, and if the expression is False the button is shown as not selected. But, well, expression can be simplified to their most basic form, like by example the case of while True, or similar, to create an endless loop.
Since it's a reset button, it should never be selected, what should be achieved with:
Code:
textbutton _("Reset To Default"):
    action [SetVariable("preferenceX", "True"), SetVariable("preferenceY", "True")]
    selected False
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
Code:
textbutton _("Reset To Default"):
    action [SetVariable("preferenceX", "True"), SetVariable("preferenceY", "True")]
    selected False

D'oh.

That as an alternative seems so obvious now I see it. Cheers Anne.
I got so caught up with the answer I ended up with, I forgot that RenPy usually has at least one other way of doing everything. And realistically, because of the usage - your answer is much better.
 
  • Like
Reactions: Lou111 and Mukashi

Mukashi

Food Truck Story
Game Developer
Jan 29, 2021
100
878
Is he really ?

The button property works as a boolean expression, and overwrite the decision made by action. If the expression is True the button is shown as selected, and if the expression is False the button is shown as not selected. But, well, expression can be simplified to their most basic form, like by example the case of while True, or similar, to create an endless loop.
Since it's a reset button, it should never be selected, what should be achieved with:
Code:
textbutton _("Reset To Default"):
    action [SetVariable("preferenceX", "True"), SetVariable("preferenceY", "True")]
    selected False
D'oh.

That as an alternative seems so obvious now I see it. Cheers Anne.
I got so caught up with the answer I ended up with, I forgot that RenPy usually has at least one other way of doing everything. And realistically, because of the usage - your answer is much better.
Thank you both for your help, that solved it :giggle: