mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-04-22 02:30:18 +00:00
Compare commits
No commits in common. "ac0d4fec8a3197c5a5ecca404deb1d06bca8e11a" and "a930cffe39a188fcca5ce8146df33021dc03036f" have entirely different histories.
ac0d4fec8a
...
a930cffe39
@ -2,4 +2,3 @@ black == 23.7.0
|
|||||||
isort == 5.12.0
|
isort == 5.12.0
|
||||||
imageio==2.31.4
|
imageio==2.31.4
|
||||||
Nuitka==1.8.4
|
Nuitka==1.8.4
|
||||||
pytest==7.4.3
|
|
||||||
|
@ -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"
|
|
@ -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)
|
|
@ -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.QtGui import QFont, QIcon, QKeySequence, QShortcut
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QListWidget,
|
QListWidget,
|
||||||
@ -8,7 +8,7 @@ from PySide6.QtWidgets import (
|
|||||||
QWidget,
|
QWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ui.navigation.navhost import NavHost, NavItem, navHost
|
from ui.navigation.navhost import NavItem, navHost
|
||||||
from ui.widgets.slidingstackedwidget import SlidingStackedWidget
|
from ui.widgets.slidingstackedwidget import SlidingStackedWidget
|
||||||
|
|
||||||
|
|
||||||
@ -69,14 +69,18 @@ class NavigationWidget(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
class NavigationSideBar(QWidget):
|
class NavigationSideBar(QWidget):
|
||||||
navItemActivated = Signal(NavItem)
|
def __init__(self, parent=None):
|
||||||
|
|
||||||
def __init__(self, parent=None, navHost=navHost):
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.navHost = None
|
self.navHost = navHost
|
||||||
|
|
||||||
|
navHost.navItemsChanged.connect(self.reloadNavWidget)
|
||||||
|
navHost.activated.connect(self.navItemActivated)
|
||||||
|
|
||||||
self.navigateUpKeyboardShortcut = QShortcut(
|
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)
|
self.verticalLayout = QVBoxLayout(self)
|
||||||
@ -84,6 +88,7 @@ class NavigationSideBar(QWidget):
|
|||||||
self.navigateUpButton = QPushButton(QIcon(":/icons/back.svg"), "")
|
self.navigateUpButton = QPushButton(QIcon(":/icons/back.svg"), "")
|
||||||
self.navigateUpButton.setFlat(True)
|
self.navigateUpButton.setFlat(True)
|
||||||
self.navigateUpButton.setFixedHeight(20)
|
self.navigateUpButton.setFixedHeight(20)
|
||||||
|
self.navigateUpButton.clicked.connect(self.navHost.navigateUp)
|
||||||
self.verticalLayout.addWidget(self.navigateUpButton)
|
self.verticalLayout.addWidget(self.navigateUpButton)
|
||||||
|
|
||||||
self.slidingStackedWidget = SlidingStackedWidget(self)
|
self.slidingStackedWidget = SlidingStackedWidget(self)
|
||||||
@ -96,29 +101,11 @@ class NavigationSideBar(QWidget):
|
|||||||
navItemListWidget.activated.connect(self.navItemListWidgetActivatedProxy)
|
navItemListWidget.activated.connect(self.navItemListWidgetActivatedProxy)
|
||||||
self.slidingStackedWidget.addWidget(navItemListWidget)
|
self.slidingStackedWidget.addWidget(navItemListWidget)
|
||||||
|
|
||||||
self.setNavHost(navHost)
|
|
||||||
self.reloadNavWidget()
|
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)
|
@Slot(QModelIndex)
|
||||||
def navItemListWidgetActivatedProxy(self, index: QModelIndex):
|
def navItemListWidgetActivatedProxy(self, index: QModelIndex):
|
||||||
self.navHost.navigate(index.data(NavItemListWidget.NavItemRole).id)
|
self.navHost.navigate(index.data(NavItemListWidget.NavItemRole).id)
|
||||||
self.navItemActivated.emit(index.data(NavItemListWidget.NavItemRole))
|
|
||||||
|
|
||||||
def fillNavItemListWidget(
|
def fillNavItemListWidget(
|
||||||
self, currentNavItem: NavItem, listWidget: NavItemListWidget
|
self, currentNavItem: NavItem, listWidget: NavItemListWidget
|
||||||
@ -136,10 +123,10 @@ class NavigationSideBar(QWidget):
|
|||||||
self.fillNavItemListWidget(
|
self.fillNavItemListWidget(
|
||||||
self.navHost.currentNavItem, self.slidingStackedWidget.widget(0)
|
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)
|
@Slot(NavItem, NavItem)
|
||||||
def navItemChanged(self, oldNavItem: NavItem, newNavItem: NavItem):
|
def navItemActivated(self, oldNavItem: NavItem, newNavItem: NavItem):
|
||||||
# update navigateUpButton text
|
# update navigateUpButton text
|
||||||
if newNavItemParent := self.navHost.getNavItemRelatives(newNavItem.id).parent:
|
if newNavItemParent := self.navHost.getNavItemRelatives(newNavItem.id).parent:
|
||||||
self.navigateUpButton.setText(newNavItemParent.text())
|
self.navigateUpButton.setText(newNavItemParent.text())
|
@ -24,23 +24,11 @@ class NavHost(QObject):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.__navItems: list[NavItem] = []
|
self.__navItems: list[NavItem] = []
|
||||||
self.__cachedNavItems: list[NavItem] = []
|
|
||||||
self.__currentNavItem: NavItem = None
|
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
|
@property
|
||||||
def navItems(self) -> list[NavItem]:
|
def navItems(self) -> list[NavItem]:
|
||||||
return self.__cachedNavItems
|
return self.__navItems
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def currentNavItem(self) -> NavItem:
|
def currentNavItem(self) -> NavItem:
|
||||||
@ -113,7 +101,6 @@ class NavHost(QObject):
|
|||||||
|
|
||||||
def registerNavItem(self, item: NavItem):
|
def registerNavItem(self, item: NavItem):
|
||||||
self.__navItems.append(item)
|
self.__navItems.append(item)
|
||||||
self.__flushCachedNavItems()
|
|
||||||
self.navItemsChanged.emit()
|
self.navItemsChanged.emit()
|
||||||
|
|
||||||
def navigate(self, navItemId: str):
|
def navigate(self, navItemId: str):
|
||||||
|
@ -12,6 +12,3 @@ class NavItem:
|
|||||||
|
|
||||||
def text(self):
|
def text(self):
|
||||||
return QCoreApplication.translate("NavItem", f"{self.id}.title")
|
return QCoreApplication.translate("NavItem", f"{self.id}.title")
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
return hash(self.id)
|
|
||||||
|
@ -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
|
|
Loading…
x
Reference in New Issue
Block a user