1################################################################################
2## Initialization
3################################################################################
4
5init offset = -1
6
7
8################################################################################
9## Styles
10################################################################################
11
12style default:
13    properties gui.text_properties()
14    language gui.language
15
16style input:
17    properties gui.text_properties("input", accent=True)
18    adjust_spacing False
19
20style hyperlink_text:
21    properties gui.text_properties("hyperlink", accent=True)
22    hover_underline True
23
24style gui_text:
25    properties gui.text_properties("interface")
26
27
28style button:
29    properties gui.button_properties("button")
30
31style button_text is gui_text:
32    properties gui.text_properties("button")
33    yalign 0.5
34
35
36style label_text is gui_text:
37    properties gui.text_properties("label", accent=True)
38
39style prompt_text is gui_text:
40    properties gui.text_properties("prompt")
41
42
43style bar:
44    ysize gui.bar_size
45    left_bar Frame("gui/bar/left.png", gui.bar_borders, tile=gui.bar_tile)
46    right_bar Frame("gui/bar/right.png", gui.bar_borders, tile=gui.bar_tile)
47
48style vbar:
49    xsize gui.bar_size
50    top_bar Frame("gui/bar/top.png", gui.vbar_borders, tile=gui.bar_tile)
51    bottom_bar Frame("gui/bar/bottom.png", gui.vbar_borders, tile=gui.bar_tile)
52
53style scrollbar:
54    ysize gui.scrollbar_size
55    base_bar Frame("gui/scrollbar/horizontal_[prefix_]bar.png", gui.scrollbar_borders, tile=gui.scrollbar_tile)
56    thumb Frame("gui/scrollbar/horizontal_[prefix_]thumb.png", gui.scrollbar_borders, tile=gui.scrollbar_tile)
57
58style vscrollbar:
59    xsize gui.scrollbar_size
60    base_bar Frame("gui/scrollbar/vertical_[prefix_]bar.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile)
61    thumb Frame("gui/scrollbar/vertical_[prefix_]thumb.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile)
62
63style slider:
64    ysize gui.slider_size
65    base_bar Frame("gui/slider/horizontal_[prefix_]bar.png", gui.slider_borders, tile=gui.slider_tile)
66    thumb "gui/slider/horizontal_[prefix_]thumb.png"
67
68style vslider:
69    xsize gui.slider_size
70    base_bar Frame("gui/slider/vertical_[prefix_]bar.png", gui.vslider_borders, tile=gui.slider_tile)
71    thumb "gui/slider/vertical_[prefix_]thumb.png"
72
73
74style frame:
75    padding gui.frame_borders.padding
76    background Frame("gui/frame.png", gui.frame_borders, tile=gui.frame_tile)
77
78
79
80################################################################################
81## In-game screens
82################################################################################
83
84
85## Say screen ##################################################################
86##
87## The say screen is used to display dialogue to the player. It takes two
88## parameters, who and what, which are the name of the speaking character and
89## the text to be displayed, respectively. (The who parameter can be None
90## if no name is given.)
91##
92## This screen must create a text displayable with id "what", as Ren'Py
93## uses this to manage text display. It can also create displayables with
94## id "who" and id "window" to apply style properties.
95##
96## https://www.renpy.org/doc/html/screen_special.html#say
97
98screen say(who, what):
99    style_prefix "say"
100
101    window:
102        id "window"
103
104        if who is not None:
105
106            window:
107                id "namebox"
108                style "namebox"
109                text who id "who"
110
111        text what id "what"
112
113
114    ## If there's a side image, display it above the text. Do not display
115    ## on the phone variant - there's no room.
116    if not renpy.variant("small"):
117        add SideImage() xalign 0.0 yalign 1.0
118
119
120## Make the namebox available for styling through the Character object.
121init python:
122    config.character_id_prefixes.append('namebox')
123
124style window is default
125style say_label is default
126style say_dialogue is default
127style say_thought is say_dialogue
128
129style namebox is default
130style namebox_label is say_label
131
132
133style window:
134    xalign 0.5
135    xfill True
136    yalign gui.textbox_yalign
137    ysize gui.textbox_height
138
139    background Image("gui/textbox.png", xalign=0.5, yalign=1.0)
140
141style namebox:
142    xpos gui.name_xpos
143    xanchor gui.name_xalign
144    xsize gui.namebox_width
145    ypos gui.name_ypos
146    ysize gui.namebox_height
147
148    background Frame("gui/namebox.png", gui.namebox_borders, tile=gui.namebox_tile, xalign=gui.name_xalign)
149    padding gui.namebox_borders.padding
150
151style say_label:
152    properties gui.text_properties("name", accent=True)
153    xalign gui.name_xalign
154    yalign 0.5
155
156style say_dialogue:
157    properties gui.text_properties("dialogue")
158
159    xpos gui.dialogue_xpos
160    xsize gui.dialogue_width
161    ypos gui.dialogue_ypos
162
163
164## Input screen ################################################################
165##
166## This screen is used to display renpy.input. The prompt parameter is used
167## to pass a text prompt in.
168##
169## This screen must create an input displayable with id "input" to accept
170## the various input parameters.
171##
172## https://www.renpy.org/doc/html/screen_special.html#input
173
174screen input(prompt):
175    style_prefix "input"
176
177    window:
178
179        vbox:
180            xalign gui.dialogue_text_xalign
181            xpos gui.dialogue_xpos
182            xsize gui.dialogue_width
183            ypos gui.dialogue_ypos
184
185            text prompt style "input_prompt"
186            input id "input"
187
188style input_prompt is default
189
190style input_prompt:
191    xalign gui.dialogue_text_xalign
192    properties gui.text_properties("input_prompt")
193
194style input:
195    xalign gui.dialogue_text_xalign
196    xmaximum gui.dialogue_width
197
198
199## Choice screen ###############################################################
200##
201## This screen is used to display the in-game choices presented by the
202## menu statement. The one parameter, items, is a list of objects, each
203## with caption and action fields.
204##
205## https://www.renpy.org/doc/html/screen_special.html#choice
206
207screen choice(items):
208    style_prefix "choice"
209
210    vbox:
211        for i in items:
212            textbutton i.caption action i.action
213
214
215## When this is true, menu captions will be spoken by the narrator. When
216## false, menu captions will be displayed as empty buttons.
217define config.narrator_menu = True
218
219
220style choice_vbox is vbox
221style choice_button is button
222style choice_button_text is button_text
223
224style choice_vbox:
225    xalign 0.5
226    ypos gui.scale(270)
227    yanchor 0.5
228
229    spacing gui.choice_spacing
230
231style choice_button is default:
232    properties gui.button_properties("choice_button")
233
234style choice_button_text is default:
235    properties gui.button_text_properties("choice_button")
236
237
238## Quick Menu screen ###########################################################
239##
240## The quick menu is displayed in-game to provide easy access to the
241## out-of-game menus.
242
243screen quick_menu():
244
245    ## Ensure this appears on top of other screens.
246    zorder 100
247
248    if quick_menu:
249
250        hbox:
251            style_prefix "quick"
252
253            xalign 0.5
254            yalign 1.0
255
256            textbutton _("Back") action Rollback()
257            textbutton _("History") action ShowMenu('history')
258            textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True)
259            textbutton _("Auto") action Preference("auto-forward", "toggle")
260            textbutton _("Save") action ShowMenu('save')
261            textbutton _("Q.Save") action QuickSave()
262            textbutton _("Q.Load") action QuickLoad()
263            textbutton _("Prefs") action ShowMenu('preferences')
264
265
266## This code ensures that the quick_menu screen is displayed in-game, whenever
267## the player has not explicitly hidden the interface.
268init python:
269    config.overlay_screens.append("quick_menu")
270
271default quick_menu = True
272
273style quick_button is default
274style quick_button_text is button_text
275
276style quick_button:
277    properties gui.button_properties("quick_button")
278
279style quick_button_text:
280    properties gui.button_text_properties("quick_button")
281
282
283################################################################################
284## Main and Game Menu Screens
285################################################################################
286
287## Navigation screen ###########################################################
288##
289## This screen is included in the main and game menus, and provides navigation
290## to other menus, and to start the game.
291
292screen navigation():
293
294    vbox:
295        style_prefix "navigation"
296
297        xpos gui.navigation_xpos
298        yalign 0.5
299
300        spacing gui.navigation_spacing
301
302        if main_menu:
303
304            textbutton _("Start") action Start()
305
306        else:
307
308            textbutton _("History") action ShowMenu("history")
309
310            textbutton _("Save") action ShowMenu("save")
311
312        textbutton _("Load") action ShowMenu("load")
313
314        textbutton _("Preferences") action ShowMenu("preferences")
315
316        if _in_replay:
317
318            textbutton _("End Replay") action EndReplay(confirm=True)
319
320        elif not main_menu:
321
322            textbutton _("Main Menu") action MainMenu()
323
324        textbutton _("About") action ShowMenu("about")
325
326        if renpy.variant("pc") or (renpy.variant("web") and not renpy.variant("mobile")):
327
328            ## Help isn't necessary or relevant to mobile devices.
329            textbutton _("Help") action ShowMenu("help")
330
331        if renpy.variant("pc"):
332
333            ## The quit button is banned on iOS and unnecessary on Android and Web.
334            textbutton _("Quit") action Quit(confirm=not main_menu)
335
336
337style navigation_button is gui_button
338style navigation_button_text is gui_button_text
339
340style navigation_button:
341    size_group "navigation"
342    properties gui.button_properties("navigation_button")
343
344style navigation_button_text:
345    properties gui.button_text_properties("navigation_button")
346
347
348## Main Menu screen ############################################################
349##
350## Used to display the main menu when Ren'Py starts.
351##
352## https://www.renpy.org/doc/html/screen_special.html#main-menu
353
354screen main_menu():
355
356    ## This ensures that any other menu screen is replaced.
357    tag menu
358
359    add gui.main_menu_background
360
361    ## This empty frame darkens the main menu.
362    frame:
363        style "main_menu_frame"
364
365    ## The use statement includes another screen inside this one. The actual
366    ## contents of the main menu are in the navigation screen.
367    use navigation
368
369    if gui.show_name:
370
371        vbox:
372            style "main_menu_vbox"
373
374            text "[config.name!t]":
375                style "main_menu_title"
376
377            text "[config.version]":
378                style "main_menu_version"
379
380
381style main_menu_frame is empty
382style main_menu_vbox is vbox
383style main_menu_text is gui_text
384style main_menu_title is main_menu_text
385style main_menu_version is main_menu_text
386
387style main_menu_frame:
388    xsize gui.scale(280)
389    yfill True
390
391    background "gui/overlay/main_menu.png"
392
393style main_menu_vbox:
394    xalign 1.0
395    xoffset gui.scale(-20)
396    xmaximum gui.scale(800)
397    yalign 1.0
398    yoffset gui.scale(-20)
399
400style main_menu_text:
401    properties gui.text_properties("main_menu", accent=True)
402
403style main_menu_title:
404    properties gui.text_properties("title")
405
406style main_menu_version:
407    properties gui.text_properties("version")
408
409
410## Game Menu screen ############################################################
411##
412## This lays out the basic common structure of a game menu screen. It's called
413## with the screen title, and displays the background, title, and navigation.
414##
415## The scroll parameter can be None, or one of "viewport" or "vpgrid". When
416## this screen is intended to be used with one or more children, which are
417## transcluded (placed) inside it.
418
419screen game_menu(title, scroll=None, yinitial=0.0):
420
421    style_prefix "game_menu"
422
423    if main_menu:
424        add gui.main_menu_background
425    else:
426        add gui.game_menu_background
427
428    frame:
429        style "game_menu_outer_frame"
430
431        hbox:
432
433            ## Reserve space for the navigation section.
434            frame:
435                style "game_menu_navigation_frame"
436
437            frame:
438                style "game_menu_content_frame"
439
440                if scroll == "viewport":
441
442                    viewport:
443                        yinitial yinitial
444                        scrollbars "vertical"
445                        mousewheel True
446                        draggable True
447                        pagekeys True
448
449                        side_yfill True
450
451                        vbox:
452                            transclude
453
454                elif scroll == "vpgrid":
455
456                    vpgrid:
457                        cols 1
458                        yinitial yinitial
459
460                        scrollbars "vertical"
461                        mousewheel True
462                        draggable True
463                        pagekeys True
464
465                        side_yfill True
466
467                        transclude
468
469                else:
470
471                    transclude
472
473    use navigation
474
475    textbutton _("Return"):
476        style "return_button"
477
478        action Return()
479
480    label title
481
482    if main_menu:
483        key "game_menu" action ShowMenu("main_menu")
484
485
486style game_menu_outer_frame is empty
487style game_menu_navigation_frame is empty
488style game_menu_content_frame is empty
489style game_menu_viewport is gui_viewport
490style game_menu_side is gui_side
491style game_menu_scrollbar is gui_vscrollbar
492
493style game_menu_label is gui_label
494style game_menu_label_text is gui_label_text
495
496style return_button is navigation_button
497style return_button_text is navigation_button_text
498
499style game_menu_outer_frame:
500    bottom_padding gui.scale(30)
501    top_padding gui.scale(120)
502
503    background "gui/overlay/game_menu.png"
504
505style game_menu_navigation_frame:
506    xsize gui.scale(280)
507    yfill True
508
509style game_menu_content_frame:
510    left_margin gui.scale(40)
511    right_margin gui.scale(20)
512    top_margin gui.scale(10)
513
514style game_menu_viewport:
515    xsize gui.scale(920)
516
517style game_menu_vscrollbar:
518    unscrollable gui.unscrollable
519
520style game_menu_side:
521    spacing gui.scale(10)
522
523style game_menu_label:
524    xpos gui.scale(50)
525    ysize gui.scale(120)
526
527style game_menu_label_text:
528    size gui.title_text_size
529    color gui.accent_color
530    yalign 0.5
531
532style return_button:
533    xpos gui.navigation_xpos
534    yalign 1.0
535    yoffset gui.scale(-30)
536
537
538## About screen ################################################################
539##
540## This screen gives credit and copyright information about the game and
541## Ren'Py.
542##
543## There's nothing special about this screen, and hence it also serves as an
544## example of how to make a custom screen.
545
546screen about():
547
548    tag menu
549
550    ## This use statement includes the game_menu screen inside this one.
551    ## The vbox child is then included inside the viewport inside the
552    ## game_menu screen.
553    use game_menu(_("About"), scroll="viewport"):
554
555        style_prefix "about"
556
557        vbox:
558
559            label "[config.name!t]"
560            text _("Version [config.version!t]\n")
561
562            ## gui.about is usually set in options.rpy.
563            if gui.about:
564                text "[gui.about!t]\n"
565
566            text _("Made with {a=https://www.renpy.org/}Ren'Py{/a} [renpy.version_only].\n\n[renpy.license!t]")
567
568
569style about_label is gui_label
570style about_label_text is gui_label_text
571style about_text is gui_text
572
573style about_label_text:
574    size gui.label_text_size
575
576
577## Load and Save screens #######################################################
578##
579## These screens are responsible for letting the player save the game and
580## load it again. Since they share nearly everything in common, both
581## are implemented in terms of a third screen, file_slots.
582##
583## https://www.renpy.org/doc/html/screen_special.html#save
584## https://www.renpy.org/doc/html/screen_special.html#load
585
586screen save():
587
588    tag menu
589
590    use file_slots(_("Save"))
591
592
593screen load():
594
595    tag menu
596
597    use file_slots(_("Load"))
598
599
600screen file_slots(title):
601
602    default page_name_value = FilePageNameInputValue(pattern=_("Page {}"), auto=_("Automatic saves"), quick=_("Quick saves"))
603
604    use game_menu(title):
605
606        fixed:
607
608            ## This ensures the input will get the enter
609            ## event before any of the buttons do.
610            order_reverse True
611
612            ## The page name, which can be edited by clicking on a button.
613            button:
614                style "page_label"
615
616                key_events True
617                xalign 0.5
618                action page_name_value.Toggle()
619
620                input:
621                    style "page_label_text"
622                    value page_name_value
623
624            ## The grid of file slots.
625            grid gui.file_slot_cols gui.file_slot_rows:
626                style_prefix "slot"
627
628                xalign 0.5
629                yalign 0.5
630
631                spacing gui.slot_spacing
632
633                for i in range(gui.file_slot_cols * gui.file_slot_rows):
634
635                    $ slot = i + 1
636
637                    button:
638                        action FileAction(slot)
639
640                        has vbox
641
642                        add FileScreenshot(slot) xalign 0.5
643
644                        text FileTime(slot, format=_("{#file_time}%A, %B %d %Y, %H:%M"), empty=_("empty slot")):
645                            style "slot_time_text"
646
647                        text FileSaveName(slot):
648                            style "slot_name_text"
649
650                        key "save_delete" action FileDelete(slot)
651
652            ## Buttons to access other pages.
653            hbox:
654                style_prefix "page"
655
656                xalign 0.5
657                yalign 1.0
658
659                spacing gui.page_spacing
660
661                textbutton _("<") action FilePagePrevious()
662
663                if config.has_autosave:
664                    textbutton _("{#auto_page}A") action FilePage("auto")
665
666                if config.has_quicksave:
667                    textbutton _("{#quick_page}Q") action FilePage("quick")
668
669                ## range(1, 10) gives the numbers from 1 to 9.
670                for page in range(1, 10):
671                    textbutton "[page]" action FilePage(page)
672
673                textbutton _(">") action FilePageNext()
674
675
676style page_label is gui_label
677style page_label_text is gui_label_text
678style page_button is gui_button
679style page_button_text is gui_button_text
680
681style slot_button is gui_button
682style slot_button_text is gui_button_text
683style slot_time_text is slot_button_text
684style slot_name_text is slot_button_text
685
686style page_label:
687    xpadding gui.scale(50)
688    ypadding gui.scale(3)
689
690style page_label_text:
691    text_align 0.5
692    layout "subtitle"
693    hover_color gui.hover_color
694
695style page_button:
696    properties gui.button_properties("page_button")
697
698style page_button_text:
699    properties gui.button_text_properties("page_button")
700
701style slot_button:
702    properties gui.button_properties("slot_button")
703
704style slot_button_text:
705    properties gui.button_text_properties("slot_button")
706
707
708## Preferences screen ##########################################################
709##
710## The preferences screen allows the player to configure the game to better
711## suit themselves.
712##
713## https://www.renpy.org/doc/html/screen_special.html#preferences
714
715screen preferences():
716
717    tag menu
718
719    use game_menu(_("Preferences"), scroll="viewport"):
720
721        vbox:
722
723            hbox:
724                box_wrap True
725
726                if renpy.variant("pc") or renpy.variant("web"):
727
728                    vbox:
729                        style_prefix "radio"
730                        label _("Display")
731                        textbutton _("Window") action Preference("display", "window")
732                        textbutton _("Fullscreen") action Preference("display", "fullscreen")
733
734                vbox:
735                    style_prefix "radio"
736                    label _("Rollback Side")
737                    textbutton _("Disable") action Preference("rollback side", "disable")
738                    textbutton _("Left") action Preference("rollback side", "left")
739                    textbutton _("Right") action Preference("rollback side", "right")
740
741                vbox:
742                    style_prefix "check"
743                    label _("Skip")
744                    textbutton _("Unseen Text") action Preference("skip", "toggle")
745                    textbutton _("After Choices") action Preference("after choices", "toggle")
746                    textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle"))
747
748                ## Additional vboxes of type "radio_pref" or "check_pref" can be added here, to
749                ## add additional creator-defined preferences.
750
751            null height (4 * gui.pref_spacing)
752
753            hbox:
754                style_prefix "slider"
755                box_wrap True
756
757                vbox:
758
759                    label _("Text Speed")
760
761                    bar value Preference("text speed")
762
763                    label _("Auto-Forward Time")
764
765                    bar value Preference("auto-forward time")
766
767                vbox:
768
769                    if config.has_music:
770                        label _("Music Volume")
771
772                        hbox:
773                            bar value Preference("music volume")
774
775                    if config.has_sound:
776
777                        label _("Sound Volume")
778
779                        hbox:
780                            bar value Preference("sound volume")
781
782                            if config.sample_sound:
783                                textbutton _("Test") action Play("sound", config.sample_sound)
784
785
786                    if config.has_voice:
787                        label _("Voice Volume")
788
789                        hbox:
790                            bar value Preference("voice volume")
791
792                            if config.sample_voice:
793                                textbutton _("Test") action Play("voice", config.sample_voice)
794
795                    if config.has_music or config.has_sound or config.has_voice:
796                        null height gui.pref_spacing
797
798                        textbutton _("Mute All"):
799                            action Preference("all mute", "toggle")
800                            style "mute_all_button"
801
802
803style pref_label is gui_label
804style pref_label_text is gui_label_text
805style pref_vbox is vbox
806
807style radio_label is pref_label
808style radio_label_text is pref_label_text
809style radio_button is gui_button
810style radio_button_text is gui_button_text
811style radio_vbox is pref_vbox
812
813style check_label is pref_label
814style check_label_text is pref_label_text
815style check_button is gui_button
816style check_button_text is gui_button_text
817style check_vbox is pref_vbox
818
819style slider_label is pref_label
820style slider_label_text is pref_label_text
821style slider_slider is gui_slider
822style slider_button is gui_button
823style slider_button_text is gui_button_text
824style slider_pref_vbox is pref_vbox
825
826style mute_all_button is check_button
827style mute_all_button_text is check_button_text
828
829style pref_label:
830    top_margin gui.pref_spacing
831    bottom_margin gui.scale(2)
832
833style pref_label_text:
834    yalign 1.0
835
836style pref_vbox:
837    xsize gui.scale(225)
838
839style radio_vbox:
840    spacing gui.pref_button_spacing
841
842style radio_button:
843    properties gui.button_properties("radio_button")
844    foreground "gui/button/radio_[prefix_]foreground.png"
845
846style radio_button_text:
847    properties gui.button_text_properties("radio_button")
848
849style check_vbox:
850    spacing gui.pref_button_spacing
851
852style check_button:
853    properties gui.button_properties("check_button")
854    foreground "gui/button/check_[prefix_]foreground.png"
855
856style check_button_text:
857    properties gui.button_text_properties("check_button")
858
859style slider_slider:
860    xsize gui.scale(350)
861
862style slider_button:
863    properties gui.button_properties("slider_button")
864    yalign 0.5
865    left_margin gui.scale(10)
866
867style slider_button_text:
868    properties gui.button_text_properties("slider_button")
869
870style slider_vbox:
871    xsize gui.scale(450)
872
873
874## History screen ##############################################################
875##
876## This is a screen that displays the dialogue history to the player.
877## While there isn't anything special about this screen, it does have to
878## access the dialogue history stored in _history_list.
879##
880## https://www.renpy.org/doc/html/history.html
881
882screen history():
883
884    tag menu
885
886    ## Avoid predicting this screen, as it can be very large.
887    predict False
888
889    use game_menu(_("History"), scroll=("vpgrid" if gui.history_height else "viewport"), yinitial=1.0):
890
891        style_prefix "history"
892
893        for h in _history_list:
894
895            window:
896
897                ## This lays things out properly if history_height is None.
898                has fixed:
899                    yfit True
900
901                if h.who:
902
903                    label h.who:
904                        style "history_name"
905                        substitute False
906
907                        ## Take the color of the who text from the Character, if set.
908                        if "color" in h.who_args:
909                            text_color h.who_args["color"]
910
911                $ what = renpy.filter_text_tags(h.what, allow=gui.history_allow_tags)
912                text what:
913                    substitute False
914
915        if not _history_list:
916            label _("The dialogue history is empty.")
917
918
919## This determines what tags are allowed to be displayed on the history
920## screen.
921
922define gui.history_allow_tags = { "alt", "noalt" }
923
924
925style history_window is empty
926
927style history_name is gui_label
928style history_name_text is gui_label_text
929style history_text is gui_text
930
931style history_text is gui_text
932
933style history_label is gui_label
934style history_label_text is gui_label_text
935
936style history_window:
937    xfill True
938    ysize gui.history_height
939
940style history_name:
941    xpos gui.history_name_xpos
942    xanchor gui.history_name_xalign
943    ypos gui.history_name_ypos
944    xsize gui.history_name_width
945
946style history_name_text:
947    min_width gui.history_name_width
948    text_align gui.history_name_xalign
949
950style history_text:
951    xpos gui.history_text_xpos
952    ypos gui.history_text_ypos
953    xanchor gui.history_text_xalign
954    xsize gui.history_text_width
955    min_width gui.history_text_width
956    text_align gui.history_text_xalign
957    layout ("subtitle" if gui.history_text_xalign else "tex")
958
959style history_label:
960    xfill True
961
962style history_label_text:
963    xalign 0.5
964
965
966## Help screen #################################################################
967##
968## A screen that gives information about key and mouse bindings. It uses
969## other screens (keyboard_help, mouse_help, and gamepad_help) to display the
970## actual help.
971
972screen help():
973
974    tag menu
975
976    default device = "keyboard"
977
978    use game_menu(_("Help"), scroll="viewport"):
979
980        style_prefix "help"
981
982        vbox:
983            spacing gui.scale(15)
984
985            hbox:
986
987                textbutton _("Keyboard") action SetScreenVariable("device", "keyboard")
988                textbutton _("Mouse") action SetScreenVariable("device", "mouse")
989
990                if GamepadExists():
991                    textbutton _("Gamepad") action SetScreenVariable("device", "gamepad")
992
993            if device == "keyboard":
994                use keyboard_help
995            elif device == "mouse":
996                use mouse_help
997            elif device == "gamepad":
998                use gamepad_help
999
1000
1001screen keyboard_help():
1002
1003    hbox:
1004        label _("Enter")
1005        text _("Advances dialogue and activates the interface.")
1006
1007    hbox:
1008        label _("Space")
1009        text _("Advances dialogue without selecting choices.")
1010
1011    hbox:
1012        label _("Arrow Keys")
1013        text _("Navigate the interface.")
1014
1015    hbox:
1016        label _("Escape")
1017        text _("Accesses the game menu.")
1018
1019    hbox:
1020        label _("Ctrl")
1021        text _("Skips dialogue while held down.")
1022
1023    hbox:
1024        label _("Tab")
1025        text _("Toggles dialogue skipping.")
1026
1027    hbox:
1028        label _("Page Up")
1029        text _("Rolls back to earlier dialogue.")
1030
1031    hbox:
1032        label _("Page Down")
1033        text _("Rolls forward to later dialogue.")
1034
1035    hbox:
1036        label "H"
1037        text _("Hides the user interface.")
1038
1039    hbox:
1040        label "S"
1041        text _("Takes a screenshot.")
1042
1043    hbox:
1044        label "V"
1045        text _("Toggles assistive {a=https://www.renpy.org/l/voicing}self-voicing{/a}.")
1046
1047    hbox:
1048        label "Shift+A"
1049        text _("Opens the accessibility menu.")
1050
1051
1052screen mouse_help():
1053
1054    hbox:
1055        label _("Left Click")
1056        text _("Advances dialogue and activates the interface.")
1057
1058    hbox:
1059        label _("Middle Click")
1060        text _("Hides the user interface.")
1061
1062    hbox:
1063        label _("Right Click")
1064        text _("Accesses the game menu.")
1065
1066    hbox:
1067        label _("Mouse Wheel Up\nClick Rollback Side")
1068        text _("Rolls back to earlier dialogue.")
1069
1070    hbox:
1071        label _("Mouse Wheel Down")
1072        text _("Rolls forward to later dialogue.")
1073
1074
1075screen gamepad_help():
1076
1077    hbox:
1078        label _("Right Trigger\nA/Bottom Button")
1079        text _("Advances dialogue and activates the interface.")
1080
1081    hbox:
1082        label _("Left Trigger\nLeft Shoulder")
1083        text _("Rolls back to earlier dialogue.")
1084
1085    hbox:
1086        label _("Right Shoulder")
1087        text _("Rolls forward to later dialogue.")
1088
1089
1090    hbox:
1091        label _("D-Pad, Sticks")
1092        text _("Navigate the interface.")
1093
1094    hbox:
1095        label _("Start, Guide")
1096        text _("Accesses the game menu.")
1097
1098    hbox:
1099        label _("Y/Top Button")
1100        text _("Hides the user interface.")
1101
1102    textbutton _("Calibrate") action GamepadCalibrate()
1103
1104
1105style help_button is gui_button
1106style help_button_text is gui_button_text
1107style help_label is gui_label
1108style help_label_text is gui_label_text
1109style help_text is gui_text
1110
1111style help_button:
1112    properties gui.button_properties("help_button")
1113    xmargin gui.scale(8)
1114
1115style help_button_text:
1116    properties gui.button_text_properties("help_button")
1117
1118style help_label:
1119    xsize gui.scale(250)
1120    right_padding gui.scale(20)
1121
1122style help_label_text:
1123    size gui.text_size
1124    xalign 1.0
1125    text_align 1.0
1126
1127
1128
1129################################################################################
1130## Additional screens
1131################################################################################
1132
1133
1134## Confirm screen ##############################################################
1135##
1136## The confirm screen is called when Ren'Py wants to ask the player a yes or
1137## no question.
1138##
1139## https://www.renpy.org/doc/html/screen_special.html#confirm
1140
1141screen confirm(message, yes_action, no_action):
1142
1143    ## Ensure other screens do not get input while this screen is displayed.
1144    modal True
1145
1146    zorder 200
1147
1148    style_prefix "confirm"
1149
1150    add "gui/overlay/confirm.png"
1151
1152    frame:
1153
1154        vbox:
1155            xalign .5
1156            yalign .5
1157            spacing gui.scale(30)
1158
1159            label _(message):
1160                style "confirm_prompt"
1161                xalign 0.5
1162
1163            hbox:
1164                xalign 0.5
1165                spacing gui.scale(100)
1166
1167                textbutton _("Yes") action yes_action
1168                textbutton _("No") action no_action
1169
1170    ## Right-click and escape answer "no".
1171    key "game_menu" action no_action
1172
1173
1174style confirm_frame is gui_frame
1175style confirm_prompt is gui_prompt
1176style confirm_prompt_text is gui_prompt_text
1177style confirm_button is gui_medium_button
1178style confirm_button_text is gui_medium_button_text
1179
1180style confirm_frame:
1181    background Frame([ "gui/confirm_frame.png", "gui/frame.png"], gui.confirm_frame_borders, tile=gui.frame_tile)
1182    padding gui.confirm_frame_borders.padding
1183    xalign .5
1184    yalign .5
1185
1186style confirm_prompt_text:
1187    text_align 0.5
1188    layout "subtitle"
1189
1190style confirm_button:
1191    properties gui.button_properties("confirm_button")
1192
1193style confirm_button_text:
1194    properties gui.button_text_properties("confirm_button")
1195
1196
1197## Skip indicator screen #######################################################
1198##
1199## The skip_indicator screen is displayed to indicate that skipping is in
1200## progress.
1201##
1202## https://www.renpy.org/doc/html/screen_special.html#skip-indicator
1203
1204screen skip_indicator():
1205
1206    zorder 100
1207    style_prefix "skip"
1208
1209    frame:
1210
1211        hbox:
1212            spacing gui.scale(6)
1213
1214            text _("Skipping")
1215
1216            text "▸" at delayed_blink(0.0, 1.0) style "skip_triangle"
1217            text "▸" at delayed_blink(0.2, 1.0) style "skip_triangle"
1218            text "▸" at delayed_blink(0.4, 1.0) style "skip_triangle"
1219
1220
1221## This transform is used to blink the arrows one after another.
1222transform delayed_blink(delay, cycle):
1223    alpha .5
1224
1225    pause delay
1226
1227    block:
1228        linear .2 alpha 1.0
1229        pause .2
1230        linear .2 alpha 0.5
1231        pause (cycle - .4)
1232        repeat
1233
1234
1235style skip_frame is empty
1236style skip_text is gui_text
1237style skip_triangle is skip_text
1238
1239style skip_frame:
1240    ypos gui.skip_ypos
1241    background Frame("gui/skip.png", gui.skip_frame_borders, tile=gui.frame_tile)
1242    padding gui.skip_frame_borders.padding
1243
1244style skip_text:
1245    size gui.notify_text_size
1246
1247style skip_triangle:
1248    ## We have to use a font that has the BLACK RIGHT-POINTING SMALL TRIANGLE
1249    ## glyph in it.
1250    font "DejaVuSans.ttf"
1251
1252
1253## Notify screen ###############################################################
1254##
1255## The notify screen is used to show the player a message. (For example,
1256## when the game is quicksaved or a screenshot has been taken.)
1257##
1258## https://www.renpy.org/doc/html/screen_special.html#notify-screen
1259
1260screen notify(message):
1261
1262    zorder 100
1263    style_prefix "notify"
1264
1265    frame at notify_appear:
1266        text "[message!tq]"
1267
1268    timer 3.25 action Hide('notify')
1269
1270
1271transform notify_appear:
1272    on show:
1273        alpha 0
1274        linear .25 alpha 1.0
1275    on hide:
1276        linear .5 alpha 0.0
1277
1278
1279style notify_frame is empty
1280style notify_text is gui_text
1281
1282style notify_frame:
1283    ypos gui.notify_ypos
1284
1285    background Frame("gui/notify.png", gui.notify_frame_borders, tile=gui.frame_tile)
1286    padding gui.notify_frame_borders.padding
1287
1288style notify_text:
1289    properties gui.text_properties("notify")
1290
1291
1292## NVL screen ##################################################################
1293##
1294## This screen is used for NVL-mode dialogue and menus.
1295##
1296## https://www.renpy.org/doc/html/screen_special.html#nvl
1297
1298
1299screen nvl(dialogue, items=None):
1300
1301    window:
1302        style "nvl_window"
1303
1304        has vbox:
1305            spacing gui.nvl_spacing
1306
1307        ## Displays dialogue in either a vpgrid or the vbox.
1308        if gui.nvl_height:
1309
1310            vpgrid:
1311                cols 1
1312                yinitial 1.0
1313
1314                use nvl_dialogue(dialogue)
1315
1316        else:
1317
1318            use nvl_dialogue(dialogue)
1319
1320        ## Displays the menu, if given. The menu may be displayed incorrectly
1321        ## if config.narrator_menu is set to True, as it is above.
1322        for i in items:
1323
1324            textbutton i.caption:
1325                action i.action
1326                style "nvl_button"
1327
1328    add SideImage() xalign 0.0 yalign 1.0
1329
1330
1331screen nvl_dialogue(dialogue):
1332
1333    for d in dialogue:
1334
1335        window:
1336            id d.window_id
1337
1338            fixed:
1339                yfit gui.nvl_height is None
1340
1341                if d.who is not None:
1342
1343                    text d.who:
1344                        id d.who_id
1345
1346                text d.what:
1347                    id d.what_id
1348
1349
1350## This controls the maximum number of NVL-mode entries that can be displayed
1351## at once.
1352define config.nvl_list_length = gui.nvl_list_length
1353
1354style nvl_window is default
1355style nvl_entry is default
1356
1357style nvl_label is say_label
1358style nvl_dialogue is say_dialogue
1359
1360style nvl_button is button
1361style nvl_button_text is button_text
1362
1363style nvl_window:
1364    xfill True
1365    yfill True
1366
1367    background "gui/nvl.png"
1368    padding gui.nvl_borders.padding
1369
1370style nvl_entry:
1371    xfill True
1372    ysize gui.nvl_height
1373
1374style nvl_label:
1375    xpos gui.nvl_name_xpos
1376    xanchor gui.nvl_name_xalign
1377    ypos gui.nvl_name_ypos
1378    yanchor 0.0
1379    xsize gui.nvl_name_width
1380    min_width gui.nvl_name_width
1381    text_align gui.nvl_name_xalign
1382
1383style nvl_dialogue:
1384    xpos gui.nvl_text_xpos
1385    xanchor gui.nvl_text_xalign
1386    ypos gui.nvl_text_ypos
1387    xsize gui.nvl_text_width
1388    min_width gui.nvl_text_width
1389    text_align gui.nvl_text_xalign
1390    layout ("subtitle" if gui.nvl_text_xalign else "tex")
1391
1392style nvl_thought:
1393    xpos gui.nvl_thought_xpos
1394    xanchor gui.nvl_thought_xalign
1395    ypos gui.nvl_thought_ypos
1396    xsize gui.nvl_thought_width
1397    min_width gui.nvl_thought_width
1398    text_align gui.nvl_thought_xalign
1399    layout ("subtitle" if gui.nvl_text_xalign else "tex")
1400
1401style nvl_button:
1402    properties gui.button_properties("nvl_button")
1403    xpos gui.nvl_button_xpos
1404    xanchor gui.nvl_button_xalign
1405
1406style nvl_button_text:
1407    properties gui.button_text_properties("nvl_button")
1408
1409
1410
1411################################################################################
1412## Mobile Variants
1413################################################################################
1414
1415style pref_vbox:
1416    variant "medium"
1417    xsize gui.scale(450)
1418
1419## Since a mouse may not be present, we replace the quick menu with a version
1420## that uses fewer and bigger buttons that are easier to touch.
1421screen quick_menu():
1422    variant "touch"
1423
1424    zorder 100
1425
1426    if quick_menu:
1427
1428        hbox:
1429            style_prefix "quick"
1430
1431            xalign 0.5
1432            yalign 1.0
1433
1434            textbutton _("Back") action Rollback()
1435            textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True)
1436            textbutton _("Auto") action Preference("auto-forward", "toggle")
1437            textbutton _("Menu") action ShowMenu()
1438
1439
1440style window:
1441    variant "small"
1442    background "gui/phone/textbox.png"
1443
1444style radio_button:
1445    variant "small"
1446    foreground "gui/phone/button/radio_[prefix_]foreground.png"
1447
1448style check_button:
1449    variant "small"
1450    foreground "gui/phone/button/check_[prefix_]foreground.png"
1451
1452style nvl_window:
1453    variant "small"
1454    background "gui/phone/nvl.png"
1455
1456style main_menu_frame:
1457    variant "small"
1458    background "gui/phone/overlay/main_menu.png"
1459
1460style game_menu_outer_frame:
1461    variant "small"
1462    background "gui/phone/overlay/game_menu.png"
1463
1464style game_menu_navigation_frame:
1465    variant "small"
1466    xsize gui.scale(340)
1467
1468style game_menu_content_frame:
1469    variant "small"
1470    top_margin 0
1471
1472style pref_vbox:
1473    variant "small"
1474    xsize gui.scale(400)
1475
1476style bar:
1477    variant "small"
1478    ysize gui.bar_size
1479    left_bar Frame("gui/phone/bar/left.png", gui.bar_borders, tile=gui.bar_tile)
1480    right_bar Frame("gui/phone/bar/right.png", gui.bar_borders, tile=gui.bar_tile)
1481
1482style vbar:
1483    variant "small"
1484    xsize gui.bar_size
1485    top_bar Frame("gui/phone/bar/top.png", gui.vbar_borders, tile=gui.bar_tile)
1486    bottom_bar Frame("gui/phone/bar/bottom.png", gui.vbar_borders, tile=gui.bar_tile)
1487
1488style scrollbar:
1489    variant "small"
1490    ysize gui.scrollbar_size
1491    base_bar Frame("gui/phone/scrollbar/horizontal_[prefix_]bar.png", gui.scrollbar_borders, tile=gui.scrollbar_tile)
1492    thumb Frame("gui/phone/scrollbar/horizontal_[prefix_]thumb.png", gui.scrollbar_borders, tile=gui.scrollbar_tile)
1493
1494style vscrollbar:
1495    variant "small"
1496    xsize gui.scrollbar_size
1497    base_bar Frame("gui/phone/scrollbar/vertical_[prefix_]bar.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile)
1498    thumb Frame("gui/phone/scrollbar/vertical_[prefix_]thumb.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile)
1499
1500style slider:
1501    variant "small"
1502    ysize gui.slider_size
1503    base_bar Frame("gui/phone/slider/horizontal_[prefix_]bar.png", gui.slider_borders, tile=gui.slider_tile)
1504    thumb "gui/phone/slider/horizontal_[prefix_]thumb.png"
1505
1506style vslider:
1507    variant "small"
1508    xsize gui.slider_size
1509    base_bar Frame("gui/phone/slider/vertical_[prefix_]bar.png", gui.vslider_borders, tile=gui.slider_tile)
1510    thumb "gui/phone/slider/vertical_[prefix_]thumb.png"
1511
1512style slider_vbox:
1513    variant "small"
1514    xsize None
1515
1516style slider_slider:
1517    variant "small"
1518    xsize gui.scale(600)
1519