While a track drag hovers within 28px of the track list's top/bottom edge, the list scrolls that way (40ms timer) so the user can drop onto off-screen rows. Qt's built-in autoscroll never fires because our dragMoveEvent accepts the event itself, so this is driven manually; the drop line refreshes as content scrolls under a stationary cursor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
"""Round 13: drag auto-scroll.
|
|
|
|
While dragging a track near the top/bottom edge of the list, it scrolls in
|
|
that direction so off-screen rows can be reached. Qt's built-in autoscroll
|
|
never runs (our dragMoveEvent accepts the event itself), so this is manual.
|
|
"""
|
|
|
|
from PyQt6.QtCore import QPoint
|
|
|
|
from lintunes.gui.track_table import TrackTableView, autoscroll_direction
|
|
|
|
|
|
class TestAutoscrollDirection:
|
|
def test_top_edge_scrolls_up(self):
|
|
assert autoscroll_direction(5, height=200, accepted=True) == -1
|
|
|
|
def test_bottom_edge_scrolls_down(self):
|
|
assert autoscroll_direction(195, height=200, accepted=True) == 1
|
|
|
|
def test_middle_does_not_scroll(self):
|
|
assert autoscroll_direction(100, height=200, accepted=True) == 0
|
|
|
|
def test_not_a_drop_target_never_scrolls(self):
|
|
assert autoscroll_direction(5, height=200, accepted=False) == 0
|
|
assert autoscroll_direction(195, height=200, accepted=False) == 0
|
|
|
|
|
|
class TestAutoscrollTick:
|
|
def test_tick_scrolls_by_direction(self, qapp):
|
|
view = TrackTableView(playlist_mode=True)
|
|
bar = view.verticalScrollBar()
|
|
bar.setRange(0, 50)
|
|
bar.setValue(10)
|
|
|
|
view._autoscroll_dir = 1
|
|
view._autoscroll_tick()
|
|
assert bar.value() == 11
|
|
|
|
view._autoscroll_dir = -1
|
|
view._autoscroll_tick()
|
|
assert bar.value() == 10
|
|
|
|
def test_tick_stops_at_the_end(self, qapp):
|
|
view = TrackTableView(playlist_mode=True)
|
|
bar = view.verticalScrollBar()
|
|
bar.setRange(0, 50)
|
|
bar.setValue(50) # already at the bottom
|
|
|
|
view._autoscroll_dir = 1
|
|
view._autoscroll_timer.start()
|
|
view._autoscroll_tick()
|
|
|
|
assert bar.value() == 50
|
|
assert not view._autoscroll_timer.isActive()
|
|
|
|
|
|
class TestUpdateAutoscroll:
|
|
def test_rejected_drop_keeps_timer_off(self, qapp):
|
|
view = TrackTableView(playlist_mode=True)
|
|
view._update_autoscroll(QPoint(10, 5), accepted=False)
|
|
assert view._autoscroll_dir == 0
|
|
assert not view._autoscroll_timer.isActive()
|
|
|
|
def test_stop_autoscroll_resets(self, qapp):
|
|
view = TrackTableView(playlist_mode=True)
|
|
view._autoscroll_dir = 1
|
|
view._autoscroll_timer.start()
|
|
view._stop_autoscroll()
|
|
assert view._autoscroll_dir == 0
|
|
assert view._autoscroll_pos is None
|
|
assert not view._autoscroll_timer.isActive()
|