Ren'Py Changing color in menu choices

monsternn

Newbie
Nov 3, 2017
46
17
So, i wanted to change menu choices color so i did
menu:{color=#44B3EA}Text {/color}
However, when this choice not available its still the same color, when standard ones are greyed out - how to do the same with this?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
menu: lines end up using a default screen called choice.

screen choice(): includes lots of formatting and positioning elements, but the bit you're most likely interested in is the style lines.

The styles control how various elements of the menu appear. From the background "button" that make up each menu item to the text that appears on that button.

So your starting place will be screens.rpy. With maybe a little reading at

A more complex version of what you are talking about is covered in this video:


Might be worth a look.
 

monsternn

Newbie
Nov 3, 2017
46
17
menu: lines end up using a default screen called choice.

screen choice(): includes lots of formatting and positioning elements, but the bit you're most likely interested in is the style lines.

The styles control how various elements of the menu appear. From the background "button" that make up each menu item to the text that appears on that button.

So your starting place will be screens.rpy. With maybe a little reading at

A more complex version of what you are talking about is covered in this video:


Might be worth a look.
Well, the thing is, its all about common changes for all the controls, i have various ccolors for various choices its not like i change color for all at once so this approach will not help.
I ask about specific changes for specific choices, not one for all.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
Depends which part of the color you want to change.

The text is easy to change...

Python:
    menu:
        "{color=#FF0000}Choice 1{/color}":
            "This is choice 1"

        "Choice 2":
            "This is choice 2"

If you were looking to do some sort of hint system that can be switched off and on again...

Python:
default hint = "#008000"

label start:

    menu:
        "Do you want to use hints?"
        "Yes":
            $ hint="#008000"
        "No":
            $ hint = ""

    menu:
        "[hint]Choice 1":
            "This is choice 1"

        "Choice 2":
            "This is choice 2"

That just the text color though. If you want to change other things, you need to mess with the screen code.

Here's a very rough example I based on a previous question someone had a long time ago.

In this case, I can set a variable on each choice line called "hint". If the choice hint is true AND a variable called hints_active is also true, then the word "(hint) " is displayed before the choice on screen.

Whilst this is very similar to my previous example of colors, the major difference is the implementation. The big difference being that you can override ANY of the screen code or styles to change things any way you can practically do with screen code.

Python:
# --- screens.rpy ---

screen choice(items):
    style_prefix "choice"

    vbox:
        for i in items:
            if i.action:
                if i.kwargs and i.kwargs.get( "hint" ) == True and hints_active == True:
                    textbutton "(hint) " + i.caption action i.action
                else:
                    textbutton i.caption action i.action
            else:
                textbutton i.caption


# --- script.rpy ---
default hints_active = False

label start:

    scene black with fade
    "*** START ***"

    menu:
        "Do you want to use hints?"
        "Yes":
            $ hints_active = True
        "No":
            $ hints_active = False

    menu:
        "Choice 1" (hint=True):
            "This is choice 1"

        "Choice 2":
            "This is choice 2"

    "*** THE END ***"
    return
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,550
8,801
Depends which part of the color you want to change.

The text is easy to change...

Python:
    menu:
        "{color=#FF0000}Choice 1{/color}":
            "This is choice 1"

        "Choice 2":
            "This is choice 2"

If you were looking to do some sort of hint system that can be switched off and on again...

Python:
default hint = "#008000"

label start:

    menu:
        "Do you want to use hints?"
        "Yes":
            $ hint="#008000"
        "No":
            $ hint = ""

    menu:
        "[hint]Choice 1":
            "This is choice 1"

        "Choice 2":
            "This is choice 2"

That just the text color though. If you want to change other things, you need to mess with the screen code.

Here's a very rough example I based on a previous question someone had a long time ago.

In this case, I can set a variable on each choice line called "hint". If the choice hint is true AND a variable called hints_active is also true, then the word "(hint) " is displayed before the choice on screen.

Whilst this is very similar to my previous example of colors, the major difference is the implementation. The big difference being that you can override ANY of the screen code or styles to change things any way you can practically do with screen code.

Python:
# --- screens.rpy ---

screen choice(items):
    style_prefix "choice"

    vbox:
        for i in items:
            if i.action:
                if i.kwargs and i.kwargs.get( "hint" ) == True and hints_active == True:
                    textbutton "(hint) " + i.caption action i.action
                else:
                    textbutton i.caption action i.action
            else:
                textbutton i.caption


# --- script.rpy ---
default hints_active = False

label start:

    scene black with fade
    "*** START ***"

    menu:
        "Do you want to use hints?"
        "Yes":
            $ hints_active = True
        "No":
            $ hints_active = False

    menu:
        "Choice 1" (hint=True):
            "This is choice 1"

        "Choice 2":
            "This is choice 2"

    "*** THE END ***"
    return
As I understand it, it's the first one but he's using to show disabled options and color tag overrides the disabled option color. So stuff like this
Python:
    menu:
        "{color=#FF0000}Choice 1{/color}" if False:
            "This is choice 1"

        "Choice 2" if False:
            "This is choice 2"

        "Choice 3":
            "This is choice 3"
would show Choice 3 in white, Choice 2 in grey and Choice 3 in red.

Something dumb like calculating the colors before the menu is shown works but maybe there's a better option
Python:
    $ clr = "#F00" if condition1 else "#aaa"
    menu:
        "{color=[clr]}Choice 1{/color}" if condition1:
            pass
 
  • Like
Reactions: monsternn

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,368
15,282
In this case, I can set a variable on each choice line called "hint". If the choice hint is true AND a variable called hints_active is also true, then the word "(hint) " is displayed before the choice on screen.
Be noted that the same approach can be used if this change is more generic. Like by example for a color change applied to a good MC/Bad MC, or Love/Corruption, kind of menu :

Python:
screen choice(items):
    style_prefix "choice"

    vbox:
        for i in items:
            if i.action:
                #  If it's a good MC/Bad MC choice.
                if i.kwargs and i.kwargs.get( "kind" ) and choiceHelper == True:
                    #  Use the 'goodChoice' or 'badChoice' style in place of the default style,
                    # which one will depend of the choice /kind/.
                    textbutton i.caption action i.action style ( "{}Choice".format( kwargs["kind"] ) )
                #  Else use the default style.
                else:
                    textbutton i.caption action i.action
            else:
                textbutton i.caption

#  Button style for "Good MC", make it a copy of the default style.
style goodChoice is choice_button
#  A button style is in two parts, here regard the text of the button.
style goodChoice_text is choice_button_text:
    #  Change to a redish color.
    color "#DD0000"

# Same for the "Bad MC" style.
style badChoice is choice_button
style badChoice_text is choice_button_text:
    # Change to a greenish color
    color "#00DD00"


# Activate like 79flavors 'hint'
default choiceHelper = False

label whatever:
    [...]
    menu:
        "Choice 1" (kind="good"):
            "This is a 'good MC choice."

        "Choice 2" (kind="bad" ):
            "This is a 'bad' MC choice."

        "Choice 3":
            "This is a neutral choice."
    [...]

And this can be extended for an even more generic approach:

Python:
screen choice(items):
    style_prefix "choice"

    vbox:
        for i in items:
            if i.action:
                if i.kwargs and i.kwargs.get( "style" ):
                    textbutton i.caption action i.action style ( "{}Choice".format( kwargs["style"] ) )
                else:
                    textbutton i.caption action i.action
            else:
                textbutton i.caption

style redChoice is choice_button
style redChoice_text is choice_button_text:
    color "#DD0000"

style greenChoice is choice_button
style greenChoice_text is choice_button_text:
    color "#00DD00"

style blueChoice is choice_button
style blueChoice_text is choice_button_text:
    color "#0000DD"


label whatever:
    [...]
    menu:
        "Choice 1" (style="blue"):
            "This choice will be blue."

        "Choice 2":
            "This choice will have the default style."

        "Choice 3" (style="red"):
            "This choice will be red."
    [...]
In both case I only changed the text color, but any part of the styles can be changed.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,368
15,282
Sorry for the double post

Something dumb like calculating the colors before the menu is shown works but maybe there's a better option
The menu item "action" attribute is different when the choice is disabled.
Bad night followed by a hard day, I don't trust my memory right now and so shouldn't you too, but it tell me that it's covered by the last else in the screen code provided by 79flavors ; therefore there's an empty "action" attribute.

It wouldn't apply in the particular case you pointed, because there the color is directly defined in the string, and therefore it override the color coming from the style. But it would apply for all other cases, since they all fallback to the default style if the said "action" attribute is empty.
 

monsternn

Newbie
Nov 3, 2017
46
17
As I understand it, it's the first one but he's using to show disabled options and color tag overrides the disabled option color. So stuff like this
Python:
    menu:
        "{color=#FF0000}Choice 1{/color}" if False:
            "This is choice 1"

        "Choice 2" if False:
            "This is choice 2"

        "Choice 3":
            "This is choice 3"
would show Choice 3 in white, Choice 2 in grey and Choice 3 in red.

Something dumb like calculating the colors before the menu is shown works but maybe there's a better option
Python:
    $ clr = "#F00" if condition1 else "#aaa"
    menu:
        "{color=[clr]}Choice 1{/color}" if condition1:
            pass
Yep, you understood it right, the problem is indeed in disabled options being colored thus confusing. And your variant is indeed working, thanks. Not as generic as i would like but still nice :)
 
Last edited:
  • Like
Reactions: osanaiko