From da3747c5f5ef104a9b2897946e5f35743516086c Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:45:16 +0100 Subject: [PATCH 1/3] Implement autoscroll in project tree, and disable library autoscroll feature (#1561) --- novelwriter/gui/projtree.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 9ac115b4..e1fd6533 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -31,8 +31,8 @@ from enum import Enum from time import time from typing import TYPE_CHECKING -from PyQt5.QtGui import QDropEvent, QMouseEvent, QPalette -from PyQt5.QtCore import QPoint, Qt, QSize, pyqtSignal, pyqtSlot +from PyQt5.QtGui import QDragMoveEvent, QDropEvent, QMouseEvent, QPalette +from PyQt5.QtCore import QPoint, QTimer, Qt, QSize, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QFrame, QHBoxLayout, QHeaderView, QLabel, QMenu, QShortcut, QSizePolicy, QToolButton, QTreeWidget, QTreeWidgetItem, @@ -508,6 +508,7 @@ class GuiProjectTree(QTreeWidget): self.setDragEnabled(True) self.setDragDropMode(QAbstractItemView.InternalMove) self.setDropIndicatorShown(True) + self.setAutoScroll(False) # But don't allow drop on root level # Due to a bug, this stops working somewhere between Qt 5.15.3 @@ -527,6 +528,13 @@ class GuiProjectTree(QTreeWidget): self.itemDoubleClicked.connect(self._treeDoubleClick) self.itemSelectionChanged.connect(self._treeSelectionChange) + # Autoscroll + self._scrollMargin = SHARED.theme.baseIconSize + self._scrollDirection = 0 + self._scrollTimer = QTimer() + self._scrollTimer.timeout.connect(self._doAutoScroll) + self._scrollTimer.setInterval(250) + # Set custom settings self.initSettings() @@ -1346,6 +1354,17 @@ class GuiProjectTree(QTreeWidget): return True + @pyqtSlot() + def _doAutoScroll(self) -> None: + """Scroll one item up or down based on direction value.""" + if self._scrollDirection == -1: + self.scrollToItem(self.itemAbove(self.itemAt(1, 1))) + elif self._scrollDirection == 1: + self.scrollToItem(self.itemBelow(self.itemAt(1, self.height() - 1))) + self._scrollDirection = 0 + self._scrollTimer.stop() + return + ## # Events ## @@ -1377,6 +1396,20 @@ class GuiProjectTree(QTreeWidget): return + def dragMoveEvent(self, event: QDragMoveEvent) -> None: + """Capture the drag move event to enable edge autoscroll.""" + y = event.pos().y() + if y < 16: + if not self._scrollTimer.isActive(): + self._scrollDirection = -1 + self._scrollTimer.start() + elif y > self.height() - 16: + if not self._scrollTimer.isActive(): + self._scrollDirection = 1 + self._scrollTimer.start() + super().dragMoveEvent(event) + return + def dropEvent(self, event: QDropEvent) -> None: """Overload the drop item event to ensure relevant data has been updated. From 05ddca043a4d7f437f63571a1131dc2f4504f243 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:48:22 +0100 Subject: [PATCH 2/3] Add comment to explain why autoscroll was added --- novelwriter/gui/projtree.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index e1fd6533..89cd4e72 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -508,11 +508,14 @@ class GuiProjectTree(QTreeWidget): self.setDragEnabled(True) self.setDragDropMode(QAbstractItemView.InternalMove) self.setDropIndicatorShown(True) + + # Disable built-in autoscroll as it isn't working in some Qt + # releases (see #1561) and instead use our own implementation self.setAutoScroll(False) # But don't allow drop on root level # Due to a bug, this stops working somewhere between Qt 5.15.3 - # and 5.15.8, so this is also blocked in dropEvent + # and 5.15.8, so this is also blocked in dropEvent (see #1569) trRoot = self.invisibleRootItem() trRoot.setFlags(trRoot.flags() ^ Qt.ItemIsDropEnabled) From 6f8109609cb7bb5984c103ba2a6dd20c5193503b Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 4 Nov 2023 16:50:41 +0100 Subject: [PATCH 3/3] Use the correct margin settings --- novelwriter/gui/projtree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 89cd4e72..31d2ca12 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -1402,11 +1402,11 @@ class GuiProjectTree(QTreeWidget): def dragMoveEvent(self, event: QDragMoveEvent) -> None: """Capture the drag move event to enable edge autoscroll.""" y = event.pos().y() - if y < 16: + if y < self._scrollMargin: if not self._scrollTimer.isActive(): self._scrollDirection = -1 self._scrollTimer.start() - elif y > self.height() - 16: + elif y > self.height() - self._scrollMargin: if not self._scrollTimer.isActive(): self._scrollDirection = 1 self._scrollTimer.start()