Variable Text Size Without Breaking Your GUI

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
User avatar
spiral
Regular
Posts: 44
Joined: Mon Mar 04, 2013 5:48 am
Location: Australia
Contact:

Variable Text Size Without Breaking Your GUI

#1 Post by spiral » Mon Oct 28, 2019 4:04 am

This is a bit hacky, and I've only used it in my game. But hopefully people will find it useful! I probably could have done a lot of this with styles, but styles confuse me, so I didn't.

Code used from: The principles I decided upon after some thought and rereading the Game Accessibility Guidelines:
  • Large text options should include all text necessary to play the game: dialogue, button text, and menus.
  • The game should start with moderately large text by default. It's no good having a "change text size" button that people with poor vision can't see.
  • the largest text size should be as large as possible without making the menus unreadable.
  • Don't offer the player too many options they don't need.
  • The small text size should be fairly readable, but is mostly there for The Aesthetic, since it looks cute and shows more of the sprites/background.
  • Every text size should fit nicely in it's text box.
  • "Dyslexic Fonts" don't actually offer any specific extra benefit to dyslexic people, as long as there's a nice clean option like Deja Vu Sans that's good enough.
  • Including accessibility options in the general preferences screen normalises them and makes more sense. All preferences are accessibility preferences for someone!
So! I have two new additions to the Preferences screen: a font choice, and a text size choice.

Font

Overwrite/replace the following in gui.rpy:

Code: Select all

define gui.text_font=gui.preference("font", "gui/IMFeDPrm28P.ttf") #the font used for dialogue, buttons etc.

define gui.interface_text_font=gui.preference("UIfont", "gui/IMFeENsc28P.ttf") #the font used for user interfaces

define gui.history_height=None
My default is IM Fell.

Since I wanted my preferences screen to look good with very large text, I made sure every line only had two columns. I also added "xsize 400" and "spacing 5" to each block to stop the text getting garbled.

So here's the row in screens.rpy with the font and text size choices in the Preferences menu:

Code: Select all

hbox:
    box_wrap True
        
    null height (4 * gui.pref_spacing)
    vbox:
        {I have multiple versions of this, see below}
                            
        
    vbox:
        xsize  400
        spacing 5

        style_prefix "radio"
        label _("Typeface")

        textbutton "{font=DejaVuSans.ttf}Sans-Serif{/font}" action [
            gui.SetPreference("font","DejaVuSans.ttf"),gui.SetPreference("UIfont", "DejaVuSans.ttf")]

        textbutton "{font=gui/IMFeDPrm28P.ttf}Serif{/font}" action [
            gui.SetPreference("font","gui/IMFeDPrm28P.ttf"),gui.SetPreference("UIfont", "gui/IMFeENsc28P.ttf")]

null height (4 * gui.pref_spacing)        
I decided the actual font names would just confuse people, but I'm not sure Sans Serif vs Serif is the best dichotomy. I might change it to simple vs fancy or something.

Text Size: Version One

This has three text size options, and three matching unscaled textboxes. I couldn't be bothered implementing text box transparency options, so just made the largest text size box entirely opaque. This is the only version that adjusts the history so that long names don't overlap the text.

Overwrite/replace the following in gui.rpy:

Code: Select all

 
define gui.textbox_height=gui.preference("text_height", 186) #the height of the text box image

define gui.dialogue_xpos=gui.preference("text_start", 59) #how far right into the textbox the dialogue starts

define gui.dialogue_width=gui.preference("text_width", 1160) #how wide the dialogue is allowed to get

define gui.history_text_xpos=gui.preference("history_xpos", 170) #where history dialogue starts

define gui.history_text_width=gui.preference("history_width", 740) #how wide history dialogue is
Add this to the Preferences screen in screens.rpy:

Code: Select all

vbox:
    xsize  400
    spacing 5

    style_prefix "radio"
    label _("Font Size")

    textbutton "Small" action [Preference("font size", 0.8), gui.SetPreference("text_height", 185),
        gui.SetPreference("text_start", 165), gui.SetPreference("text_width", 950),
        gui.SetPreference("history_xpos", 170),gui.SetPreference("history_width", 740)]

    textbutton "Medium" action [Preference("font size", 1.0), gui.SetPreference("text_height", 186),
        gui.SetPreference("text_start", 59),gui.SetPreference("text_width", 1160),
        gui.SetPreference("history_xpos", 171),gui.SetPreference("history_width", 739)]
 
    textbutton "Large" action [Preference("font size", 1.25), gui.SetPreference("text_height", 240),
        gui.SetPreference("text_start", 60),gui.SetPreference("text_width", 1166),
        gui.SetPreference("history_xpos", 260),gui.SetPreference("history_width", 660)]
Note that I made some of the sizes one pixel different, this was to stop Renpy thinking the choices counted as the same (I said this was hacky :wink: )

And here's the new code for the dialogue window:

Code: Select all

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

    background background ConditionSwitch("preferences.font_size<=0.8", Image("gui/textbox_small.png"),
                "preferences.font_size<=1.25", Image("gui/textbox_medium.png"),
                 "True", Image("gui/textbox_large.png")) 
 


These numbers were found via a lot of trial and error. I initially just used a frame for the textbox until I had the size right.

Text Size: Version Two

This has a text size slider and resizes the textbox to fit. Inspired by this approach which I couldn't quite get to work. I couldn't figure out how to stop long character names overlapping the text in the history.

Add/overwrite the following variables in gui.rpy:

Code: Select all

define gui.dialogue_ypos=0 

define gui.textbox_height=None #resize automatically

define gui.textbox_borders=Borders(10, 10, 10, 10) #size of corners

define gui.textbox_min=185 #minimum height
Here's some documentation on Frames and Borders.

In screens.rpy:

Add the line "has vbox" and some padding to the say screen:

Code: Select all

window:
        id "window"
        has vbox

        if who is not None:

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

        text what id "what"
        text " "
Edit the dialogue window:

Code: Select all

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

    background Frame("gui/textbox.png", gui.textbox_borders) 
And that should work automatically! You can either just link to the accessibility screen, or add the text size bar to your preferences screen:

Code: Select all

vbox:
    style_prefix "slider"
    box_wrap True
    xsize  400
    spacing 5
    label _("Text Size Scaling")

    null height 10

    bar value Preference("font size")

    textbutton _("Reset"):
        action Preference("font size", 1.0)
Text Size: Version 3

If you want a fancy unscaled textbox by default but a scaled one if the text size gets larger, use Version Two, but replace the window code with:

Code: Select all

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

    background ConditionSwitch("preferences.font_size<=1", Image("gui/textbox_fancy.png"),
               "True", Frame("gui/textbox_scalable.png", gui.textbox_borders)) 

Post Reply

Who is online

Users browsing this forum: No registered users