Ren'Py Styling the say screen textbox

liberatorus

Member
Jun 12, 2022
132
181
I am going through the RenPy docs and the tutorial code one thing is confusing for me is how the styles are associated with displayables, you have the say screen like this

Python:
screen say(who, what):
    style_prefix "say"

    window:
        id "window"

        if who is not None:

            window:
                style "namebox"
                text who id "who"

        text what id "what"
Then the style window is defined like this

Python:
style window is default

style window:
    xalign 0.5
    xfill True
    yalign gui.textbox_yalign
    ysize gui.textbox_height

    background Image("gui/textbox.png", xalign=0.5, yalign=1.0)
I am guessing that the Window automatically gets the style from "window"? Can I manually override to a different style name like

Python:
screen say(who, what):
    style_prefix "say"

    window:
        id "window"
        style "newstyle"   # This is where I override the name

        if who is not None:

            window:
                style "namebox"
                text who id "who"

        text what id "what"


style newstyle is default

style newstyle:
    xalign 0.5
    xfill True
    yalign gui.textbox_yalign
    ysize gui.textbox_height

    background Image("gui/textbox2.png", xalign=0.5, yalign=1.0)
This does not actually seem to work or override the style to newstyle. What am I misunderstanding?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,167
14,883
This does not actually seem to work or override the style to newstyle.
It's due to id "window" that overwrite the style name.

Normally if you want to have a different style for the first window, you need to define it under the name "say_window". As for the second one, just directly edit the style named "namebox", it's used only there, or remove the style "namebox" line and define a style named "say_namebox".
 

liberatorus

Member
Jun 12, 2022
132
181
It's due to id "window" that overwrite the style name.

Normally if you want to have a different style for the first window, you need to define it under the name "say_window". As for the second one, just directly edit the style named "namebox", it's used only there, or remove the style "namebox" line and define a style named "say_namebox".
Ok that kind of makes sense. But what will I do if I want to dynamically change style based on an option. Say I have two styles say_window1 and say_window2 and want to style the window depending on some variable?

Like window_style = "say_window1" if styleoption = 1 else "say_window2" or something like that?

Why is it not possible to give a different name for the window style?
 
Last edited:

Sancho1969

Devoted Member
Modder
Donor
Jan 19, 2020
11,972
45,272
Ok that kind of makes sense. But what will I do if I want to dynamically change style based on an option. Say I have two styles say_window1 and say_window2 and want to style the window depending on some variable?

Like window_style = "say_window1" if styleoption = 1 else "say_window2" or something like that?

Why is it not possible to give a different name for the window style?
I'll not get in the way of anne O'nymous's reply but you should read the entire page in the RenPy docs. Not just a snippet of part of the page but more importantly to some of what you are asking you seek the registering of styles to be able to change the style on a per variable instance value change.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,167
14,883
Ok that kind of makes sense. But what will I do if I want to dynamically change style based on an option.
Take a look at the page pointed by Sancho1969
You'll find there the possibility to have and use indexed styles. I'm not totally sure that it would works fine with id but it's where I would looks first.
If it don't works, you can refer to style preferences, in the same page. It's designed to cover a bigger range of change, but have better chances to works.

And in last recourse, the other style functions, that is in fact unique, hint you to another solution. Instead of change the name of the style to apply, you dynamically change the content of the style applied.
 

Sancho1969

Devoted Member
Modder
Donor
Jan 19, 2020
11,972
45,272
...
If it don't works, you can refer to style preferences, in the same page. It's designed to cover a bigger range of change, but have better chances to works.
...
Instead of change the name of the style to apply, you dynamically change the content of the style applied.
liberatorus: This, exactly is how I personally work almost 100% of the time. I never directly change the style name in the say screen nor it's associated window(s). I change backgrounds, fonts, and font attributes dynamically via style preferences. It takes a bit of effort to wrap your head around if you've never used this particular coding logic but it's extremely powerful... arguably the most powerful RenPy styling manipulation a coder can have in their toolbox of goodies. Highly recommended to take the time to understand this...imho.
 
  • Like
Reactions: liberatorus

liberatorus

Member
Jun 12, 2022
132
181
It's due to id "window" that overwrite the style name.

Normally if you want to have a different style for the first window, you need to define it under the name "say_window". As for the second one, just directly edit the style named "namebox", it's used only there, or remove the style "namebox" line and define a style named "say_namebox".
I tried the say_namebox approach you recommended. And define it in screens.rpy. But in a different file when I do

Python:
init 10 python:
    # The textbox background
    renpy.register_style_preference("textbox", "default", style.say_window, "background", Image("gui/textbox.png", xalign=0.5, yalign=1.0))
    renpy.register_style_preference("textbox", "custom", style.say_window, "background", Image("gui/textbox2.png", xalign=0.5, yalign=1.0))

    # The namebox xpos
    renpy.register_style_preference("textbox", "default", style.say_namebox, "xpos", gui.name_xpos)
    renpy.register_style_preference("textbox", "custom", style.say_namebox, "xpos", 360)
I get an exception saying that the style say_namebox does not exist? Registering say_window for style preference works just fine. I tried setting the init offset to 10 to make sure it runs after the screens.rpy but that does not help. What am I missing?
 

liberatorus

Member
Jun 12, 2022
132
181
I tried the say_namebox approach you recommended. And define it in screens.rpy. But in a different file when I do

Python:
init 10 python:
    # The textbox background
    renpy.register_style_preference("textbox", "default", style.say_window, "background", Image("gui/textbox.png", xalign=0.5, yalign=1.0))
    renpy.register_style_preference("textbox", "custom", style.say_window, "background", Image("gui/textbox2.png", xalign=0.5, yalign=1.0))

    # The namebox xpos
    renpy.register_style_preference("textbox", "default", style.say_namebox, "xpos", gui.name_xpos)
    renpy.register_style_preference("textbox", "custom", style.say_namebox, "xpos", 360)
I get an exception saying that the style say_namebox does not exist? Registering say_window for style preference works just fine. I tried setting the init offset to 10 to make sure it runs after the screens.rpy but that does not help. What am I missing?
I did manage to solve it by adding

Python:
    style.say_namebox = Style(style.default)
to the init block before calling register_style_preference. But I am not sure why that is necessary since I am defining say_namebox in the screens.rpy anyway.