Стили

Стили позволяют настраивать внешний вид Displayables, изменяя значение свойств стиля. Например, изменение свойства background изменяет фон окна или кнопки.

Свойствам стиля (см. Свойства стилей) можно добавлять префиксы, указывающие, когда используется свойство. Например, свойство hover_background кнопки используется, когда она находится в фокусе, в то время как её свойство idle_background используется, когда она не в фокусе. (Установка свойства background устанавливает и idle_background, и hover_background, среди прочих.)

Хотя в Ren'Py более 100 свойств стиля, в этом разделе используется лишь несколько из них.

Использование стилей и наследование

Каждый displayable имеет встроенный стиль. Когда displayable создаётся, напрямую или с помощью системы экранов, можно указать свойства стиля, которые используются для обновления внешнего вида displayable. В следующем примере:

image big hello world = Text("Hello, World", size=40)

свойство size передаётся в displayable Text, что позволяет нам изменить размер его текста. Это настроит внешний вид displayable текста, отображая текст высотой 40 пикселей (хотя это также зависит от шрифта).

Аналогично, при использовании языка экранов, каждый оператор пользовательского интерфейса принимает соответствующие свойства стиля:

screen big_hello_world:
    text "Hello, World" size 40

Отдельные стили существуют для группировки свойств, чтобы их можно было применять к displayables вместе. Например, эти два текста будут выглядеть одинаково:

image big one = Text("Hello, World", size=40, color="#f00")
image big two = Text("Hello, World", style="big_red")

style big_red:
    size 40
    color "#f00"

Каждый стиль имеет набор свойств и одного родителя. Когда определённый стиль применяется к определённому displayable, каждое свойство стиля (из тех, что принимает displayable) будет искаться среди свойств стиля. Если оно не найдено, поиск продолжается в родительском стиле, затем в родителе родителя и так далее.

Каждый displayable принимает свойство с именем style, которое применяет указанный стиль к displayable:

image big hello world = Text("Hello World", style="big")

screen hello_world:
    text "Hello, World" style "big"

Когда свойство style не указано, родитель выбирается на основе типа предоставленного displayable. Например, кнопки (включая imagebuttons и textbuttons) по умолчанию используют стиль "button", сетки (grids) — стиль "grid" и так далее. На выбор родителя можно повлиять свойством style_prefix операторов пользовательского интерфейса в языке экранов.

Когда стиль определяется без указания родителя, для стиля выбирается родитель по умолчанию. Если имя стиля содержит подчёркивание (_), имя родителя определяется удалением всего до первого подчёркивания включительно. Когда используется несуществующий стиль, и имя стиля содержит подчёркивание, Ren'Py создаст его с использованием родителя по умолчанию. Например, стиль с именем my_button будет наследоваться от button. Это наследование можно изменить с помощью оператора style или методов класса Style. В противном случае используется стиль с именем "default".

Имена стилей, начинающиеся с подчёркивания, зарезервированы для использования Ren'Py.

Поскольку Ren'Py строит стили при запуске, именованные стили не следует изменять после фазы init.

Во время разработки инспектор стилей может быть очень полезен для проверки того, какие стили и свойства стилей используются displayable.

Определение стилей: оператор Style

Предпочтительный способ определения стилей — через оператор style:

style my_text is text:
    size 40
    font "gentium.ttf"

Если стиль не существует, оператор style его создаёт. В противном случае существующий стиль изменяется оператором style.

Примечание

В отличие от других операторов, таких как screen, transform или image, оператор style не является уникальным для данного имени: несколько операторов могут ссылаться на один и тот же стиль и изменять его последовательно, иногда конкурирующим или противоречивым образом. В таких случаях для конечного результата большое значение имеет время init, в которое выполняются различные операторы style.

Оператор style начинается с ключевого слова style и имени определяемого стиля. За ним в первой строке следуют ноль или более предложений и необязательное двоеточие.

Если двоеточие присутствует, за ним должен следовать блок. Каждая строка блока должна содержать одно или несколько предложений. В противном случае оператор завершён.

Оператор style принимает следующие предложения:

style-property simple-expression

Присваивает значение простого выражения указанному свойству стиля.

is parent

Устанавливает или заменяет родителя этого стиля. Родитель должен быть словом, указывающим имя стиля.

clear

Удаляет все свойства этого стиля, которые были присвоены до выполнения этого оператора style. Это не мешает стилю наследовать значения свойств от своих родителей и не меняет его родителя. Чтобы очистить родителя стиля, используйте вместо этого is default.

take style-name

Очищает все свойства этого стиля, которые были назначены до выполнения этого оператора style, и заменяет их свойствами именованного стиля. Это не изменяет родителя этого стиля.

variant simple-expression

Вычисляет простое выражение, чтобы получить строку или список строк, которые интерпретируются как варианты экрана. Если активен хотя бы один из предоставленных вариантов, оператор style выполняется, в противном случае остальная часть блока игнорируется.

properties simple-expression

Вычисляет простое выражение, чтобы получить словарь. Ожидается, что словарь будет сопоставлять свойства стиля со значениями, и значения назначаются так, как если бы они были предоставлены оператору style.

Примеры операторов style:

# Создаёт новый стиль, наследуемый от default.
style big_red:
    size 40

# Обновляет стиль.
style big_red color "#f00"

# Берёт свойства label_text из big_red, но только если мы
# на сенсорной системе.

style label_text:
    variant "touch"
    take big_red

# Стиль a имеет все свойства стиля c, за исключением того, что когда они
# отсутствуют в c, свойства берутся из b или родителей b.
style a is b:
    take c

Операторы style всегда выполняются во время init.

Определение стилей: Python

Именованные стили существуют как поля в глобальном объекте style. Чтобы создать новый стиль, создайте экземпляр класса Style и присвойте его полю в объекте style:

init python:
    style.big_red = Style(style.default)

Свойства стиля можно устанавливать, присваивая их полям объектов Style, похожим на свойства.

init python:
    style.big_red.color = "#f00"
    style.big_red.size = 42

Однако значение свойства стиля нельзя получить таким образом, его можно только записать.

class Style(parent)
parent

Родитель стиля. Это может быть другой объект Style или строка.

clear()

Удаляет все свойства стиля из этого объекта. Значения будут наследоваться от родителя этого объекта.

Эквивалент предложения clear в операторе style.

set_parent(parent)

Устанавливает родителя этого объекта стиля в parent, который может быть другим объектом Style или строкой.

Эквивалент предложения is в операторе style.

take(other)

Берёт все свойства стиля из other, который может быть другим объектом Style или строкой.

Эквивалент предложения take в операторе style.

Индексные стили

Индексные стили — это легковесные стили, которые можно использовать для настройки внешнего вида displayable на основе данных, предоставленных этому displayable. Индексный стиль создаётся путём индексации существующего объекта Style строкой или целым числом. Если индексный стиль не существует, индексация создаёт его как дочерний элемент исходного объекта Style.

init python:
    style.button["Foo"].background = "#f00"
    style.button["Bar"].background = "#00f"
screen indexed_style_test:
    vbox:
        textbutton "Foo" style style.button["Foo"]
        textbutton "Bar" style style.button["Bar"]

Предпочтения стилей

Примечание

Предпочтения GUI часто могут предоставить лучший способ достижения того же результата, поскольку предпочтение GUI может изменить переменную, используемую в нескольких стилях.

Часто бывает желательно позволить пользователю настраивать аспекты пользовательского интерфейса, которые лучше всего выражаются через стили. Например, создатель может захотеть дать игрокам возможность настраивать внешний вид, цвет и размер текста. Предпочтения стилей позволяют выполнять такую настройку.

Предпочтение стиля — это предпочтение, управляющее одним или несколькими свойствами стиля. Предпочтение стиля имеет имя и одну или несколько альтернатив. В любой момент времени одна из доступных альтернатив выбрана и сохранена в постоянных данных (persistent data). По умолчанию используется первая зарегистрированная альтернатива.

Альтернатива содержит одну или несколько ассоциаций стиля, свойства и значения для этого свойства. Она представляет собой обещание, что когда альтернатива будет выбрана, это свойство этого стиля получит это значение. Это происходит при первой инициализации Ren'Py, а затем всякий раз, когда выбирается новая альтернатива.

Следует убедиться, что каждая альтернатива для данного предпочтения стиля обновляет один и тот же набор стилей и свойств. В противном случае результат не будет детерминированным, так как переход от одной альтернативы к другой, а затем обратно к первой, оставит некоторые свойства установленными так, как они были во второй альтернативе.

Вот пример регистрации свойства стиля, которое позволяет пользователю выбирать между большим простым текстом и меньшим текстом с контуром.

init python:
    # Альтернатива "decorated" предпочтения "text" установит размер 22 для стиля "say_dialogue".
    renpy.register_style_preference("text", "decorated", style.say_dialogue, "size", 22)
    renpy.register_style_preference("text", "decorated", style.say_dialogue, "outlines", [ (1, "#000", 0, 0) ])

    renpy.register_style_preference("text", "large", style.say_dialogue, "size", 24)
    renpy.register_style_preference("text", "large", style.say_dialogue, "outlines", [ ])

    # Альтернатива "decorated" будет по умолчанию для предпочтения "text", так как была зарегистрирована первой.

Следующий код позволяет пользователю выбирать эти альтернативы с помощью кнопок:

textbutton "Decorated" action StylePreference("text", "decorated")
textbutton "Large" action StylePreference("text", "large")
StylePreference(preference, alternative)

Действие, которое делает alternative выбранной альтернативой для указанного предпочтения стиля.

Событие update вызывается при вызове этого действия.

preference

Строка, задающая имя предпочтения стиля.

alternative

Строка, задающая имя альтернативы.

renpy.get_style_preference(preference)

Возвращает строку, содержащую имя выбранной альтернативы для указанного предпочтения стиля.

preference

Строка, задающая имя предпочтения стиля.

renpy.register_style_preference(preference, alternative, style, property, value)

Регистрирует информацию об альтернативе для предпочтения стиля.

preference

Строка, имя предпочтения стиля.

alternative

Строка, имя альтернативы.

style

Стиль, который будет обновлен. Это может быть объект стиля или строка, задающая имя стиля.

property

Строка, задающая имя свойства стиля, которое будет обновлено.

value

Значение, которое будет присвоено свойству стиля.

renpy.set_style_preference(preference, alternative)

Устанавливает выбранную альтернативу для предпочтения стиля.

Событие update вызывается при вызове этой функции.

preference

Строка, задающая имя предпочтения стиля.

alternative

Строка, задающая имя альтернативы.

Другие функции стилей

style.rebuild()

Вызывает перестроение именованных стилей, позволяя изменять стили после завершения фазы init.

Предупреждение

Именованные стили не сохраняются как часть данных для каждой игры. Это означает, что изменения в них не сохранятся при цикле сохранения и загрузки.