Ren'Py Using xfill on vpgrid doesn't increase viewport size?

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,550
8,801
I have a screen that looks somewhat like this

Python:
screen my_screen():
    predict False
    modal True

    frame:
        xalign 0.5
        background "#aaaa"
        vpgrid cols cols_number:
            xalign 0.5
            
            for i in range(0, number_of_cells):
                button:
                    xsize x_size
                    ysize y_size
                   add "icon [i]"
                    action NullAction()
Without xfill, vpgrid's content takes about 2/3 of the screen width. so I can still roll back and roll forward if I put my mouse outside of the vpgrid borders. This is understandable.

If I use xfill on the frame like this
Python:
screen my_screen():
    predict False
    modal True

    frame:
        xfill True 
        xalign 0.5
        background "#aaaa"
        vpgrid cols cols_number:
            xalign 0.5
            
            for i in range(0, number_of_cells):
                button:
                    xsize x_size
                    ysize y_size
                   add "icon [i]"
                    action NullAction()
the frame background now fills the entire screen, but vpgrid still takes 2/3 of the frame width (since it's aligned to the center you can see the frame background to the right of the scrollbar) and scrolling works the same way. That's also understandable because vpgrid size didn't change and default keymap still works if you add modal True

If I add xfill to vpgrid
Python:
screen my_screen():
    predict False
    modal True

    frame:
        xfill True #doesn't seem necessary anymore because the screen looks the same without it
        xalign 0.5
        background "#aaaa"
        vpgrid cols cols_number:
            xfill True
            xalign 0.5
            
            for i in range(0, number_of_cells):
                button:
                    xsize x_size
                    ysize y_size
                   add "icon [i]"
                    action NullAction()
the vpgrid's scrollbar, as expected, gets to the right edge of the screen. The content for some reason gets shifted to the left, instead of staying in the middle, but fine, I'll try to figure it out later. It looks like the vpgrid takes all space on the screen, which is what I want. But when I try to scroll somewhere outside of the actual content, which still takes 2/3 of the width, I trigger rollbacks and rollforwards instead of scrolling the vpgrid.

What do I need to do to make a vpgrid take the entire screen space without changing the size of the grid cells? Is it even possible?
 

rayminator

Engaged Member
Respected User
Sep 26, 2018
3,041
3,140
it's because you have your vgrid wrong vpgrid cols cols_number:

it should look like this

Python:
screen vpgrid_test():

    vpgrid:

        cols 2
        spacing 5
        draggable True
        mousewheel True

        scrollbars "vertical"

        # Since we have scrollbars, we have to position the side, rather
        # than the vpgrid proper.
        side_xalign 0.5

        for i in range(1, 100):

            textbutton "Button [i]":
                xysize (200, 50)
                action Return(i)
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,550
8,801
it's because you have your vgrid wrong vpgrid cols cols_number:

it should look like this

Python:
screen vpgrid_test():

    vpgrid:

        cols 2
        spacing 5
        draggable True
        mousewheel True

        scrollbars "vertical"

        # Since we have scrollbars, we have to position the side, rather
        # than the vpgrid proper.
        side_xalign 0.5

        for i in range(1, 100):

            textbutton "Button [i]":
                xysize (200, 50)
                action Return(i)
pretty sure my vpgrid is fine but I made something reproducible to explain my problem
Python:
screen vpgrid_test():
    frame:
        xalign 0.5
        background "#aaa"
        vpgrid:
            cols 5
            transpose False
            mousewheel True
            draggable True
            scrollbars "vertical"
            side_xalign 0.5
            for i in range(0, 100):
                button:
                    xysize(250,250)
                    text "[i]"
                    action NullAction()
You don't have permission to view the spoiler content. Log in or register now.
scrolling while the mouse is in the black area outside the frame triggers rollback, as expected

Python:
screen vpgrid_test():
    frame:
        xfill True
        xalign 0.5
        background "#aaa"
        vpgrid:
            cols 5
            transpose False
            mousewheel True
            draggable True
            scrollbars "vertical"
            side_xalign 0.5
            for i in range(0, 100):
                button:
                    xysize(250,250)
                    text "[i]"
                    action NullAction()
You don't have permission to view the spoiler content. Log in or register now.
if my mouse is in the area highlighted by the red rectangles, it triggers rollback instead of scrolling, understandable

Python:
screen vpgrid_test():
    frame:
        xfill True
        xalign 0.5
        background "#aaa"
        vpgrid:
            xfill True
            cols 5
            transpose False
            mousewheel True
            draggable True
            scrollbars "vertical"
            side_xalign 0.5
            for i in range(0, 100):
                button:
                    xysize(250,250)
                    text "[i]"
                    action NullAction()
You don't have permission to view the spoiler content. Log in or register now.
1. cells are aligned to the left despite side_xalign being 0.5
2. if my mouse is in the area highlighted by the red rectangle, it triggers rollback instead of scrolling
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,284
What do I need to do to make a vpgrid take the entire screen space without changing the size of the grid cells? Is it even possible?
The doc regarding :
"A vpgrid assumes that all children are the same size, the size being taken from the dimensions of the first child."

You tried to apply xfill to the frame, what just made the container use all the width. Then you tried to apply it to the vpgrid, that have no size by itself. This while you should apply it to the children of vpgrid.
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,550
8,801
The doc regarding :
"A vpgrid assumes that all children are the same size, the size being taken from the dimensions of the first child."

You tried to apply xfill to the frame, what just made the container use all the width. Then you tried to apply it to the vpgrid, that have no size by itself. This while you should apply it to the children of vpgrid.
From documentation, it only works for displayables that can change size, so it probably shouldn't work for displayables that have xsize. It definitely doesn't work for buttons if I set xsize, if I don't, the first button takes the entire width and I have to add horizontal scrolling. Looks like I might have to accept defeat and either make the children bigger to use an entire width, or accept accidental rollbacks because the mouse is not inside vpgrid
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,284
From documentation, it only works for displayables that can change size, so it probably shouldn't work for displayables that have xsize.
Be imaginative... Something like this should do it:
Code:
screen whatever():
[...]
       vpgrid:
           col 1
           [...]
           for i in range(0, 100, 2):
                frame:
                    xfill true
                    textbutton "[i]":
                        xpos 0.33
                        xysize(250,250)
                        action whatever
                    $ i += 1
                    textbutton "[i]":
                        xpos 0.66
                        xysize(250,250)
                        action whatever
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,550
8,801
Be imaginative... Something like this should do it:
Code:
screen whatever():
[...]
       vpgrid:
           col 1
           [...]
           for i in range(0, 100, 2):
                frame:
                    xfill true
                    textbutton "[i]":
                        xpos 0.33
                        xysize(250,250)
                        action whatever
                    $ i += 1
                    textbutton "[i]":
                        xpos 0.66
                        xysize(250,250)
                        action whatever
Thanks, this looks interesting. One of the reasons I used vpgrid was because I thought about it as a viewport where I wouldn't have to calculate xpos or xalign so I'll see if I can do the stuff I want with viewport and a full-width frame
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,550
8,801
ended up increasing the number of columns to config.screen_width // grid_child_x_size and adding a bunch of null displayables. looks like the least amount of effort required