Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tools: Use material symbols in UIs #593

Merged
merged 32 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d10cf78
baseic implementation of Material Symobls
iLLiCiTiT Jun 2, 2024
8f83fa5
Projects model has folder and task type items
iLLiCiTiT Jun 2, 2024
22b6663
folder and task icon is not set on their items
iLLiCiTiT Jun 2, 2024
c2217f8
added implementation to get material symbols icon
iLLiCiTiT Jun 2, 2024
6c21d53
modified folders and tasks widget to be able use icons from items
iLLiCiTiT Jun 2, 2024
d2b77bb
use icons in launcher
iLLiCiTiT Jun 2, 2024
a733273
use icons in loader
iLLiCiTiT Jun 2, 2024
160a23d
removed unnecessary line
iLLiCiTiT Jun 2, 2024
1562170
added new methods to abstract controller
iLLiCiTiT Jun 2, 2024
345ed2e
context dialog shows AYON icons
iLLiCiTiT Jun 2, 2024
715a1d3
workfiles tool shows AYON icons
iLLiCiTiT Jun 2, 2024
c3a23a3
initial change in publisher
iLLiCiTiT Jun 2, 2024
c5bc4ff
added icons to tasks combobox
iLLiCiTiT Jun 2, 2024
12494d3
initial logic for status icons
iLLiCiTiT Jun 2, 2024
964b982
fix bug
iLLiCiTiT Jun 5, 2024
337cbd6
paint icon in status delegate
iLLiCiTiT Jun 5, 2024
92dd4fb
status delegate full implementation
iLLiCiTiT Jun 6, 2024
18e27a5
scenemanager shows icons of status in view
iLLiCiTiT Jun 6, 2024
893a075
Merge branch 'develop' into feature/material-symbols-in-uis
iLLiCiTiT Jun 6, 2024
eb9aca2
Merge branch 'develop' into feature/material-symbols-in-uis
iLLiCiTiT Jun 8, 2024
266ea1d
move vendor
iLLiCiTiT Jun 8, 2024
ace46cd
add icon to select version dialog
iLLiCiTiT Jun 8, 2024
34faa28
don't use QColor when calling 'get_qt_icon'
iLLiCiTiT Jun 10, 2024
909b6b9
fix option initialization
iLLiCiTiT Jun 10, 2024
2ff21e3
add icons to simple folders widget
iLLiCiTiT Jun 10, 2024
4264af6
use 'QtGui' to get 'QPalette'
iLLiCiTiT Jun 10, 2024
c622fb3
Merge branch 'develop' into feature/material-symbols-in-uis
iLLiCiTiT Jun 10, 2024
038b97e
paint status icon in combobox
iLLiCiTiT Jun 10, 2024
6ef2618
Merge branch 'develop' into feature/material-symbols-in-uis
iLLiCiTiT Jun 14, 2024
03db989
Merge branch 'develop' into feature/material-symbols-in-uis
iLLiCiTiT Jun 17, 2024
7c88ac7
use height of font to determine icon size
iLLiCiTiT Jun 17, 2024
085f746
Merge branch 'develop' into feature/material-symbols-in-uis
iLLiCiTiT Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 5 additions & 27 deletions client/ayon_core/tools/common_models/hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import ayon_api
import six

from ayon_core.style import get_default_entity_icon_color
from ayon_core.lib import NestedCacheItem

HIERARCHY_MODEL_SENDER = "hierarchy.model"
Expand All @@ -31,25 +30,17 @@ class FolderItem:
path (str): Folder path.
folder_type (str): Type of folder.
label (Union[str, None]): Folder label.
icon (Union[dict[str, Any], None]): Icon definition.
"""

def __init__(
self, entity_id, parent_id, name, path, folder_type, label, icon
self, entity_id, parent_id, name, path, folder_type, label
):
self.entity_id = entity_id
self.parent_id = parent_id
self.name = name
self.path = path
self.folder_type = folder_type
self.label = label or name
if not icon:
icon = {
"type": "awesome-font",
"name": "fa.folder",
"color": get_default_entity_icon_color()
}
self.icon = icon

def to_data(self):
"""Converts folder item to data.
Expand All @@ -65,7 +56,6 @@ def to_data(self):
"path": self.path,
"folder_type": self.folder_type,
"label": self.label,
"icon": self.icon,
}

@classmethod
Expand Down Expand Up @@ -95,23 +85,15 @@ class TaskItem:
name (str): Name of task.
task_type (str): Type of task.
parent_id (str): Parent folder id.
icon (Union[dict[str, Any], None]): Icon definitions.
"""

def __init__(
self, task_id, name, task_type, parent_id, icon
self, task_id, name, task_type, parent_id
):
self.task_id = task_id
self.name = name
self.task_type = task_type
self.parent_id = parent_id
if icon is None:
icon = {
"type": "awesome-font",
"name": "fa.male",
"color": get_default_entity_icon_color()
}
self.icon = icon

self._label = None

Expand Down Expand Up @@ -149,7 +131,6 @@ def to_data(self):
"name": self.name,
"parent_id": self.parent_id,
"task_type": self.task_type,
"icon": self.icon,
}

@classmethod
Expand Down Expand Up @@ -180,8 +161,7 @@ def _get_task_items_from_tasks(tasks):
task["id"],
task["name"],
task["type"],
folder_id,
None
folder_id
))
return output

Expand All @@ -197,8 +177,7 @@ def _get_folder_item_from_hierarchy_item(item):
name,
path,
item["folderType"],
item["label"],
None,
item["label"]
)


Expand All @@ -210,8 +189,7 @@ def _get_folder_item_from_entity(entity):
name,
entity["path"],
entity["folderType"],
entity["label"] or name,
None,
entity["label"] or name
)


Expand Down
193 changes: 177 additions & 16 deletions client/ayon_core/tools/common_models/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,74 @@ def from_project_item(cls, status_data):
)


class FolderTypeItem:
"""Item representing folder type of project.

Args:
name (str): Folder type name ("Shot").
short (str): Short folder type name ("sh").
icon (str): Icon name in MaterialIcons ("fiber_new").

"""
def __init__(self, name, short, icon):
self.name = name
self.short = short
self.icon = icon

def to_data(self):
return {
"name": self.name,
"short": self.short,
"icon": self.icon,
}

@classmethod
def from_data(cls, data):
return cls(**data)

@classmethod
def from_project_item(cls, folder_type_data):
return cls(
name=folder_type_data["name"],
short=folder_type_data["shortName"],
icon=folder_type_data["icon"],
)


class TaskTypeItem:
"""Item representing task type of project.

Args:
name (str): Task type name ("Shot").
short (str): Short task type name ("sh").
icon (str): Icon name in MaterialIcons ("fiber_new").

"""
def __init__(self, name, short, icon):
self.name = name
self.short = short
self.icon = icon

def to_data(self):
return {
"name": self.name,
"short": self.short,
"icon": self.icon,
}

@classmethod
def from_data(cls, data):
return cls(**data)

@classmethod
def from_project_item(cls, task_type_data):
return cls(
name=task_type_data["name"],
short=task_type_data["shortName"],
icon=task_type_data["icon"],
)


class ProjectItem:
"""Item representing folder entity on a server.

Expand Down Expand Up @@ -147,19 +215,21 @@ def _get_project_items_from_entitiy(projects):
class ProjectsModel(object):
def __init__(self, controller):
self._projects_cache = CacheItem(default_factory=list)
self._project_statuses_cache = NestedCacheItem(
levels=1, default_factory=list
)
self._projects_by_name = NestedCacheItem(
levels=1, default_factory=list
)
self._project_statuses_cache = {}
self._folder_types_cache = {}
self._task_types_cache = {}

self._is_refreshing = False
self._controller = controller

def reset(self):
self._project_statuses_cache = {}
self._folder_types_cache = {}
self._task_types_cache = {}
self._projects_cache.reset()
self._project_statuses_cache.reset()
self._projects_by_name.reset()

def refresh(self):
Expand Down Expand Up @@ -217,22 +287,87 @@ def get_project_status_items(self, project_name, sender):
list[StatusItem]: Status items for project.

"""
statuses_cache = self._project_statuses_cache[project_name]
if not statuses_cache.is_valid:
with self._project_statuses_refresh_event_manager(
sender, project_name
if project_name is None:
return []

statuses_cache = self._project_statuses_cache.get(project_name)
if (
statuses_cache is not None
and not self._projects_cache.is_valid
):
statuses_cache = None

if statuses_cache is None:
with self._project_items_refresh_event_manager(
sender, project_name, "statuses"
):
project_entity = None
if project_name:
project_entity = self.get_project_entity(project_name)
project_entity = self.get_project_entity(project_name)
statuses = []
if project_entity:
statuses = [
StatusItem.from_project_item(status)
for status in project_entity["statuses"]
]
statuses_cache.update_data(statuses)
return statuses_cache.get_data()
statuses_cache = statuses
self._project_statuses_cache[project_name] = statuses_cache
return list(statuses_cache)

def get_folder_type_items(self, project_name, sender):
"""Get project status items.

Args:
project_name (str): Project name.
sender (Union[str, None]): Name of sender who asked for items.

Returns:
list[FolderType]: Folder type items for project.

"""
return self._get_project_items(
project_name,
sender,
"folder_types",
self._folder_types_cache,
self._folder_type_items_getter,
)

def get_task_type_items(self, project_name, sender):
"""Get project task type items.

Args:
project_name (str): Project name.
sender (Union[str, None]): Name of sender who asked for items.

Returns:
list[TaskTypeItem]: Task type items for project.

"""
return self._get_project_items(
project_name,
sender,
"task_types",
self._task_types_cache,
self._task_type_items_getter,
)

def _get_project_items(
self, project_name, sender, item_type, cache_obj, getter
):
if (
project_name in cache_obj
and (
project_name is None
or self._projects_by_name[project_name].is_valid
)
):
return cache_obj[project_name]

with self._project_items_refresh_event_manager(
sender, project_name, item_type
):
cache_value = getter(self.get_project_entity(project_name))
cache_obj[project_name] = cache_value
return cache_value

@contextlib.contextmanager
def _project_refresh_event_manager(self, sender):
Expand All @@ -254,9 +389,11 @@ def _project_refresh_event_manager(self, sender):
self._is_refreshing = False

@contextlib.contextmanager
def _project_statuses_refresh_event_manager(self, sender, project_name):
def _project_items_refresh_event_manager(
self, sender, project_name, item_type
):
self._controller.emit_event(
"projects.statuses.refresh.started",
f"projects.{item_type}.refresh.started",
{"sender": sender, "project_name": project_name},
PROJECTS_MODEL_SENDER
)
Expand All @@ -265,7 +402,7 @@ def _project_statuses_refresh_event_manager(self, sender, project_name):

finally:
self._controller.emit_event(
"projects.statuses.refresh.finished",
f"projects.{item_type}.refresh.finished",
{"sender": sender, "project_name": project_name},
PROJECTS_MODEL_SENDER
)
Expand All @@ -282,3 +419,27 @@ def _refresh_projects_cache(self, sender=None):
def _query_projects(self):
projects = ayon_api.get_projects(fields=["name", "active", "library"])
return _get_project_items_from_entitiy(projects)

def _status_items_getter(self, project_entity):
if not project_entity:
return []
return [
StatusItem.from_project_item(status)
for status in project_entity["statuses"]
]

def _folder_type_items_getter(self, project_entity):
if not project_entity:
return []
return [
FolderTypeItem.from_project_item(folder_type)
for folder_type in project_entity["folderTypes"]
]

def _task_type_items_getter(self, project_entity):
if not project_entity:
return []
return [
TaskTypeItem.from_project_item(task_type)
for task_type in project_entity["taskTypes"]
]
10 changes: 10 additions & 0 deletions client/ayon_core/tools/context_dialog/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,16 @@ def set_strict(self, enabled):
def get_project_items(self, sender=None):
return self._projects_model.get_project_items(sender)

def get_folder_type_items(self, project_name, sender=None):
return self._projects_model.get_folder_type_items(
project_name, sender
)

def get_task_type_items(self, project_name, sender=None):
return self._projects_model.get_task_type_items(
project_name, sender
)

def get_folder_items(self, project_name, sender=None):
return self._hierarchy_model.get_folder_items(project_name, sender)

Expand Down
Loading