launcher is using projects widget from utils

This commit is contained in:
Jakub Trllo 2025-06-18 13:44:04 +02:00
parent 7e29ac8377
commit 53803f040d
2 changed files with 41 additions and 159 deletions

View file

@ -1,154 +0,0 @@
from qtpy import QtWidgets, QtCore
from ayon_core.tools.flickcharm import FlickCharm
from ayon_core.tools.utils import (
PlaceholderLineEdit,
RefreshButton,
ProjectsQtModel,
ProjectSortFilterProxy,
)
from ayon_core.tools.common_models import PROJECTS_MODEL_SENDER
class ProjectIconView(QtWidgets.QListView):
"""Styled ListView that allows to toggle between icon and list mode.
Toggling between the two modes is done by Right Mouse Click.
"""
IconMode = 0
ListMode = 1
def __init__(self, parent=None, mode=ListMode):
super(ProjectIconView, self).__init__(parent=parent)
# Workaround for scrolling being super slow or fast when
# toggling between the two visual modes
self.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.setObjectName("IconView")
self._mode = None
self.set_mode(mode)
def set_mode(self, mode):
if mode == self._mode:
return
self._mode = mode
if mode == self.IconMode:
self.setViewMode(QtWidgets.QListView.IconMode)
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setWrapping(True)
self.setWordWrap(True)
self.setGridSize(QtCore.QSize(151, 90))
self.setIconSize(QtCore.QSize(50, 50))
self.setSpacing(0)
self.setAlternatingRowColors(False)
self.setProperty("mode", "icon")
self.style().polish(self)
self.verticalScrollBar().setSingleStep(30)
elif self.ListMode:
self.setProperty("mode", "list")
self.style().polish(self)
self.setViewMode(QtWidgets.QListView.ListMode)
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setWrapping(False)
self.setWordWrap(False)
self.setIconSize(QtCore.QSize(20, 20))
self.setGridSize(QtCore.QSize(100, 25))
self.setSpacing(0)
self.setAlternatingRowColors(False)
self.verticalScrollBar().setSingleStep(34)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.RightButton:
self.set_mode(int(not self._mode))
return super(ProjectIconView, self).mousePressEvent(event)
class ProjectsWidget(QtWidgets.QWidget):
"""Projects Page"""
refreshed = QtCore.Signal()
def __init__(self, controller, parent=None):
super(ProjectsWidget, self).__init__(parent=parent)
header_widget = QtWidgets.QWidget(self)
projects_filter_text = PlaceholderLineEdit(header_widget)
projects_filter_text.setPlaceholderText("Filter projects...")
refresh_btn = RefreshButton(header_widget)
header_layout = QtWidgets.QHBoxLayout(header_widget)
header_layout.setContentsMargins(0, 0, 0, 0)
header_layout.addWidget(projects_filter_text, 1)
header_layout.addWidget(refresh_btn, 0)
projects_view = ProjectIconView(parent=self)
projects_view.setSelectionMode(QtWidgets.QListView.NoSelection)
flick = FlickCharm(parent=self)
flick.activateOn(projects_view)
projects_model = ProjectsQtModel(controller)
projects_proxy_model = ProjectSortFilterProxy()
projects_proxy_model.setSourceModel(projects_model)
projects_view.setModel(projects_proxy_model)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.addWidget(header_widget, 0)
main_layout.addWidget(projects_view, 1)
projects_view.clicked.connect(self._on_view_clicked)
projects_model.refreshed.connect(self.refreshed)
projects_filter_text.textChanged.connect(
self._on_project_filter_change)
refresh_btn.clicked.connect(self._on_refresh_clicked)
controller.register_event_callback(
"projects.refresh.finished",
self._on_projects_refresh_finished
)
self._controller = controller
self._projects_view = projects_view
self._projects_model = projects_model
self._projects_proxy_model = projects_proxy_model
def has_content(self):
"""Model has at least one project.
Returns:
bool: True if there is any content in the model.
"""
return self._projects_model.has_content()
def _on_view_clicked(self, index):
if not index.isValid():
return
model = index.model()
flags = model.flags(index)
if not flags & QtCore.Qt.ItemIsEnabled:
return
project_name = index.data(QtCore.Qt.DisplayRole)
self._controller.set_selected_project(project_name)
def _on_project_filter_change(self, text):
self._projects_proxy_model.setFilterFixedString(text)
def _on_refresh_clicked(self):
self._controller.refresh()
def _on_projects_refresh_finished(self, event):
if event["sender"] != PROJECTS_MODEL_SENDER:
self._projects_model.refresh()

View file

@ -3,9 +3,13 @@ from qtpy import QtWidgets, QtCore, QtGui
from ayon_core import style, resources
from ayon_core.tools.launcher.control import BaseLauncherController
from ayon_core.tools.utils import MessageOverlayObject
from ayon_core.tools.utils import (
MessageOverlayObject,
PlaceholderLineEdit,
RefreshButton,
ProjectsWidget,
)
from .projects_widget import ProjectsWidget
from .hierarchy_page import HierarchyPage
from .actions_widget import ActionsWidget
@ -50,7 +54,25 @@ class LauncherWindow(QtWidgets.QWidget):
pages_widget = QtWidgets.QWidget(content_body)
# - First page - Projects
projects_page = ProjectsWidget(controller, pages_widget)
projects_page = QtWidgets.QWidget(pages_widget)
projects_header_widget = QtWidgets.QWidget(projects_page)
projects_filter_text = PlaceholderLineEdit(projects_header_widget)
projects_filter_text.setPlaceholderText("Filter projects...")
refresh_btn = RefreshButton(projects_header_widget)
projects_header_layout = QtWidgets.QHBoxLayout(projects_header_widget)
projects_header_layout.setContentsMargins(0, 0, 0, 0)
projects_header_layout.addWidget(projects_filter_text, 1)
projects_header_layout.addWidget(refresh_btn, 0)
projects_widget = ProjectsWidget(controller, pages_widget)
projects_layout = QtWidgets.QVBoxLayout(projects_page)
projects_layout.setContentsMargins(0, 0, 0, 0)
projects_layout.addWidget(projects_header_widget, 0)
projects_layout.addWidget(projects_widget, 1)
# - Second page - Hierarchy (folders & tasks)
hierarchy_page = HierarchyPage(controller, pages_widget)
@ -102,12 +124,16 @@ class LauncherWindow(QtWidgets.QWidget):
page_slide_anim.setEndValue(1.0)
page_slide_anim.setEasingCurve(QtCore.QEasingCurve.OutQuad)
projects_page.refreshed.connect(self._on_projects_refresh)
refresh_btn.clicked.connect(self._on_refresh_request)
projects_widget.refreshed.connect(self._on_projects_refresh)
actions_refresh_timer.timeout.connect(
self._on_actions_refresh_timeout)
page_slide_anim.valueChanged.connect(
self._on_page_slide_value_changed)
page_slide_anim.finished.connect(self._on_page_slide_finished)
projects_filter_text.textChanged.connect(
self._on_project_filter_change)
controller.register_event_callback(
"selection.project.changed",
@ -142,6 +168,7 @@ class LauncherWindow(QtWidgets.QWidget):
self._pages_widget = pages_widget
self._pages_layout = pages_layout
self._projects_page = projects_page
self._projects_widget = projects_widget
self._hierarchy_page = hierarchy_page
self._actions_widget = actions_widget
# self._action_history = action_history
@ -194,6 +221,12 @@ class LauncherWindow(QtWidgets.QWidget):
elif self._is_on_projects_page:
self._go_to_hierarchy_page(project_name)
def _on_project_filter_change(self, text):
self._projects_widget.set_name_filter(text)
def _on_refresh_request(self):
self._controller.refresh()
def _on_projects_refresh(self):
# Refresh only actions on projects page
if self._is_on_projects_page:
@ -201,7 +234,7 @@ class LauncherWindow(QtWidgets.QWidget):
return
# No projects were found -> go back to projects page
if not self._projects_page.has_content():
if not self._projects_widget.has_content():
self._go_to_projects_page()
return
@ -280,6 +313,9 @@ class LauncherWindow(QtWidgets.QWidget):
def _go_to_projects_page(self):
if self._is_on_projects_page:
return
# Deselect project in projects widget
self._projects_widget.set_selected_project(None)
self._is_on_projects_page = True
self._hierarchy_page.set_page_visible(False)