Maintaining Focus in Scrolling Viewport

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
snotwurm
Newbie
Posts: 2
Joined: Thu Apr 25, 2024 8:47 am
itch: snotwurm
Contact:

Maintaining Focus in Scrolling Viewport

#1 Post by snotwurm »

Hi all! I'm doing some contract work on a published VN, and we're trying to improve the feel of the controller support. The game displays all the dialogue choice options in a scrolling viewport, and we are attempting to set the viewport scroll directly based on when one of the choices is focused.

Our current approach is to create an action that fires when the textbutton is hovered.

In choices screen here:

Code: Select all

screen choice(items):
    style_prefix "choice"
    default yadj = ui.adjustment()
    default hoveredrect = (1, 2, 3, 100)
    default hoveredy = 100

    key "K_UP" action ScrollViewport(yadj, 'up', items)
    key "K_DOWN" action ScrollViewport(yadj, 'down', items)
    key "pad_lefty_pos" action ScrollViewport(yadj, 'down', items)
    key "pad_lefty_neg" action ScrollViewport(yadj, 'up', items)
    key "pad_righty_pos" action ScrollViewport(yadj, 'down', items)
    key "pad_righty_neg" action ScrollViewport(yadj, 'up', items)
    key "pad_dpup_press" action ScrollViewport(yadj, 'up', items)
    key "pad_dpdown_press" action ScrollViewport(yadj, 'down', items)
    add "gui/choices_backdrop.png"
    viewport yadjustment yadj:
        draggable True
        mousewheel True
        scrollbars "vertical"
        xalign 0.0
        xsize 430
        ysize 650
        xpos 1480
        ypos 25
        vbox:
            for idx, i in enumerate(items):
                if idx == 0:
                    textbutton i.caption id "choice_" + str(idx) action i.action default_focus True hovered OnChoiceFocus(idx, yadj)
                        #hovered SetVariable("captured", renpy.focus_coordinates())
                else:
                    textbutton i.caption id "choice_" + str(idx) action i.action hovered OnChoiceFocus(idx, yadj)
                        #hovered SetVariable("captured", renpy.focus_coordinates())
And scrolling viewport code here:

Code: Select all

######## Viewport Scrolling ##############
init python:
    class OnChoiceFocus(Action):
        def __init__(self, index, yadj):
            self.index = index
            self.yadj = yadj

        def __call__(self):
            widget = renpy.get_widget("choice", "choice_" + str(self.index))
            dispProps = renpy.get_displayable_properties("choice_" + str(self.index))
            renpy.log(dispProps)
            # self.yadj.change(dispProps["offset"])
            # GetFocusRect("current_choice")

    class ScrollViewport(Action):

        def __init__(self, yadj, scroll_dir, items, step=(gui.interface_text_size)*3):
        #def __init__(self, yadj, scroll_dir, step):
            self.yadj = yadj
            self.scroll_dir = scroll_dir
            self.step = step
            self.items = items

        def __call__(self):
            #yadj = renpy.focus_coordinates()[3]
            # Don't confuse dir with the other use case for "up" which
            # refers to the state of the key (pressed/released)
            # print renpy.get_focus_rect()

            if self.scroll_dir == "up":
                renpy.display.behavior.queue_event('focus_up', up=False)
            else:
                renpy.display.behavior.queue_event('focus_down', up=False)

            return
In the code above when a textbutton is hovered, we're trying to get the offset of that textbutton relative to the viewport, and scroll the viewport to that position, to ensure the choice is always visible.

We're having trouble getting the offset of the textbutton. Is there a way to get the offset of the returned widget (which is `Text`, rather than `Button`) to then use in the adjustment for the viewport?

Post Reply

Who is online

Users browsing this forum: No registered users