Ren'Py Changing style (font size for example) via action, calling style.rebuild()

Penfold Mole

Engaged Member
Respected User
May 22, 2017
3,118
7,618
I've been trying to improve my Ren'Py patch:

Lately I've been trying to bind keyboard keys to change font size while the game is running.

I can not use the StylePreference action, because the size is not a predefined constant to be defined via renpy.register_style_preference function.

The size is being calculated from the config.screen_height (making it universal for different game screen sizes), dividing it by a variable that can be changed within a predefined range.

I stuffed those key bindings into the modified version of the quick_menu screen that has been a part of my patch for some time.

I would like to put everything into a single action statement, but I haven't found a way to call style.rebuild() via action.

So far this is the only way it works:

These key bindings are inside the quick_menu screen:
Code:
        key "alt_K_UP" action [ If(say_dialogue_font_div > font_div_min, SetVariable('say_dialogue_font_div', say_dialogue_font_div - 2), None ), Call('resize_dialogue') ]
       
        key "alt_K_DOWN" action [ If(say_dialogue_font_div < font_div_max, SetVariable('say_dialogue_font_div', say_dialogue_font_div + 2), None ), Call('resize_dialogue') ]
And to call style.rebuild() I had to create a separate subroutine:
Code:
label resize_dialogue:
    $ style.say_dialogue.size = int(config.screen_height / say_dialogue_font_div )
    $ style.rebuild()
    return
This could just stay that way (by now), but the problem is that this way every keypress also counts as a step forward in the game, as if Enter, Space or LMB has been pushed. It's the call of the subroutine that does it. Adding a Rollback() to the end of the action list doesn't work, already tried it.

It would be perfect if I could do this without calling a subroutine.

I guess I'm doing this completely wrong and there is actually a way? Just completely different. :p

_____________________________________________

The second thing I'd like to do is to bind a global key to an action. The way S takes a screenshot and F toggles full screen.
I'd like to make Alt+F1 to call a menu screen (similar to the preferences menu or help menu screen). Or Alt+m to toggle suppress_overlay and quick_menu, one to False the other to True and vice versa.

I know how I could do this in a game - create a custom (invisible) screen, assign a key to an action in it and call it after the start label. Simple.
But I'd like to get by without that screen, create a global key, because it has to be created via patching a random Ren'Py game. It has to be inside the single file of my patch. I don't think I can call a screen that doesn't exist in the game from there.
quick_menu screen is being called by default, that's why I've been using it, but it has a problem - it can be switched off by the game dev via suppress_overlay variable. While the quick_menu == False, all the key bindings in the quick_menu are working, but they stop working when suppress_overlay == True.

All the help I can get is highly appreciated, thanks in advance!
 

Epadder

Programmer
Game Developer
Oct 25, 2016
568
1,064
I can't test this completely but, instead of "Call" use "Function"... no guarantee it will work better :unsure::whistle:

Python:
init python:
    def resize_dialogue():
        style.say_dialogue.size = int(config.screen_height / say_dialogue_font_div )
        style.rebuild()

key "alt_K_UP" action [ If(say_dialogue_font_div > font_div_min, SetVariable('say_dialogue_font_div', say_dialogue_font_div - 2), None ), Function('resize_dialogue') ]
      
key "alt_K_DOWN" action [ If(say_dialogue_font_div < font_div_max, SetVariable('say_dialogue_font_div', say_dialogue_font_div + 2), None ), Function('resize_dialogue') ]
I'm not sure how to approach the second part of your question at all, sorry :oops:
 
  • Like
Reactions: Penfold Mole

Penfold Mole

Engaged Member
Respected User
May 22, 2017
3,118
7,618
Sorry, no. The above version I posted actually works. Just not the way I'd like.
What I'd like to do is to get by without the whole 'resize_dialogue' subroutine that adds a step forward to the game and add that style.rebuild() directly to the list of actions somehow. I just don't know if or how it's possible.

Thanks anyway.

I tried it as a python function the way you suggested, but Ren'Py throws me a "TypeError: 'unicode' object is not callable".
You don't have permission to view the spoiler content. Log in or register now.


Now I tried to attach a test version of my patch here, but I keep getting "server error, please try again later". I guess I'll try tomorrow again.

___________________________
BTW, I found a way around creating a global key. It's not very respectful toward the game devs who have designed their game choice screens into something very different from the default, but it (hopefully) makes my patch a bit more universal and re-adjustable for every player's personal preferences in the future.
I mean, I added a standard say and choice screen to the patch. We'll see how well it works with various games where those screens are heavily customized in various ways I may not be able to predict.

However, I'd still like to see how to add a global key binding to an action.
 

Epadder

Programmer
Game Developer
Oct 25, 2016
568
1,064
Whoops I shouldn't have left resize_dialogue quoted....
Python:
key "alt_K_UP" action [ If(say_dialogue_font_div > font_div_min, SetVariable('say_dialogue_font_div', say_dialogue_font_div - 2), None ), Function(resize_dialogue) ]
key "alt_K_DOWN" action [ If(say_dialogue_font_div < font_div_max, SetVariable('say_dialogue_font_div', say_dialogue_font_div + 2), None ), Function(resize_dialogue) ]
 
  • Like
Reactions: Penfold Mole

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,978
16,233
The second thing I'd like to do is to bind a global key to an action. The way S takes a screenshot and F toggles full screen.
I'd like to make Alt+F1 to call a menu screen (similar to the preferences menu or help menu screen). Or Alt+m to toggle suppress_overlay and quick_menu, one to False the other to True and vice versa.
Basically, something like what I do for the generic configuration menu for my tools/mods, right ? So, I'll share my knowledge. But first, be aware that it's not something documented, nor something intended to be stable. And so, it's something that shouldn't be done outside of the core itself ; but in the same time, it's something that works with all version, starting 6.15.0, because I made it this way.
Code:
init python:
    def myAction():
        renpy.run( store.Show( "penfoldMenuScreen" ) )

    config.underlay[0].keymap["penfoldMenu"] = myAction
    config.keymap["penfoldMenu"] = "alt_K_F1"

label start:
    "Please, press ALT + F1"
    "thanks"
    return

screen penfoldMenuScreen:
     text "The menu is opened"
"config.underlay[0].keymap" is not the regular way to do it now, but it's the way to have compatibility with games above the 6.99.1 version.
 
  • Like
Reactions: Penfold Mole

Penfold Mole

Engaged Member
Respected User
May 22, 2017
3,118
7,618
Whoops I shouldn't have left resize_dialogue quoted....
Python:
key "alt_K_UP" action [ If(say_dialogue_font_div > font_div_min, SetVariable('say_dialogue_font_div', say_dialogue_font_div - 2), None ), Function(resize_dialogue) ]
key "alt_K_DOWN" action [ If(say_dialogue_font_div < font_div_max, SetVariable('say_dialogue_font_div', say_dialogue_font_div + 2), None ), Function(resize_dialogue) ]
Oh, of course, I didn't notice it either. :)
I made exactly the same mistake just a few hours before when I tried to use Call action on style.rebuild() directly and got the same error message. The difference was, when I removed quotes from around the style.rebuild() there, the game just froze and I had to kill it. :poop:

But after removing quotes from around there now...
You don't have permission to view the spoiler content. Log in or register now.

No more forward stepping in the game, just the size of the font changes! Exactly what I wanted. :D

Thank you! (y)

___________________________

And Anne, what would I do without your help?! Thank you very much! d_daisy.gif

I'll try that and will use it, should the workaround through the added standard say screen become too troublesome for some games, so that I'd have to remove it again. Or maybe I'll use it anyway, regardless if the say sceen stays there or not. I haven't decided yet.
 
  • Like
Reactions: Epadder

wurg

Active Member
Modder
Apr 19, 2018
705
1,655
This is off topic for this thread, but the information in here helped me do what I was trying to do.

My question is: Why when I put the () on style.rebuild would it lock the game up making me close it with the task manager, I don't understand why this happened. I pretty new to Python and Ren'Py, but I'm trying to muddle my way through it.

The code is in the preferences menu of the game to change the font of the game on the fly if the user wants, it works perfectly the way it is now, but when I put the () on style.rebuild and clicked preferences on the game menu the game would lock up.

Any insights to this would be appreciated, thank you.

Python:
        # to allow the user to choose a different font, can be switched in game also
                vbox:
                    label _("Font")
                    textbutton _("{font=blk.ttf}Original") action SetVariable ( "style.say_dialogue.font", "blk.ttf"), SetVariable ( "gui.text_font", "blk.ttf" ), style.rebuild
                    textbutton _("{font=CalibriRegular.ttf}Calibri") action SetVariable ( "style.say_dialogue.font", "CalibriRegular.ttf" ), SetVariable ( "gui.text_font", "CalibriRegular.ttf" ), style.rebuild
 

the66

beware, the germans are cumming
Modder
Donor
Respected User
Jan 27, 2017
7,809
24,389
This is off topic for this thread, but the information in here helped me do what I was trying to do.

My question is: Why when I put the () on style.rebuild would it lock the game up making me close it with the task manager, I don't understand why this happened. I pretty new to Python and Ren'Py, but I'm trying to muddle my way through it.

The code is in the preferences menu of the game to change the font of the game on the fly if the user wants, it works perfectly the way it is now, but when I put the () on style.rebuild and clicked preferences on the game menu the game would lock up.

Any insights to this would be appreciated, thank you.

Python:
        # to allow the user to choose a different font, can be switched in game also
                vbox:
                    label _("Font")
                    textbutton _("{font=blk.ttf}Original") action SetVariable ( "style.say_dialogue.font", "blk.ttf"), SetVariable ( "gui.text_font", "blk.ttf" ), style.rebuild
                    textbutton _("{font=CalibriRegular.ttf}Calibri") action SetVariable ( "style.say_dialogue.font", "CalibriRegular.ttf" ), SetVariable ( "gui.text_font", "CalibriRegular.ttf" ), style.rebuild
why so complicated? use standard Ren'Py statements.

Python:
#gui.rpy
define gui.text_font = gui.preference("dialogue_font", "blk.ttf")

#screens.rpy
vbox:
    label _("Font")
    textbutton _('{font=blk.ttf}Original') action gui.SetPreference("dialogue_font", "blk.ttf")
    textbutton _('{font=CalibriRegular.ttf}Calibri') action gui.SetPreference("dialogue_font", "CalibriRegular.ttf")
 
  • Like
Reactions: wurg

wurg

Active Member
Modder
Apr 19, 2018
705
1,655
why so complicated? use standard Ren'Py statements.

Python:
#gui.rpy
define gui.text_font = gui.preference("dialogue_font", "blk.ttf")

#screens.rpy
vbox:
    label _("Font")
    textbutton _('{font=blk.ttf}Original') action gui.SetPreference("dialogue_font", "blk.ttf")
    textbutton _('{font=CalibriRegular.ttf}Calibri') action gui.SetPreference("dialogue_font", "CalibriRegular.ttf")
Honestly, because I don't know better, I'm trying to muddle my way through and learn, but as you know there are a lot of different aspects to it, most times multiple ways to do the same thing.

Thank You for your help, it works like a charm.
 

the66

beware, the germans are cumming
Modder
Donor
Respected User
Jan 27, 2017
7,809
24,389
Honestly, because I don't know better, I'm trying to muddle my way through and learn, but as you know there are a lot of different aspects to it, most times multiple ways to do the same thing.

Thank You for your help, it works like a charm.
and to answer your question, why style.rebuild() malfunctions.
style.rebuild is a bound class method and works, style.rebuild() is the return value of said method.
 
  • Like
Reactions: wurg