Styles allow the look of displayables to be customized. This is done by changing the value of style properties for displayables. For example, changing the background property allows the background of a window or button to be customized.
Each displayable has a style built-into it. When the displayable is created, either directly or using the screen system, style properties can be supplied to it, and these styles are used to update the look of the displayable. In the following example:
image big_hello_word = Text("Hello, World", size=40)
the size property is supplied to a Text displayable, allowing us to change its text size. This will customize the look of the text displayable by displaying the text 40 pixels high.
Ren'Py also supports style inheritance. Each displayable takes a style property, that gives the name of the style to use. If a property is not defined for a style, Ren'Py will look it up in the named style, that style's parent, and so on. This allows us to customize a named style in a central place.
A named style exists as a field on the global style object. Style properties exist as fields on styles. So to set the size property of the default style, one can use a python block:
init python:
style.default.font = "mikachan.ttf"
style.default.size = 23
As Ren'Py caches styles, named styles should not be changed outside of init blocks.
Applying a prefix to a style property indicates allows a displayable to change it's look in response to its focus or selection status. For example, a button can change its color when the mouse hovers above it, or to indicate when the choice represented by the button is the currently selected one.
There are five states a displayable can be it.
Button and Bar displayables (and their variants) update their state, and the state of their children, in response to events. For example, when the user puts his mouse over an unselected button, it and all its children will be put into the hover state.
Style property prefixes allow one to set style properties for the different states. There is a system of implications set up, so that a prefix can imply setting the property for more than one state.
The implications are:
prefix | states implied by prefix |
---|---|
(no prefix) | insensitive, idle, hover, selected_idle, selected_hover |
insensitive_ | insensitive |
idle_ | idle, selected_idle |
selected_ | selected_idle, selected_hover |
selected_idle_ | selected_idle |
selected_hover_ | selected_hover |
Using a text button, we can show this in action. Text buttons use two styles by default: button for the button itself, and button_text for the text inside the button. The background style property sets the background of a button, while the color property sets the color of text.
init python:
# The button background is gray when insensitive, light
# blue when hovered, and dark blue otherwise.
style.button.background = "#006"
style.button.insensitive_background = "#444"
style.button.hover_background = "#00a"
# The button text is yellow when selected, and white
# otherwise.
style.button_text.color = "#fff"
style.button_text.selected_color = "#ff0"
Each style property expects a specific kind of data. Many of these are standard python types, but a few are novel. Here are descriptions of the novel kinds of value a style property can expect.
Positions are used to specify locations relative to the upper-left corner of the containing area. (For positions, the containing area is given by the layout the displayable is in, if one is given, or the screen otherwise. For anchors, the containing area is the size of the displayable itself.)
The way a position value is interpreted depends on the type of the value:
Colors in Ren'Py can be expressed as strings beginning with the hash mark (#), followed by a hex triple or hex quadruple, with each of the three or four elements consisting of a one or two hexidecimal character color code.
In a triple, the components represent red, green, and blue. In a quadruple, the components represent red, green, blue, and alpha. For example:
The color triples are the same as used in HTML.
Colors can also be represented as a 4-component tuple, with the 4 components being integers between 0 and 255. The components correspond to red, green, blue, and alpha, in that order.
The style properties control the look of the various displayables. Not all style properties apply to all displayables, so we've divided them up into groups.
These are used to control the position of a displayable inside the area allocated to it by a layout, or on the screen when not inside a layout.
The position of the displayable relative to the left side of the containing area.
The position of the displayable relative to the right side of the containing area.
Equivalent to setting xpos to the first component of the tuple, and ypos to the second component of the tuple.
The position of the anchor relative to the left side of the displayable.
The position of the anchor relative to the top side of the displayable.
Equivalent to setting xanchor to the first component of the tuple, and yanchor to the second component of the tuple.
Equivalent to setting xpos and xanchor to the same value. This has the effect of placing the displayable at a relative location on the screen, with 0.0 being the left side, 0.5 the center, and 1.0 being the right side.
Equivalent to setting ypos and yanchor to the same value. This has the effect of placing the displayable at a relative location on the screen, with 0.0 being the top, 0.5 the center, and 1.0 the bottom.
Equivalent to setting xalign to the first component of the tuple, and yalign to the second.
Gives a number of pixels that are added to the horizontal position computed using xpos and xalign.
Gives a number of pixels that are added to the vertical position computed using ypos and yalign.
Specifies the maximum horizontal size of the displayable, in pixels.
Specifies the maximum vertical size of the displayable in pixels.
Equivalent to setting xmaximum to the first component of the tuple, and ymaximum to the second.
Sets the minimum width of the displayable, in pixels. Only works with displayables that can vary their size.
Sets the minimum height of the displayables, in pixels. Only works with displayables that can vary their size.
Equivalent to setting xminimum to the first component of the tuple, and yminimum to the second.
If true, the displayable will expand to fill all available horizontal space. If not true, it will only be large enough to contain its children.
This only works for displayables that can change size.
If true, the displayable will expand to fill all available horizontal space. If not true, it will only be large enough to contain its children.
This only works for displayables that can change size.
The tuple is interpreted as (xpos, ypos, width, height). Attempts to position the displayable such that it's upper-left corner is at xpos and ypos, and its size is width and height.
It does this by setting the xpos, ypos, xanchor, yanchor, xmaximum, ymaximum, xminimum, yminimum, xfill, and yfill properties to appropriate values.
This will not work with all displayables and all layouts.
If True, the default, truetype font text will be rendered anti-aliased.
When rendering an image-based font, black will be mapped to this color. This has no effect for truetype fonts.
If True, render the font in a bold style. For a truetype font, this usually involves synthetically increasing the font weight. It can also cause the font to be remapped, using config.font_replacement_map.
The color the text is rendered in. When using a truetype font, the font is rendered in this color. When using an image-based font, white is mapped to this color.
The amount that the first line of text in a paragraph is indented by, in pixels.
A string giving the name of the font used to render text.
For a truetype font file, this is usually the name of the file containing the font (like "DejaVuSans.ttf"). To select a second font in a collection, this can be prefixed with a number and at sign (like "0@font.ttc" or "1@font.ttc"). For an image-based font, this should be the name used to register the font.
The size of the font on the screen. While this is nominally in pixels, font files may have creative interpretations of this value.
If true, the text will be rendered in italics. For a truetype font, this usually involves synthetically increasing the font slant. It can also cause the font to be remapped, using config.font_replacement_map.
If true, additional whitespace is inserted between words so that the left and right margins of each line are even. This is not performed on the last line of a paragraph.
Controls the language family used to break text into lines. Legal values are:
Controls how words are allocated to lines. Legal values are:
Sets the minimum width of each line of that. If a line is shorter than this, it is padded to this length, with text_align used to specify where such padding is placed.
This is a list of outlines that are drawn behind the text. Each tuple specifies an outline, and outlines are drawn from back to front.
The list contains (size, color, xoffset, yoffset) tuples. Size is the amount the font is expanded by, in pixels. Color is the color of the outline. xoffset and yoffset are the amount the outline is shifted by, in pixels.
The outline functionality can also be used to give drop-shadows to fonts, by specifiying a size of 0 and non-zero offsets.
Outlines only work with truetype fonts.
Specifies the number of pixels the second and later lines in a paragraph are indented by.
If a number, shows text at the rate of that many characters per second. If True, shows text at the speed taken from the "Text Speed" preference.
The speed of the text is multiplied by this number. This can be used to have a character that speeks at a faster-than-normal rate of speed.
This is used when a line is shorter than the width of the text displayable. It determines how much of the extra space is placed on the left side of the text. (And hence, the text alignment.)
0.0 will yield left-aligned text, 0.5 centered text, and 1.0 right-aligned text.
If true, an underline will be added to the text.
Window properties are used to specify the look of windows, frames, and buttons.
A displayable that is used as the background of the window. This is often a Frame(), allowing the size of the background to scale with the size of the window.
If None, no background is drawn, but other properties function as if the background was present.
If not None, this displayable is drawn above the contents of the window.
The amount of transparent space to the left of the background, in pixels.
The amount of transparent space to the right of the background, in pixels.
Equivalent to setting left_margin and right_margin to the same value.
The amount of transparent space above the background, in pixels.
The amount of transparent space below the background, in pixels.
Equivalent to setting top_margin and bottom_margin to the same value.
The amount of space between the background and the left side of the window content, in pixels.
The amount of space between the background and the right side of the window content, in pixels.
Equivalent to setting left_padding and right_padding to the same value.
The amount of space between the background and the top side of the window content, in pixels.
The amount of space between the background and the bottom side of the window content, in pixels.
Equivalent to setting top_padding and bottom_padding to the same value.
If not None, this should be a string. Ren'Py will render all windows with the same size_group value at the same size.
A sound that is played when the button gains focus.
A sound that is played when the button is clicked.
The mouse style that is used when the button is focused. This should be one of the styles in config.mouse.
A mask that's used to control what portions of the button can be focused, and hence clicked on. If it's a displayable, then areas of the displayable that are not transparent can be focused. If it's True, then the button itself is used as the displayable (so non-transparent areas of the button can be focused.) Otherwise, the entire button can be focused.
Bars are drawn with gutters on the left and right, that when clicked can cause the bart to move by a small amount. The remaining space is the portion of the bar that can change, with the amount on each side proportional to the bar's value as a fraction of the range.
The thumb is an area in the center of the bar that can be dragged by the user.
When a bar is drawn, the thumb's shadow is drawn first. Then the left/bottom and right/top sides of the bar, followed by the thumb itself.
Note that the valid sides of a bar depend on the value of the bar_vertical property. If it's True, the top and bottom sides are relevant. Otherwise, the left and right sides are used.
If true, the bar has a vertical orientation. If false, it has a horizontal orientation.
If true, the value of the bar is represented on the right/top side of the bar, rather than the left/bottom side.
If true, we resize the sides of the bar. If false, we render the sides of the bar at full size, and then crop them.
The size of the gutter on the left side of the bar, in pixels.
The size of the gutter on the right side of the bar, in pixels.
The size of the gutter on the top side of the bar, in pixels.
The size of the gutter on the bottom side of the bar, in pixels.
The displayable used for the left side of the bar.
The displayable used for the right side of the bar.
The displayable used for the top side of the bar.
The displayable uses for the bottom side of the bar.
If not None, this is a displayable that is drawn over the break between the sides of the bar.
If not None, this is a displayable that is drawn over the break between the sides of the bar.
The amount that by which the thumb overlaps the bars, in pixels. To have the left and right bars continue unbroken, set this to half the width of the thumb in pixels.
The mouse style that is used when the button is focused. This should be one of the styles in config.mouse.
Controls what happens if the bar is unscrollable (if the range is set to 0, as is the case with a viewport containing a displayable smaller than itself). There are three possible values:
Named styles exists as fields on the global style object. To create a new style, create an instance of the Style class, and assign it to a field on the style object.
init python:
style.big_text = Style(style.default)
style.big_text.size = 42
Once created, a named style can be applied to displayables by supplying it's name, or the style object.
screen two_big_lines:
vbox:
text "This is Big Text!" style "big_text"
text "So is this." style style.big_text
Creates a new style object. Style properties can be assigned to the fields of this object.
This removes all style properties from this object. Values will be inherited from this object's parent.
Sets the parent of this style object to parent.
This takes all style properties from other. other must be a style object.
Indexed styles are lightweight styles that can be used to customize the look of a displayable based on the data supplied to that displayable. An index style is created by indexing a style object with a string or integer. If an indexed style does not exist, indexing creates it.
init python:
style.button['Foo'].background = "#f00"
style.button['Bar'].background = "#00f"
An index style is used by supplying the indexed style to a displayable.
screen indexed_style_test:
vbox:
textbutton "Foo" style style.button["Foo"]
textbutton "Bar" style style.button["Bar"]
When a property is not defined by a style, it is inherited from the style's parent. When indexing is involved, properties are inherited first from the unindexed form of the style, then from the indexed form of the parent, then the unindexed form of the parent, and so on.
For example, when style.mm_button inherits from style.button, which in turn inherits from style.default, then the properties of style.mm_button["Start Game"] are taken from:
With the property value taken from the lowest numbered style with the property defined.