Create your AI Cum Slut -70% for Mother's Day
x

Ren'Py Tooltip anchoring and viewport autoscrolling

Cskin Games

Well-Known Member
Game Developer
Jun 24, 2021
1,840
2,905
I'm having a couple issues I haven't been able to solve yet with a screen I made for a "biographies" app I have in-game. (Do note - if you see anything in the code and go "wtf does that even do?" - I haven't attempted cleaning it up yet, since I've just been trying different things getting everything to work so I might have forgot to delete unnecessary stuff. I haven't gone through it for that yet, that's once I get it all working)

Here's the relevant screen:

Code:
screen phonebiosapp():
    default sides = "c"
    default name = ""
    default tmp = ""
    $tempvar = len(bioschars)
    fixed:
        xysize (1200,650)
        side sides:
            spacing 10
            frame:
                background None
                vpgrid yadjustment biosadjust:
                    xpos 430
                    ypos 250
                    xminimum 700
                    if sides == "c":
                        cols 5
                    else:
                        cols 3
                    spacing 20
                    draggable True
                    mousewheel True
                    for x,i in zip(range(0,50),bioschars):
                        if i:
                            frame at delayed2:
                                background Frame("images/bios/border.png")
                                vbox:
                                    imagebutton at delayed2:
                                        if i.lower() == "felicity" and felicitypath:
                                            idle "bios_" + i.lower() + "b_idle"
                                            hover "bios_" + i.lower() + "b_hover"
                                            insensitive "bios_" + i.lower() + "_hover"
                                            tooltip i
                                        elif i.lower() == "pixie" and ch4:
                                            idle "bios_" + i.lower() + "b_idle"
                                            hover "bios_" + i.lower() + "b_hover"
                                            insensitive "bios_" + i.lower() + "_hover"
                                            tooltip i
                                        else:
                                            idle "bios_" + i.lower() + "_idle"
                                            hover "bios_" + i.lower() + "_hover"
                                            insensitive "bios_" + i.lower() + "_hover"
                                            if i == "mc":
                                                tooltip "[mcname]"
                                            elif i == "Samantha":
                                                tooltip "Mom"
                                            elif i == "Jack":
                                                tooltip "Dad"
                                            elif i == "Susan":
                                                tooltip "[teacher1]"
                                            elif i == "Janice":
                                                tooltip "[teacher2]"
                                            elif i == "DJ":
                                                tooltip "[djname]"
                                            elif i == "Ham":
                                                tooltip "[hamname]"
                                            elif i == "Finde":
                                                tooltip "[artname]"
                                            else:
                                                tooltip i
                                        action SetVariable('inbios',True), SetScreenVariable("sides","c r"), SetScreenVariable("name",i), SetScreenVariable("tmp",eval("bios_"+i)),SensitiveIf(i != name)
                    if sides == "c r":
                        if len(bioschars)%3 > 0:
                            $tempvar = 3 - len(bioschars)%3
                    else:
                        if len(bioschars) != 50 and len(bioschars) > 40:
                            $tempvar = 50 - len(bioschars)
                        elif len(bioschars) != 40 and len(bioschars) > 30:
                            $tempvar = 40 - len(bioschars)
                        elif len(bioschars) != 30 and len(bioschars) > 20:
                            $tempvar = 30 - len(bioschars)
                        elif len(bioschars) != 20 and len(bioschars) > 10:
                            $tempvar = 20 - len(bioschars)
                        elif len(bioschars) != 10:
                            $tempvar = 10 - len(bioschars)
                    for i in range(0,tempvar):
                        vbox:
                            frame:
                                background None
            if sides == "c r":
                frame:
                    background None
                    pos 1115,250
                    frame:
                        background Frame("images/bios/biosframe.png",20,20)
                        xsize 450
                        ysize 175
                        vbox:
                            yalign 0.5
                            xalign 0.5
                            hbox:
                                xalign 0.5
                                text "Name: "
                                if name == "mc":
                                    text "[mcname]"
                                elif name == "Samantha":
                                    text "Mom"
                                elif name == "Jack":
                                    text "Dad"
                                elif name == "Susan":
                                    text "[teacher1]"
                                elif name =="DJ":
                                    text "[djname]"
                                elif name =="Ham":
                                    text "[hamname]"
                                elif name == "Janice":
                                    text "[teacher2]"
                                elif name == "Finde":
                                    text "[artname]"
                                else:
                                    text "[name]"
                            hbox:
                                xalign 0.5
                                text "Age: "
                                text "[{}]".format("age_"+name)
                            hbox:
                                xalign 0.5
                                text "Status: "
                                text "[{}]".format("status_"+name)
                    frame:
                        background Frame("images/bios/biosframe.png")
                        xysize 450,400
                        ypos 200
                        viewport:
                            mousewheel True
                            draggable True
                            xsize 450
                            ysize 375
                            vbox:
                                for i in reversed(range(0,len(tmp))):
                                    hbox:
                                        text tmp[i] style "biostext" xalign 0.5
                                    if i > 0:
                                        hbox:
                                            xysize (50,100)
                                            add "biosdiv" yalign 0.5
                    frame:
                        background None
                        pos 180,600
                        imagebutton:
                            idle "biosback"
                            hover "biosback_hover"
                            action SetScreenVariable("sides","c"), SetScreenVariable("name","")

    $tooltip = GetTooltip('phonebiosapp')

    if tooltip:
        nearrect:
            focus "tooltip"
            prefer_top True
            ypos 50
            frame:
                background None
                xalign 0.5
                text tooltip size 36 style "biostext"


So far with this, I have 2 issues.

First - the tooltip. When you open the screen and hover, it works fine, like such:

1740251431426.png



However, once you start scrolling, the tooltip doesn't scroll with the viewport - if you continue mousing over the same image eventually you'll get something like this:

1740251466860.png

I'd like to find a way to "anchor" the tooltip to the top of the relevant imagebutton so it stays in position even when scrolling.

I did come across ways to anchor the tooltip to the mouse position but that's no good, since I want it to be static. (Example - looking at the first image, it appears right above the head. I'd like it to stay in that spot even when scrolling - so technically the tooltip moves, it's just always anchored to the correct button).


The 2nd issue comes when actually clicking the button, triggering the "side" screen - it never scrolls correctly. If you look at the code as it is right now, you may see a yadjustment in the viewport, that was just one of many attempts to get it to properly scroll to the correct spot. It wasn't there originally, and I've tried a bunch of different methods but so far all unsuccessful.

For example, let's say you're here in the screen:

1740251684475.png



You click on Grace, and then don't move the mouse at all, and you'll get this:

1740251718720.png



The viewport scrolls in a way that "Grace" disappears entirely (It's scrolled way down the screen - you have to scroll quite a bit to find it) and the viewport auto-scrolled up to a much higher point.

Removing the yadjustment I have in there doesn't fix the problem - it just makes it scroll in a different way since the entire VP is being resized. My ultimate goal is to try and make it so whatever button you click on becomes "centered" in the new view, instead of having the viewport scroll to a different area.
 

gojira667

Member
Sep 9, 2019
351
342
First - the tooltip. When you open the screen and hover, it works fine, like such:

View attachment 4577845

However, once you start scrolling, the tooltip doesn't scroll with the viewport - if you continue mousing over the same image eventually you'll get something like this:

View attachment 4577848

I'd like to find a way to "anchor" the tooltip to the top of the relevant imagebutton so it stays in position even when scrolling.
Currently the nearrect is outside and above the vpgrid. I wouldn't expect it to do what you are hoping. You can moving it at the end of the vpgrid though I don't know how prefer top/bottom will react with scrolling off the screen. :unsure: Should be fine, but nearrect likes to give me trouble. This moves the tooltip frame into the vpgrid.

Removing the yadjustment I have in there doesn't fix the problem - it just makes it scroll in a different way since the entire VP is being resized. My ultimate goal is to try and make it so whatever button you click on becomes "centered" in the new view, instead of having the viewport scroll to a different area.
I don't see where you scroll with the yadjustment. Anyway, is the vpgrid fixed in size? You have what, 50 slots at 5 columns X 10 rows? When showing the bio on the right the vpgrid's width resizes and you have 50 slots at 3 columns X 17 rows. You will need to manipulate yadjustment to scoll it correctly for the resized vpgrid and again when you close it.

You can do so simply based on button position. Watch/show yadjustment, scroll until centered, note buttons and then repeat a second time for the resized 3 column. Slap it into a couple of dicts and set the yadjustment on the side open/close. Assuming fixed buttons.
 
  • Like
Reactions: anne O'nymous

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
11,807
18,241
However, once you start scrolling, the tooltip doesn't scroll with the viewport
As said by Gojira667, this is probably due to the fact that the tooltip is outside of the vpgrid. As he said, try to put the part of the code displaying it inside the vpgrid, it should (no guaranty) solve the issue.


The 2nd issue comes when actually clicking the button, triggering the "side" screen - it never scrolls correctly.
It scroll correctly. The vpgrid was showing the row X, and continue to show the row X, except that now the rows as smaller, what it don't know.
You need to compute the new number of row, and correct the "yadjustment" value accordingly. Without forgetting to do the opposite when you close the side part.
 

Cskin Games

Well-Known Member
Game Developer
Jun 24, 2021
1,840
2,905
As said by Gojira667, this is probably due to the fact that the tooltip is outside of the vpgrid. As he said, try to put the part of the code displaying it inside the vpgrid, it should (no guaranty) solve the issue.

I'll give that a shot in a bit and see what it does.


It scroll correctly. The vpgrid was showing the row X, and continue to show the row X, except that now the rows as smaller, what it don't know.
You need to compute the new number of row, and correct the "yadjustment" value accordingly. Without forgetting to do the opposite when you close the side part.

Yeah, that's why I was trying to use the yadjustment but I haven't been able to get it right. I messed around with both dynamic and static values, and nothing so far I've tried has worked. I've tried a bunch of different things so off the top of my head I can't remember everything I've tried.

Right now, its using a yadjustment value of biosadjust, which in an earlier part of the code is set to ui.adjustment() - while obviously not correct, that was just the last thing I had set it to before giving up for a while to clear my mind and come back to it. Do you know of a way to actually automatically "compute" things, or just a matter of trial and error with different values (or trying to calculate it manually)?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
11,807
18,241
Yeah, that's why I was trying to use the yadjustment but I haven't been able to get it right. I messed around with both dynamic and static values, and nothing so far I've tried has worked. I've tried a bunch of different things so off the top of my head I can't remember everything I've tried.
Well, it's late and I'm too tired to check the doc, so I'll assume that yadjustment contain the row, not a percent.

The basic approach would be:
new first row = ( 5 x first row ) / 3

But this still lead to issue, since you pass from 15 characters shown to 9 characters. Therefore, if it's, by example, the 10th one that is selected, it will still be out of the screen.


In consequence, a better approach is to have a counter that increase with each profile picture, and base the new adjustment value on it. Something like:
Python:
screen blabla():

    default currentIndex

    $ count = 0
    vpgrid [...]:
        for [...]:
            if display:
               $ count += 1
               imagebutton:
                   [...]
                   action SetScreenVariable( "currentIndex", count ) [...]
Then, when you open the bio, you do something like:
previous first row = first row
first row = int( currentIndex / 3 ) + 1

And when you close the bio:
first row = previous first row

Normally this should works.
 
  • Like
Reactions: gojira667

gojira667

Member
Sep 9, 2019
351
342
Right now, its using a yadjustment value of biosadjust, which in an earlier part of the code is set to ui.adjustment(
Is biosadjust a store variable? Then:
Code:
watch biosadjust.value
Otherwise, temporarily add a text element that will show the same in the screen.

You try using ? Needs an id:
Code:
                vpgrid id "vpg_bios" yadjustment biosadjust:
 

Cskin Games

Well-Known Member
Game Developer
Jun 24, 2021
1,840
2,905
Is biosadjust a store variable? Then:
Code:
watch biosadjust.value
Otherwise, temporarily add a text element that will show the same in the screen.

You try using ? Needs an id:
Code:
                vpgrid id "vpg_bios" yadjustment biosadjust:
Edit:

Solved the first issue finally - just did away with tooltips entirely because nothing I did worked correctly. Every attempt to solve a problem worked but simultaneously created a new problem.


The "fix" was just to remove tooltips entirely - and instead use hover_foreground Text() for the hover text. Doing that worked as expected and didn't create any problems - so that's one problem down.

Since it's way late, tomorrow I'll look into trying to fix the 2nd problem of scrolling when opening the new window.
 
Last edited:

gojira667

Member
Sep 9, 2019
351
342
The "fix" was just to remove tooltips entirely - and instead use hover_foreground Text() for the hover text. Doing that worked as expected and didn't create any problems - so that's one problem down.
(y) Not sure if you want the name shown after they are selected with the right-pane showing, but if you did tooltip wouldn't help for that case.

Since it's way late, tomorrow I'll look into trying to fix the 2nd problem of scrolling when opening the new window.
I've used Function(biosadjust.change, 0) to reset the yadjustment scrolling in some screens, but :unsure: I may have stumbled into that from flailing instead of trying Scroll.

You need the yadjustment change to happen after the vpgrid is resized. If that is a problem personally I would try to fight it a bit more, but worst case you could move your if sides == "c r": up and have two different vpgrids (and yadjustments) with the different layouts.