Compare commits

..

No commits in common. "ac0d4fec8a3197c5a5ecca404deb1d06bca8e11a" and "a930cffe39a188fcca5ce8146df33021dc03036f" have entirely different histories.

11 changed files with 15 additions and 207 deletions

View File

@ -2,4 +2,3 @@ black == 23.7.0
isort == 5.12.0
imageio==2.31.4
Nuitka==1.8.4
pytest==7.4.3

View File

View File

View File

@ -1,31 +0,0 @@
from ui.navigation.navhost import NavHost
from ui.navigation.navitem import NavItem
class TestNavHost:
def test_auto_append_parent(self):
navHost = NavHost()
navHost.registerNavItem(NavItem(id="aaa.bbb.ccc.ddd"))
navItems = navHost.navItems
assert NavItem(id="aaa.bbb.ccc.ddd") in navItems
assert NavItem(id="aaa.bbb.ccc") in navItems
assert NavItem(id="aaa.bbb") in navItems
assert NavItem(id="aaa") in navItems
def test_auto_select_child(self):
navHost = NavHost()
navHost.registerNavItem(NavItem(id="aaa"))
navHost.registerNavItem(NavItem(id="bbb"))
assert navHost.currentNavItem.id == "aaa"
navHost.registerNavItem(NavItem(id="aaa.bbb"))
navHost.registerNavItem(NavItem(id="aaa.ccc"))
navHost.navigate("aaa")
assert navHost.currentNavItem.id == "aaa.bbb"

View File

@ -1,47 +0,0 @@
from PySide6.QtWidgets import QWidget
from ui.navigation.navhost import NavHost, navHost
from ui.navigation.navitem import NavItem
from ui.navigation.navitemwidgets import NavItemWidgets
from ui.widgets.slidingstackedwidget import SlidingStackedWidget
class AnimatedStackedNavItemsWidgets(SlidingStackedWidget):
def __init__(
self, navItemWidgets: NavItemWidgets, navHost: NavHost = navHost, parent=None
):
super().__init__(parent)
self.navItemWidgets = navItemWidgets
self.navHost = navHost
self.navHost.activated.connect(self.__switchTo)
self.animationFinished.connect(self.endChangingWidget)
def __switchTo(self, oldNavItem: NavItem, newNavItem: NavItem):
oldNavItemDepth = self.navHost.getNavItemDepth(oldNavItem.id)
newNavItemDepth = self.navHost.getNavItemDepth(newNavItem.id)
if oldNavItemDepth != newNavItemDepth:
slidingDirection = (
self.slidingDirection.RightToLeft
if newNavItemDepth > oldNavItemDepth
else self.slidingDirection.LeftToRight
)
else:
slidingDirection = self.slidingDirection.TopToBottom
newWidget = self.navItemWidgets.get(newNavItem.id) or QWidget()
self.startChangingWidget(newWidget, slidingDirection)
def startChangingWidget(self, newWidget: QWidget, slidingDirection):
newIndex = self.addWidget(newWidget)
[self.widget(i).setEnabled(False) for i in range(self.count())]
self.slideInIdx(newIndex, slidingDirection)
def endChangingWidget(self):
oldWidget = self.widget(0)
self.removeWidget(oldWidget)
newWidget = self.widget(0)
newWidget.setEnabled(True)

View File

@ -1,4 +1,4 @@
from PySide6.QtCore import QModelIndex, Qt, Signal, Slot
from PySide6.QtCore import QModelIndex, Qt, Slot
from PySide6.QtGui import QFont, QIcon, QKeySequence, QShortcut
from PySide6.QtWidgets import (
QListWidget,
@ -8,7 +8,7 @@ from PySide6.QtWidgets import (
QWidget,
)
from ui.navigation.navhost import NavHost, NavItem, navHost
from ui.navigation.navhost import NavItem, navHost
from ui.widgets.slidingstackedwidget import SlidingStackedWidget
@ -69,14 +69,18 @@ class NavigationWidget(QWidget):
class NavigationSideBar(QWidget):
navItemActivated = Signal(NavItem)
def __init__(self, parent=None, navHost=navHost):
def __init__(self, parent=None):
super().__init__(parent)
self.navHost = None
self.navHost = navHost
navHost.navItemsChanged.connect(self.reloadNavWidget)
navHost.activated.connect(self.navItemActivated)
self.navigateUpKeyboardShortcut = QShortcut(
QKeySequence(Qt.Modifier.ALT | Qt.Key.Key_Left), self, lambda: True
QKeySequence(Qt.Modifier.ALT | Qt.Key.Key_Left),
self,
self.navHost.navigateUp,
)
self.verticalLayout = QVBoxLayout(self)
@ -84,6 +88,7 @@ class NavigationSideBar(QWidget):
self.navigateUpButton = QPushButton(QIcon(":/icons/back.svg"), "")
self.navigateUpButton.setFlat(True)
self.navigateUpButton.setFixedHeight(20)
self.navigateUpButton.clicked.connect(self.navHost.navigateUp)
self.verticalLayout.addWidget(self.navigateUpButton)
self.slidingStackedWidget = SlidingStackedWidget(self)
@ -96,29 +101,11 @@ class NavigationSideBar(QWidget):
navItemListWidget.activated.connect(self.navItemListWidgetActivatedProxy)
self.slidingStackedWidget.addWidget(navItemListWidget)
self.setNavHost(navHost)
self.reloadNavWidget()
def setNavHost(self, navHost: NavHost):
if self.navHost is not None:
self.navHost.navItemsChanged.disconnect(self.reloadNavWidget)
self.navHost.activated.disconnect(self.navItemChanged)
self.navigateUpKeyboardShortcut.activated.disconnect(
self.navHost.navigateUp
)
self.navigateUpButton.clicked.disconnect(self.navHost.navigateUp)
self.navHost = navHost
self.navHost.navItemsChanged.connect(self.reloadNavWidget)
self.navHost.activated.connect(self.navItemChanged)
self.navigateUpKeyboardShortcut.activated.connect(self.navHost.navigateUp)
self.navigateUpButton.clicked.connect(self.navHost.navigateUp)
@Slot(QModelIndex)
def navItemListWidgetActivatedProxy(self, index: QModelIndex):
self.navHost.navigate(index.data(NavItemListWidget.NavItemRole).id)
self.navItemActivated.emit(index.data(NavItemListWidget.NavItemRole))
def fillNavItemListWidget(
self, currentNavItem: NavItem, listWidget: NavItemListWidget
@ -136,10 +123,10 @@ class NavigationSideBar(QWidget):
self.fillNavItemListWidget(
self.navHost.currentNavItem, self.slidingStackedWidget.widget(0)
)
self.navItemChanged(self.navHost.currentNavItem, self.navHost.currentNavItem)
self.navItemActivated(self.navHost.currentNavItem, self.navHost.currentNavItem)
@Slot(NavItem, NavItem)
def navItemChanged(self, oldNavItem: NavItem, newNavItem: NavItem):
def navItemActivated(self, oldNavItem: NavItem, newNavItem: NavItem):
# update navigateUpButton text
if newNavItemParent := self.navHost.getNavItemRelatives(newNavItem.id).parent:
self.navigateUpButton.setText(newNavItemParent.text())

View File

@ -24,23 +24,11 @@ class NavHost(QObject):
super().__init__(parent)
self.__navItems: list[NavItem] = []
self.__cachedNavItems: list[NavItem] = []
self.__currentNavItem: NavItem = None
def __flushCachedNavItems(self):
navItems = set(self.__navItems)
for item in self.__navItems:
parts = item.id.split(".")
for i in range(1, len(parts)):
parentItemId = ".".join(parts[:i])
navItems.add(NavItem(id=parentItemId))
self.__cachedNavItems = list(navItems)
@property
def navItems(self) -> list[NavItem]:
return self.__cachedNavItems
return self.__navItems
@property
def currentNavItem(self) -> NavItem:
@ -113,7 +101,6 @@ class NavHost(QObject):
def registerNavItem(self, item: NavItem):
self.__navItems.append(item)
self.__flushCachedNavItems()
self.navItemsChanged.emit()
def navigate(self, navItemId: str):

View File

@ -12,6 +12,3 @@ class NavItem:
def text(self):
return QCoreApplication.translate("NavItem", f"{self.id}.title")
def __hash__(self):
return hash(self.id)

View File

@ -1,84 +0,0 @@
from PySide6.QtCore import QObject
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QLabel, QSizePolicy, QSpacerItem, QVBoxLayout, QWidget
from ui.navigation.navhost import NavHost, navHost
from ui.navigation.navitem import NavItem
from ui.navigation.navsidebar import NavigationSideBar
class DefaultParentNavItemWidget(QWidget):
def __init__(self, navItem: NavItem, navItemChildren: list[NavItem], parent=None):
super().__init__(parent)
self.navItem = navItem
self.partialNavHost = NavHost(self)
self.partialNavHost.registerNavItem(navItem)
for _navItem in navItemChildren:
self.partialNavHost.registerNavItem(_navItem)
self.partialNavHost.navigate(navItem.id)
self.verticalLayout = QVBoxLayout(self)
self.navItemLabelFont = QFont(self.font())
self.navItemLabelFont.setPointSize(14)
self.navItemLabel = QLabel(self)
self.navItemLabel.setFont(self.navItemLabelFont)
spacer = QSpacerItem(
20, 20, QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding
)
self.verticalLayout.addSpacerItem(spacer)
self.navSideBar = NavigationSideBar(self, self.partialNavHost)
self.navSideBar.navigateUpButton.setEnabled(False)
self.verticalLayout.addWidget(self.navSideBar)
self.verticalLayout.addSpacerItem(spacer)
self.retranslateUi()
def retranslateUi(self):
self.navItemLabel.setText(self.navItem.text())
class NavItemWidgets(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.__map: dict[str, QWidget] = {}
# this reference holds all the `DefaultParentNavItemWidget`s
# since these widgets are created with no parents, not keeping a reference to
# them may result in errors, even a silent app crash that is hard to debug
self.__defaultParentWidgetRefs: dict[str, QWidget] = {}
def register(self, navItemId: str, widget: QWidget):
self.__map[navItemId] = widget
def unregister(self, navItemId: str) -> bool:
try:
widget = self.__map.pop(navItemId)
widget.deleteLater()
return True
except KeyError:
return False
def get(self, navItemId: str) -> QWidget | None:
widget = self.__map.get(navItemId)
if widget is not None:
return widget
elif navItemChildren := navHost.getNavItemRelatives(navItemId).children:
if self.__defaultParentWidgetRefs.get(navItemId) is None:
defaultParentNavItemWidget = DefaultParentNavItemWidget(
navHost.findNavItem(navItemId), navItemChildren
)
self.__defaultParentWidgetRefs[navItemId] = defaultParentNavItemWidget
defaultParentNavItemWidget.partialNavHost.activated.connect(
lambda o, n: navHost.navigate(n.id)
)
return self.__defaultParentWidgetRefs.get(navItemId)
else:
return None