Page 1 of 1

[Solved] How to make a history of screens?

Posted: Tue May 07, 2019 3:56 pm
by Saa
In my game, there's a phone/social media funcionality where each new "page" is a screen. So if you click a post to reply to it, it shows you a "reply(post)" screen (where post is an object from the Posts class), and if you click someone's name, it takes you to a "profile(person)" screen (where person is an object from this recipe)

Thing is, I want to make a "back" button that takes you to the last screen you saw. Since you can go to a profile by clicking a post and a post by clicking a reply, and do this infinite times (click a profile then a post in it then a name in it then a post in the person's profile...), this is proving pretty challenging. I've tried to do it by using a list and storing post and person objects in it, but it doesn't work, sometimes buttons just turn unclickable, and it doesn't even give me any errors so I have no idea what's wrong. It also feels terribly inefficient, since it's storing whole objects in it.

Current code:

Code: Select all

default iraAdded = False
default luxAdded = False
default bizAdded = False
default barAdded = False
default sleepyAdded = False
################################################################################
## Stylesheet
################################################################################
style phone_vbox:
    color "#ffffff"
    xsize  350

style opname:
    color "#00f"
    hover_underline True
    selected_underline True
################################################################################
## Posts
################################################################################
init python:
    import renpy.store as store
    reply_screen = False
    class Posts(store.object):
        def __init__(self, poster, pid, post, visi, liked, repliable, reply1, aff1, reply2, aff2):
            self.poster = poster
            self.pid = pid
            self.post = post
            self.visi = visi
            self.liked = liked
            self.repliable = repliable
            self.reply1 = reply1
            self.reply2 = reply2
            self.aff1 = aff1
            self.aff2 = aff2
            posts.insert(0, self)
        # def comment(self):
            # global comment_screen
            # comment_screen = True
            # renpy.call_in_new_context(self.comment_label, current_post=self)
            # comment_screen = False
    class Comments(store.object):
        def __init__(self, poster, pid, comment):
            self.poster = poster
            self.pid = pid
            self.comment = comment
            comments.append(self)
    def add_message (poster, pid, post, repliable, reply1, aff1, reply2, aff2):
        visi = False
        liked = False
        if poster.added == True:
            visi = True
        message = Posts(poster, pid, post, visi, liked, repliable, reply1, aff1, reply2,  aff2)
        if visi == True:
            renpy.notify("New post!")
    def add_comment (poster, pid, comment, reply, repliable, reply1, aff1, reply2, aff2):
        comment = Comments(poster, pid, comment)
        if reply==True:
            renpy.notify("Someone replied to your reply!")
        else:
            pass
        for i in posts:
            if i.pid == pid:
                i.repliable = repliable
                i.reply1 = reply1
                i.reply2 = reply2
                i.aff1 = aff1
                i.aff2 = aff2
    def addFriend (friend):
        for i in posts:
            if i.poster == friend:
                i.visi = True
        friend.added = True
        renpy.notify("Friend added!")
    def like(i):
        if i.liked == False:
            i.liked = True
        else:
            i.liked = False
        i.poster.affection +=0.1
    def affe(poster, afpoint):
        poster.affection += afpoint
    def clearphist():
        phonehistory = []
    def remphist():
        phonehistory.pop(0)
################################################################################
## Phone screen
################################################################################
screen phone():
    modal True
    zorder 100
    style_prefix "phone"
    imagebutton idle "gui/overlay/confirm.png" action [Hide("phone"), Hide("reply"), Hide("profile")] keysym("K_ESCAPE")
    add "images/placeholder/phoneimgmap.png" xalign .5
    button:
        pos (455, 631)
        action [Hide("phone"), Hide("reply"), Hide("profile"), Function(clearphist)]
    viewport xmaximum 350 ymaximum 510 draggable True mousewheel True pagekeys True:
        xalign .5
        yalign 0.4
        vbox:
            for i in posts:
                if i.visi==True:
                    frame:
                        background "#fff"
                        xsize 350
                        hbox:
                            imagebutton idle i.poster.propic action Show("profile", None, i.poster)
                            textbutton i.poster.username:
                                text_style "opname"
                                action Show("profile", None, i.poster)
                    frame background "#eee" xsize 350 ysize 2
                    frame:
                        background "#fff"
                        xsize 350
                        text i.post
                    frame:
                        background "#eee"
                        xsize 350
                        hbox:
                            button:
                                background "#fff"
                                xsize 170
                                if i.liked==False:
                                    text "♡ Like" text_align 0.5 hover_underline True
                                elif i.liked==True:
                                    text "♥ Unlike" text_align 0.5 hover_underline True
                                action Function(like, i)
                            null width 1
                            button:
                                background "#fff"
                                xsize 170
                                text "← Reply" text_align 0.5 hover_underline True
                                action Show("reply", None, i)
                    null width 350 height 10
screen reply(post):
    zorder 101
    style_prefix "phone"
    add "images/placeholder/phone.png" xalign .5
    button:
        pos (35, 635)
        if len(phonehistory)>0 and isinstance(phonehistory[0], CharacterStats) == True:
            action [Hide("reply"), Show("profile", None, phonehistory[0]), Function(remphist)]
        else:
            action Hide("reply")
    viewport xmaximum 350 ymaximum 510 draggable True mousewheel True pagekeys True:
        xalign .5
        yalign 0.4
        vbox:
            frame:
                background "#fff"
                xsize 350
                hbox:
                    imagebutton idle post.poster.propic action [Show("profile", None, post.poster), Hide("reply"), AddToSet(phonehistory, post)]
                    textbutton post.poster.username:
                        text_style "opname"
                        action [Show("profile", None, post.poster), Hide("reply"), AddToSet(phonehistory, post)]
            frame background "#eee" xsize 350 ysize 2
            frame:
                background "#fff"
                xsize 350
                text post.post
            frame:
                background "#eee"
                xsize 350
                button:
                    background "#fff"
                    xsize 345
                    if post.liked==False:
                        text "♡ Like" text_align 0.5 hover_underline True
                    elif post.liked==True:
                        text "♥ Unlike" text_align 0.5 hover_underline True
                    action Function(like, post)
            for i in comments:
                if i.pid == post.pid:
                    frame:
                        background "#fff"
                        xsize 350
                        vbox:
                            hbox:
                                imagebutton idle i.poster.propic action [Show("profile", None, i.poster), Hide("reply"), AddToSet(phonehistory, post)]
                                textbutton i.poster.username:
                                    text_style "opname"
                                    action [Show("profile", None, i.poster), Hide("reply"), AddToSet(phonehistory, post)]
                            text i.comment
                    frame background "#eee" xsize 350 ysize 2
            if post.repliable==True:
                frame:
                    background "#eee"
                    xsize 350
                    hbox:
                        imagebutton idle m.propic action NullAction()
                        vbox:
                            textbutton post.reply1 text_style "replychoice" action [Function(add_comment, m, post.pid, post.reply1, False, False, "", 0, "", 0), Function(affe, post.poster, post.aff1), Hide("reply"), Show("reply", None, post)]
                            textbutton post.reply2 text_style "replychoice" action [Function(add_comment, m, post.pid, post.reply2, False, False, "", 0, "", 0), Function(affe, post.poster, post.aff2), Hide("reply"), Show("reply", None, post)]
screen profile(person):
    zorder 102
    style_prefix "phone"
    add "images/placeholder/phone.png" xalign .5
    button:
        pos (35, 635)
        if len(phonehistory)>0 and isinstance(phonehistory[0], Posts)==True:
            action [Show("reply", phonehistory[0]), Hide("profile"), Function(remphist)]
        else:
            action [Hide("profile")]
    viewport xmaximum 350 ymaximum 510 draggable True mousewheel True pagekeys True:
        xalign .5
        yalign 0.4
        vbox:
            add person.propic xalign .5
            text person.username xalign .5
            text person.bio style "pbio" xalign .5
            for i in posts:
                if i.poster==person:
                    frame:
                        background "#fff"
                        xsize 350
                        hbox:
                            imagebutton idle person.propic action NullAction()
                            textbutton person.username:
                                text_style "opname"
                                action NullAction()
                    frame background "#eee" xsize 350 ysize 2
                    frame:
                        background "#fff"
                        xsize 350
                        text i.post
                    frame:
                        background "#eee"
                        xsize 350
                        hbox:
                            button:
                                background "#fff"
                                xsize 170
                                if i.liked==False:
                                    text "♡ Like" text_align 0.5 hover_underline True
                                elif i.liked==True:
                                    text "♥ Unlike" text_align 0.5 hover_underline True
                                action Function(like, i)
                            null width 1
                            button:
                                background "#fff"
                                xsize 170
                                text "← Reply" text_align 0.5 hover_underline True
                                action [Show("reply", None, i), Hide("profile"), AddToSet(phonehistory, person)]
                    null width 350 height 10
style phone_prompt is gui_prompt
style phone_prompt_text is gui_prompt_text
style phone_button is gui_medium_button
style phone_button_text is gui_medium_button_text
style phone_text:
    color "#000"
style replychoice:
    color "#000"
    #text_color "#fff"
style pbio:
    size 10

Re: How to make a history of screens?

Posted: Tue May 07, 2019 4:52 pm
by nature1996
Try using Call rather than Show, and using return to close the screen

Re: How to make a history of screens?

Posted: Tue May 07, 2019 5:29 pm
by Saa
nature1996 wrote:
Tue May 07, 2019 4:52 pm
Try using Call rather than Show, and using return to close the screen
Call only works for labels, it gives me an error if I try using it for screens.

I tried using a function to call screens for me:

Code: Select all

    def showprofile(person):
        renpy.call_screen("profile", person)
    def showreply(post):
        renpy.call_screen("reply", post)
But I get the error "Cannot start an interaction in the middle of an interaction, without creating a new context".

Re: [Not yet solved] How to make a history of screens?

Posted: Tue May 07, 2019 5:55 pm
by nature1996
I was talking about the screen code replace any action

Code: Select all

Show("screen")
by:

Code: Select all

action Function(renpy.call_screen, "screen")
It should call the screen, which will pile it. If you exit the screen using "action Return()", it should go back to the previous one.

Re: [Not yet solved] How to make a history of screens?

Posted: Tue May 07, 2019 6:05 pm
by Saa
nature1996 wrote:
Tue May 07, 2019 5:55 pm
I was talking about the screen code replace any action

Code: Select all

Show("screen")
by:

Code: Select all

action Function(renpy.call_screen, "screen")
It should call the screen, which will pile it. If you exit the screen using "action Return()", it should go back to the previous one.
That's pretty much what I did, and even doing exactly what you said gave the same "Cannot start an interaction in the middle of an interaction, without creating a new context" error.

Re: [Not yet solved] How to make a history of screens?

Posted: Tue May 07, 2019 6:37 pm
by Imperf3kt
Try using action Call("screen")
Note the capitalised C

Re: [Not yet solved] How to make a history of screens?

Posted: Tue May 07, 2019 6:46 pm
by Saa
Imperf3kt wrote:
Tue May 07, 2019 6:37 pm
Try using action Call("screen")
Note the capitalised C
It gives me a ScriptError: could not find label 'reply'.

Re: [Not yet solved] How to make a history of screens?

Posted: Tue May 07, 2019 9:39 pm
by philat
Hard to offer much other than general comments as it's not testable, but perhaps set a variable for the back button when you're showing the new screen. In other words, screen A has a button that 1) shows screen B, 2) sets a variable called previous_screen to "A". screen B has a back button that basically does Show(previous_screen).

Edit: Never mind, realized I misread the question. I don't know see why your general approach wouldn't work.

Re: [Solved] How to make a history of screens?

Posted: Wed May 08, 2019 10:26 am
by Saa
I found the issue! There were three, actually.

The first: when clicking outside the phone, I forgot to reset the list.

The code was:

Code: Select all

imagebutton idle "gui/overlay/confirm.png" action [Hide("phone"), Hide("reply"), Hide("profile")] keysym("K_ESCAPE")
And should have been:

Code: Select all

imagebutton idle "gui/overlay/confirm.png" action [Hide("phone"), Hide("reply"), Hide("profile"), Function(clearphist)] keysym("K_ESCAPE")
The second: I forgot to specify the transition when returning to the reply screen from the profile screen.

The code was:

Code: Select all

action [Show("reply", phonehistory[0]), Hide("profile"), Function(remphist)]
And should have been:

Code: Select all

action [Show("reply", None, phonehistory[0]), Hide("profile"), Function(remphist)]
The third: I got the order list wrong. The last element in the list was the most recent, not the first. This caused all kinds of issues.
The code was:

Code: Select all

phonehistory[0]
And should have been:

Code: Select all

phonehistory[-1]
Thank you to everyone who tried to help! It's working perfectly now.