Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ScrollViewport action #4973

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

altskop
Copy link
Contributor

@altskop altskop commented Sep 14, 2023

This PR introduces a new Screen Action, ScrollViewport.

Unlike the existing Scroll action, which only offers relative scrolling in one dimension (X or Y), ScrollViewport provides the flexibility to scroll to precise coordinates (which could either be relative or absolute).

For example, in a use case where you have a viewport that has to scroll to the center upon a button press, Scroll action is insufficient. It lacks control over both dimensions and requires the developer to set the scroll amount, which often is not a calculation that can be done without knowing the viewport's current adjustment values.

With the introduction of ScrollViewport, it is as easy as this:

action ScrollViewport("test_viewport", (0.5, 0.5), 0.5)

This action will cause the viewport with the id test_viewport to scroll to its center in 0.5s.

Considerations:

  • Scroll action could be further enhanced by allowing providing specific value to scroll to, vs the amount of pixels/pages to scroll by. It would still lack control over both dimensions, but a set of two Scrolls would achieve the same effect as the ScrollViewport action. Let me know if you'd prefer this option instead.

Copy link
Member

@mal mal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first impression was that this probably belonged in the existing Scroll action, but after seeing how geared towards relative movement that action is I became less convinced.

Either way, I've included a code suggestion to simplify and take advantage of previous changes in the current release cycle.

Comment on lines +749 to +773
xadjustment = d.xadjustment
yadjustment = d.yadjustment
adjustment = (xadjustment, yadjustment) # tuple of x and y adjustments to use in the loop below

xyadjustment_change = [] # x and y relative adjustment changes for the animate call based on the position and the current adjustment values

for i, pos in enumerate(self.position):
# a loop for x and y
# using a loop here to avoid code duplication and allow mixing and matching of absolute and relative values
if isinstance(pos, float) and not isinstance(pos, absolute):
# If x/y is a float, use it as a relative position
xyadjustment_change.append(pos * adjustment[i].range - adjustment[i].value)

else:
# otherwise, use it as an absolute position
xyadjustment_change.append(pos - adjustment[i].value)

if self.delay == 0.0:
# if there is no delay, call change and sum the x and y adjustment changes to arrive at the final position
xadjustment.change(xadjustment.value + xyadjustment_change[0])
yadjustment.change(yadjustment.value + xyadjustment_change[1])
else:
# otherwise, animate the x and y adjustment changes
xadjustment.animate(xyadjustment_change[0], self.delay, _warper.ease)
yadjustment.animate(xyadjustment_change[1], self.delay, _warper.ease)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section can be simplified significantly by leveraging changes merged earlier in the 8,2,0 cycle.

Suggested change
xadjustment = d.xadjustment
yadjustment = d.yadjustment
adjustment = (xadjustment, yadjustment) # tuple of x and y adjustments to use in the loop below
xyadjustment_change = [] # x and y relative adjustment changes for the animate call based on the position and the current adjustment values
for i, pos in enumerate(self.position):
# a loop for x and y
# using a loop here to avoid code duplication and allow mixing and matching of absolute and relative values
if isinstance(pos, float) and not isinstance(pos, absolute):
# If x/y is a float, use it as a relative position
xyadjustment_change.append(pos * adjustment[i].range - adjustment[i].value)
else:
# otherwise, use it as an absolute position
xyadjustment_change.append(pos - adjustment[i].value)
if self.delay == 0.0:
# if there is no delay, call change and sum the x and y adjustment changes to arrive at the final position
xadjustment.change(xadjustment.value + xyadjustment_change[0])
yadjustment.change(yadjustment.value + xyadjustment_change[1])
else:
# otherwise, animate the x and y adjustment changes
xadjustment.animate(xyadjustment_change[0], self.delay, _warper.ease)
yadjustment.animate(xyadjustment_change[1], self.delay, _warper.ease)
px, py = self.position
x = absolute.compute_raw(px, d.xadjustment.range)
y = absolute.compute_raw(py, d.yadjustment.range)
if self.delay:
d.xadjustment.animate(x - d.xadjustment.value, self.delay, _warper.ease)
d.yadjustment.animate(y - d.yadjustment.value, self.delay, _warper.ease)
else:
d.xadjustment.change(x)
d.yadjustment.change(y)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants