[SOLVED] Multiple items in glossary list remain selected, last screen stays up after return to main menu

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Kaji
Regular
Posts: 87
Joined: Thu Nov 17, 2022 10:17 pm
Github: Kaji01
Discord: Kaji#7767
Contact:

[SOLVED] Multiple items in glossary list remain selected, last screen stays up after return to main menu

#1 Post by Kaji »

OK, so I'm using a modification of a glossary setup that I found posted on the forums here: viewtopic.php?f=51&t=51990

I wanted to be able to do richer layouts than what it allowed for, so what I've done is set it up so that I can call a screen for each entry, instead of simply swapping out the string loading the data for the entry.

The Good: I got it to work! The screens show up properly and have no problem displaying their content however I want it to appear.

The Bad: When I click on a second entry on the list the new screen appears over top of the old one. The old entry remains highlighted until I click something else (clicking the same entry I just selected works fine and brings it back to one highlighted entry at a time on the list. When I hit Return, however, the last entry selected remains on the screen (though a click dismisses it straight away).

What I've Tried: Since I can't dynamically call a screen as part of the action call or any of the buttons to choose another entry (since they're all written out when it goes to the screen) I have a current_glossary_screen variable set so that I can dismiss the old screen as soon as the new screen loads using renpy.hide_screen(current_glossary_screen) (at which point the new screen's name is written to the variable).

I tried making this call twice to see if there was some sort of extra version being created with each click, but it didn't help. The only way to make the old screen go away seems to be clicking a second time.

The Question: What do I need to do to ensure that the old entry's screen dismisses properly when someone clicks on a new entry or clicks Return?

The Code: The modified code for the main glossary screen is as follows:

Code: Select all

default current_glossary_screen = "blank_glossary_entry"

style glossary_ruby_style:
    size 16
    yoffset -30
    color '#00a5bf' # asagiiro
    font "SourceHanSansLite.ttf"

style glossary_text:
    font "SourceHanSansLite.ttf"
    color '#00a5bf' # asagiiro
    ruby_style style.tn_ruby_style

style glossary_button is button:
    xalign 0.5 yalign 0.5
    background "#000a0280" # sumiiro @50%
    xsize 1920
    ysize 1080

style glossary_frame is frame:
    xalign 0.5 yalign 0.5
    background "#171412" # kokushoku
    xmaximum 1000
    padding [30, 30, 30, 30]

style glossary_hbox is hbox:
    spacing 45

style glossary_vbox is vbox:
    spacing 15

## Relatively unmodified version, based on original code with bits pulled in from main
screen glossary():
    ## This ensures that any other menu screen is replaced.
    tag menu

    add gui.main_menu_background

    ## This empty frame darkens the main menu.
    frame:
        style "game_menu_frame"

    text "Glossary" size 40 xalign 0.5 ypos 20
    hbox spacing 200:
        viewport:
            xpos 50 ypos 100 xsize 300 ysize 780
            scrollbars "vertical"
            spacing 5
            draggable True
            mousewheel True
            arrowkeys True

            vbox spacing 20:
                # use sorted(glossary_dict.keys()) instead of glossary_dict
                # to arrange the terms in alphabetic order
                for word in glossary_dict:
                    if (word['screen'] == ''):
                        $ word['screen'] = 'glossary_sample_entry'
                    $ current_glossary_screen = word['screen']
#                    action SetVariable("current_glossary_screen", word["screen"])

                    textbutton word["localized"]:
                        action Show(word['screen'])

    textbutton _("Return"):
        style "return_button"

        action [Hide(current_glossary_screen), Return()]
The data format is as follows:

Code: Select all

init python:
    glossary_display_desc = ""
    glossary_display_title = ""
    glossary_display_img = ""

    glossary_dict = [
        {
            "headword": "恵比寿",
            "localized": _("Ebisu"),
            "sort_j": "えびす",
            "sort_local": _("Ebisu{#for-sorting}"),
            "screen": "glossary_ebisu",
            "image": ""
        },
        {
            "headword": "大黒",
            "localized": _("Daikoku"),
            "sort_j": "だいこく",
            "sort_local": _("Daikoku{#for-sorting}"),
            "screen": "glossary_daikoku",
            "image": ""
        },
    ]
And then each entry gets its own screen modeled after this template and named after the value in the entry's "screen" value:

Code: Select all

screen blank_glossary_entry():
    $ current_glossary_screen = "blank_glossary_entry"

    style_prefix "glossary"

    viewport:
        xpos 375 ypos 100 xsize 1445 ysize 780
        scrollbars "vertical"
        spacing 5
        draggable True
        mousewheel True
        arrowkeys True

        frame:
            xpos 375 ypos 100 xsize 1445 ysize 780

            vbox:
                text "this is a test"

User avatar
Kaji
Regular
Posts: 87
Joined: Thu Nov 17, 2022 10:17 pm
Github: Kaji01
Discord: Kaji#7767
Contact:

Re: [SOLVED] Multiple items in glossary list remain selected, last screen stays up after return to main menu

#2 Post by Kaji »

Slightly hackish, but I found a solution to the issue. Long story short, the current_glossary_screen variable proved worthless; even calling $ renpy.hide_screen(current_glossary_screen) at the start of the load of the new screen and updating its value there wasn't helping.

So what I did is I went and wrote a function, shown below, that loops through the entire entry registry and hides all screens in the dictionary, and placed that call right at the start of building out the new screen. While intuitively this would seem to hide the screen being drawn as well, it seems to leave that one alone without having to add any logic to skip that screen.

This also saves any further hacks having to figure out how to dismiss everything when leaving the glossary view.

Hope this helps someone!

Code: Select all

init python:
    def hide_current():
        for word in glossary_dict:
            renpy.hide_screen(word['screen'])
Also, here's the updated glossary entry screen template:

Code: Select all

screen blank_glossary_entry():
    $ hide_current()

    style_prefix "glossary"

    viewport:
        xpos 375 ypos 100 xsize 1445 ysize 780
        scrollbars "vertical"
        spacing 5
        draggable True
        mousewheel True
        arrowkeys True

        frame:
            xpos 375 ypos 100 xsize 1445 ysize 780
#            background "#ffffff" # Testing BG Color

            vbox:
                text "this is a test"

Post Reply

Who is online

Users browsing this forum: No registered users