Simplify scroll logic

We no longer need to remember the previous value, which cases issues
with trackpad scrolling on macOS.
This commit is contained in:
Arjan Molenaar 2024-08-20 15:39:40 +02:00
parent 7b2750650a
commit d18894bb4e
2 changed files with 16 additions and 33 deletions

View File

@ -93,9 +93,12 @@ class GtkView(Gtk.DrawingArea, Gtk.Scrollable):
self.set_focusable(True)
self.connect_after("resize", GtkView.on_resize)
def alignment_updated(matrix: Matrix) -> None:
def alignment_updated(x: float | None, y: float | None) -> None:
if self._model:
self._matrix *= matrix
if x is not None:
self.matrix.set(x0=-x)
if y is not None:
self.matrix.set(y0=-y)
self._scrolling = Scrolling(alignment_updated)
@ -327,10 +330,9 @@ class GtkView(Gtk.DrawingArea, Gtk.Scrollable):
qtree.add(item=item, bounds=(x, y, w, h))
@g_async(single=True)
def update_scrolling(self) -> None:
self._scrolling.update_adjustments(
self.get_width(), self.get_height(), self.bounding_box
self.get_width(), self.get_height(), self._qtree.soft_bounds
)
def _debug_draw_bounding_box(self, cr, width, height):

View File

@ -5,13 +5,14 @@ from typing import Callable
from gi.repository import Gtk
from gaphas.geometry import Rectangle
from gaphas.matrix import Matrix
class Scrolling:
"""Contains Gtk.Adjustment and related code."""
def __init__(self, scrolling_updated: Callable[[Matrix], None]) -> None:
def __init__(
self, scrolling_updated: Callable[[float | None, float | None], None]
) -> None:
self._scrolling_updated = scrolling_updated
self.hadjustment: Gtk.Adjustment | None = None
self.vadjustment: Gtk.Adjustment | None = None
@ -19,8 +20,6 @@ class Scrolling:
self.vscroll_policy: Gtk.ScrollablePolicy | None = None
self._hadjustment_handler_id = 0
self._vadjustment_handler_id = 0
self._last_hvalue = 0
self._last_vvalue = 0
def get_property(self, prop):
if prop.name == "hadjustment":
@ -41,18 +40,16 @@ class Scrolling:
self.hadjustment.disconnect(self._hadjustment_handler_id)
self.hadjustment = value
self._hadjustment_handler_id = self.hadjustment.connect(
"value-changed", self.on_adjustment_changed
"value-changed", self.on_hadjustment_changed
)
self._scrolling_updated(Matrix())
elif prop.name == "vadjustment":
if value is not None:
if self.vadjustment and self._vadjustment_handler_id:
self.vadjustment.disconnect(self._vadjustment_handler_id)
self.vadjustment = value
self._vadjustment_handler_id = self.vadjustment.connect(
"value-changed", self.on_adjustment_changed
"value-changed", self.on_vadjustment_changed
)
self._scrolling_updated(Matrix())
elif prop.name == "hscroll-policy":
self.hscroll_policy = value
elif prop.name == "vscroll-policy":
@ -61,8 +58,7 @@ class Scrolling:
raise AttributeError(f"Unknown property {prop.name}")
def update_adjustments(self, width: int, height: int, bounds: Rectangle) -> None:
"""Update scroll bar values (adjustments in GTK), and reset the scroll
value to 0.
"""Update scroll bar values (adjustments in GTK).
The value will change when a scroll bar is moved.
"""
@ -72,36 +68,21 @@ class Scrolling:
u = c + Rectangle(width=width, height=height)
if self.hadjustment:
self.hadjustment.set_value(0)
self.hadjustment.set_lower(u.x)
self.hadjustment.set_upper(u.x1)
self.hadjustment.set_step_increment(width // 10)
self.hadjustment.set_page_increment(width)
self.hadjustment.set_page_size(width)
self._last_hvalue = 0
if self.vadjustment:
self.vadjustment.set_value(0)
self.vadjustment.set_lower(u.y)
self.vadjustment.set_upper(u.y1)
self.vadjustment.set_step_increment(height // 10)
self.vadjustment.set_page_increment(height)
self.vadjustment.set_page_size(height)
self._last_vvalue = 0
def on_adjustment_changed(self, adj):
"""Change the transformation matrix of the view to reflect the value of
the x/y adjustment (scrollbar)."""
value = adj.get_value()
if value == 0:
return
def on_hadjustment_changed(self, adj):
self._scrolling_updated(adj.get_value(), None)
m = Matrix()
if adj is self.hadjustment:
m.translate(self._last_hvalue - value, 0)
self._last_hvalue = value
elif adj is self.vadjustment:
m.translate(0, self._last_vvalue - value)
self._last_vvalue = value
self._scrolling_updated(m)
def on_vadjustment_changed(self, adj):
self._scrolling_updated(None, adj.get_value())