mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-26 22:02:15 +01:00
Merge branch 'develop' of github.com:pypeclub/OpenPype into feature/OP-2765_AE-to-new-publisher
This commit is contained in:
commit
fc4dca52f2
14 changed files with 331 additions and 89 deletions
|
|
@ -48,8 +48,13 @@ class ExtractSlateFrame(openpype.api.Extractor):
|
|||
self.log.info(
|
||||
"StagingDir `{0}`...".format(instance.data["stagingDir"]))
|
||||
|
||||
frame_start = instance.data["frameStart"]
|
||||
frame_end = instance.data["frameEnd"]
|
||||
handle_start = instance.data["handleStart"]
|
||||
handle_end = instance.data["handleEnd"]
|
||||
|
||||
frame_length = int(
|
||||
instance.data["frameEnd"] - instance.data["frameStart"] + 1
|
||||
(frame_end - frame_start + 1) + (handle_start + handle_end)
|
||||
)
|
||||
|
||||
temporary_nodes = []
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class PreCollectNukeInstances(pyblish.api.ContextPlugin):
|
|||
# Add all nodes in group instances.
|
||||
if node.Class() == "Group":
|
||||
# only alter families for render family
|
||||
if "write" in families_ak.lower():
|
||||
if families_ak and "write" in families_ak.lower():
|
||||
target = node["render"].value()
|
||||
if target == "Use existing frames":
|
||||
# Local rendering
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ class ValidateWriteLegacy(pyblish.api.InstancePlugin):
|
|||
# test if render in family test knob
|
||||
# and only one item should be available
|
||||
assert len(family_test) == 1, msg + " > More avalon attributes"
|
||||
assert "render" in node[family_test[0]].value(), msg + \
|
||||
assert "render" in node[family_test[0]].value() \
|
||||
or "still" in node[family_test[0]].value(), msg + \
|
||||
" > Not correct family"
|
||||
|
||||
# test if `file` knob in node, this way old
|
||||
# non-group-node write could be detected
|
||||
assert "file" not in node.knobs(), msg + \
|
||||
|
|
@ -74,6 +74,8 @@ class ValidateWriteLegacy(pyblish.api.InstancePlugin):
|
|||
Create_name = "CreateWriteRender"
|
||||
elif family == "prerender":
|
||||
Create_name = "CreateWritePrerender"
|
||||
elif family == "still":
|
||||
Create_name = "CreateWriteStill"
|
||||
|
||||
# get appropriate plugin class
|
||||
creator_plugin = None
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ def create_hard_link(src_path, dst_path):
|
|||
res = CreateHardLink(dst_path, src_path, None)
|
||||
if res == 0:
|
||||
raise ctypes.WinError()
|
||||
return
|
||||
# Raises not implemented error if gets here
|
||||
raise NotImplementedError(
|
||||
"Implementation of hardlink for current environment is missing."
|
||||
|
|
|
|||
|
|
@ -1159,12 +1159,26 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
# - there may be a better way (checking `codec_type`?)
|
||||
input_width = None
|
||||
input_height = None
|
||||
output_width = None
|
||||
output_height = None
|
||||
for stream in streams:
|
||||
if "width" in stream and "height" in stream:
|
||||
input_width = int(stream["width"])
|
||||
input_height = int(stream["height"])
|
||||
break
|
||||
|
||||
# Get instance data
|
||||
pixel_aspect = temp_data["pixel_aspect"]
|
||||
|
||||
if reformat_in_baking:
|
||||
self.log.debug((
|
||||
"Using resolution from input. It is already "
|
||||
"reformated from upstream process"
|
||||
))
|
||||
pixel_aspect = 1
|
||||
output_width = input_width
|
||||
output_height = input_height
|
||||
|
||||
# Raise exception of any stream didn't define input resolution
|
||||
if input_width is None:
|
||||
raise AssertionError((
|
||||
|
|
@ -1173,8 +1187,8 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
|
||||
# NOTE Setting only one of `width` or `heigth` is not allowed
|
||||
# - settings value can't have None but has value of 0
|
||||
output_width = output_def.get("width") or None
|
||||
output_height = output_def.get("height") or None
|
||||
output_width = output_width or output_def.get("width") or None
|
||||
output_height = output_height or output_def.get("height") or None
|
||||
|
||||
# Overscal color
|
||||
overscan_color_value = "black"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
families = ["slate", "review"]
|
||||
match = pyblish.api.Subset
|
||||
|
||||
hosts = ["nuke", "maya", "shell"]
|
||||
hosts = ["nuke", "shell"]
|
||||
optional = True
|
||||
|
||||
def process(self, instance):
|
||||
|
|
@ -59,13 +59,44 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
if "slate-frame" not in p_tags:
|
||||
continue
|
||||
|
||||
# get repre file
|
||||
stagingdir = repre["stagingDir"]
|
||||
input_file = "{0}".format(repre["files"])
|
||||
input_path = os.path.join(
|
||||
os.path.normpath(stagingdir), repre["files"])
|
||||
self.log.debug("__ input_path: {}".format(input_path))
|
||||
|
||||
video_streams = openpype.lib.ffprobe_streams(
|
||||
input_path, self.log
|
||||
)
|
||||
|
||||
# Try to find first stream with defined 'width' and 'height'
|
||||
# - this is to avoid order of streams where audio can be as first
|
||||
# - there may be a better way (checking `codec_type`?)
|
||||
input_width = None
|
||||
input_height = None
|
||||
for stream in video_streams:
|
||||
if "width" in stream and "height" in stream:
|
||||
input_width = int(stream["width"])
|
||||
input_height = int(stream["height"])
|
||||
break
|
||||
|
||||
# Raise exception of any stream didn't define input resolution
|
||||
if input_width is None:
|
||||
raise AssertionError((
|
||||
"FFprobe couldn't read resolution from input file: \"{}\""
|
||||
).format(input_path))
|
||||
|
||||
# values are set in ExtractReview
|
||||
if use_legacy_code:
|
||||
to_width = inst_data["reviewToWidth"]
|
||||
to_height = inst_data["reviewToHeight"]
|
||||
else:
|
||||
to_width = repre["resolutionWidth"]
|
||||
to_height = repre["resolutionHeight"]
|
||||
to_width = input_width
|
||||
to_height = input_height
|
||||
|
||||
self.log.debug("to_width: `{}`".format(to_width))
|
||||
self.log.debug("to_height: `{}`".format(to_height))
|
||||
|
||||
# defining image ratios
|
||||
resolution_ratio = (
|
||||
|
|
@ -94,15 +125,9 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
|
||||
_remove_at_end = []
|
||||
|
||||
stagingdir = repre["stagingDir"]
|
||||
input_file = "{0}".format(repre["files"])
|
||||
|
||||
ext = os.path.splitext(input_file)[1]
|
||||
output_file = input_file.replace(ext, "") + suffix + ext
|
||||
|
||||
input_path = os.path.join(
|
||||
os.path.normpath(stagingdir), repre["files"])
|
||||
self.log.debug("__ input_path: {}".format(input_path))
|
||||
_remove_at_end.append(input_path)
|
||||
|
||||
output_path = os.path.join(
|
||||
|
|
@ -347,8 +372,21 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
|
||||
profile_name = no_audio_stream.get("profile")
|
||||
if profile_name:
|
||||
profile_name = profile_name.replace(" ", "_").lower()
|
||||
codec_args.append("-profile:v {}".format(profile_name))
|
||||
# Rest of arguments is prores_kw specific
|
||||
if codec_name == "prores_ks":
|
||||
codec_tag_to_profile_map = {
|
||||
"apco": "proxy",
|
||||
"apcs": "lt",
|
||||
"apcn": "standard",
|
||||
"apch": "hq",
|
||||
"ap4h": "4444",
|
||||
"ap4x": "4444xq"
|
||||
}
|
||||
codec_tag_str = no_audio_stream.get("codec_tag_string")
|
||||
if codec_tag_str:
|
||||
profile = codec_tag_to_profile_map.get(codec_tag_str)
|
||||
if profile:
|
||||
codec_args.extend(["-profile:v", profile])
|
||||
|
||||
pix_fmt = no_audio_stream.get("pix_fmt")
|
||||
if pix_fmt:
|
||||
|
|
|
|||
|
|
@ -836,6 +836,19 @@ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
|||
}
|
||||
|
||||
/* New Create/Publish UI */
|
||||
#CreateDialogHelpButton {
|
||||
background: rgba(255, 255, 255, 31);
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
font-size: 10pt;
|
||||
font-weight: bold;
|
||||
padding: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
#CreateDialogHelpButton:hover {
|
||||
background: rgba(255, 255, 255, 63);
|
||||
}
|
||||
|
||||
#PublishLogConsole {
|
||||
font-family: "Noto Sans Mono";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import collections
|
|||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from openpype.tools.utils import (
|
||||
PlaceholderLineEdit,
|
||||
RecursiveSortFilterProxyModel
|
||||
RecursiveSortFilterProxyModel,
|
||||
get_asset_icon,
|
||||
)
|
||||
from openpype.tools.utils.assets_widget import (
|
||||
SingleSelectAssetsWidget,
|
||||
|
|
@ -102,11 +103,15 @@ class AssetsHierarchyModel(QtGui.QStandardItemModel):
|
|||
for name in sorted(children_by_name.keys()):
|
||||
child = children_by_name[name]
|
||||
child_id = child["_id"]
|
||||
has_children = bool(assets_by_parent_id.get(child_id))
|
||||
icon = get_asset_icon(child, has_children)
|
||||
|
||||
item = QtGui.QStandardItem(name)
|
||||
item.setFlags(
|
||||
QtCore.Qt.ItemIsEnabled
|
||||
| QtCore.Qt.ItemIsSelectable
|
||||
)
|
||||
item.setData(icon, QtCore.Qt.DecorationRole)
|
||||
item.setData(child_id, ASSET_ID_ROLE)
|
||||
item.setData(name, ASSET_NAME_ROLE)
|
||||
|
||||
|
|
|
|||
|
|
@ -103,71 +103,98 @@ class CreateErrorMessageBox(ErrorMessageBox):
|
|||
|
||||
|
||||
# TODO add creator identifier/label to details
|
||||
class CreatorDescriptionWidget(QtWidgets.QWidget):
|
||||
class CreatorShortDescWidget(QtWidgets.QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super(CreatorDescriptionWidget, self).__init__(parent=parent)
|
||||
super(CreatorShortDescWidget, self).__init__(parent=parent)
|
||||
|
||||
# --- Short description widget ---
|
||||
icon_widget = IconValuePixmapLabel(None, self)
|
||||
icon_widget.setObjectName("FamilyIconLabel")
|
||||
|
||||
family_label = QtWidgets.QLabel("family")
|
||||
# --- Short description inputs ---
|
||||
short_desc_input_widget = QtWidgets.QWidget(self)
|
||||
|
||||
family_label = QtWidgets.QLabel(short_desc_input_widget)
|
||||
family_label.setAlignment(
|
||||
QtCore.Qt.AlignBottom | QtCore.Qt.AlignLeft
|
||||
)
|
||||
|
||||
description_label = QtWidgets.QLabel("description")
|
||||
description_label = QtWidgets.QLabel(short_desc_input_widget)
|
||||
description_label.setAlignment(
|
||||
QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft
|
||||
)
|
||||
|
||||
detail_description_widget = QtWidgets.QTextEdit(self)
|
||||
detail_description_widget.setObjectName("InfoText")
|
||||
detail_description_widget.setTextInteractionFlags(
|
||||
QtCore.Qt.TextBrowserInteraction
|
||||
short_desc_input_layout = QtWidgets.QVBoxLayout(
|
||||
short_desc_input_widget
|
||||
)
|
||||
short_desc_input_layout.setSpacing(0)
|
||||
short_desc_input_layout.addWidget(family_label)
|
||||
short_desc_input_layout.addWidget(description_label)
|
||||
# --------------------------------
|
||||
|
||||
label_layout = QtWidgets.QVBoxLayout()
|
||||
label_layout.setSpacing(0)
|
||||
label_layout.addWidget(family_label)
|
||||
label_layout.addWidget(description_label)
|
||||
|
||||
top_layout = QtWidgets.QHBoxLayout()
|
||||
top_layout.setContentsMargins(0, 0, 0, 0)
|
||||
top_layout.addWidget(icon_widget, 0)
|
||||
top_layout.addLayout(label_layout, 1)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout = QtWidgets.QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addLayout(top_layout, 0)
|
||||
layout.addWidget(detail_description_widget, 1)
|
||||
layout.addWidget(icon_widget, 0)
|
||||
layout.addWidget(short_desc_input_widget, 1)
|
||||
# --------------------------------
|
||||
|
||||
self.icon_widget = icon_widget
|
||||
self.family_label = family_label
|
||||
self.description_label = description_label
|
||||
self.detail_description_widget = detail_description_widget
|
||||
self._icon_widget = icon_widget
|
||||
self._family_label = family_label
|
||||
self._description_label = description_label
|
||||
|
||||
def set_plugin(self, plugin=None):
|
||||
if not plugin:
|
||||
self.icon_widget.set_icon_def(None)
|
||||
self.family_label.setText("")
|
||||
self.description_label.setText("")
|
||||
self.detail_description_widget.setPlainText("")
|
||||
self._icon_widget.set_icon_def(None)
|
||||
self._family_label.setText("")
|
||||
self._description_label.setText("")
|
||||
return
|
||||
|
||||
plugin_icon = plugin.get_icon()
|
||||
description = plugin.get_description() or ""
|
||||
detailed_description = plugin.get_detail_description() or ""
|
||||
|
||||
self.icon_widget.set_icon_def(plugin_icon)
|
||||
self.family_label.setText("<b>{}</b>".format(plugin.family))
|
||||
self.family_label.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
|
||||
self.description_label.setText(description)
|
||||
self._icon_widget.set_icon_def(plugin_icon)
|
||||
self._family_label.setText("<b>{}</b>".format(plugin.family))
|
||||
self._family_label.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
|
||||
self._description_label.setText(description)
|
||||
|
||||
if commonmark:
|
||||
html = commonmark.commonmark(detailed_description)
|
||||
self.detail_description_widget.setHtml(html)
|
||||
|
||||
class HelpButton(QtWidgets.QPushButton):
|
||||
resized = QtCore.Signal()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(HelpButton, self).__init__(*args, **kwargs)
|
||||
self.setObjectName("CreateDialogHelpButton")
|
||||
|
||||
self._expanded = None
|
||||
self.set_expanded()
|
||||
|
||||
def set_expanded(self, expanded=None):
|
||||
if self._expanded is expanded:
|
||||
if expanded is not None:
|
||||
return
|
||||
expanded = False
|
||||
self._expanded = expanded
|
||||
if expanded:
|
||||
text = "<"
|
||||
else:
|
||||
self.detail_description_widget.setMarkdown(detailed_description)
|
||||
text = "?"
|
||||
self.setText(text)
|
||||
|
||||
self._update_size()
|
||||
|
||||
def _update_size(self):
|
||||
new_size = self.minimumSizeHint()
|
||||
if self.size() != new_size:
|
||||
self.resize(new_size)
|
||||
self.resized.emit()
|
||||
|
||||
def showEvent(self, event):
|
||||
super(HelpButton, self).showEvent(event)
|
||||
self._update_size()
|
||||
|
||||
def resizeEvent(self, event):
|
||||
super(HelpButton, self).resizeEvent(event)
|
||||
self._update_size()
|
||||
|
||||
|
||||
class CreateDialog(QtWidgets.QDialog):
|
||||
|
|
@ -215,13 +242,7 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
context_layout.addWidget(assets_widget, 2)
|
||||
context_layout.addWidget(tasks_widget, 1)
|
||||
|
||||
# Precreate attributes widgets
|
||||
pre_create_widget = PreCreateWidget(self)
|
||||
|
||||
# TODO add HELP button
|
||||
creator_description_widget = CreatorDescriptionWidget(self)
|
||||
creator_description_widget.setVisible(False)
|
||||
|
||||
# --- Creators view ---
|
||||
creators_view = QtWidgets.QListView(self)
|
||||
creators_model = QtGui.QStandardItemModel()
|
||||
creators_view.setModel(creators_model)
|
||||
|
|
@ -260,24 +281,65 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
mid_layout.addWidget(creators_view, 1)
|
||||
mid_layout.addLayout(form_layout, 0)
|
||||
mid_layout.addWidget(create_btn, 0)
|
||||
# ------------
|
||||
|
||||
# --- Creator short info and attr defs ---
|
||||
creator_attrs_widget = QtWidgets.QWidget(self)
|
||||
|
||||
creator_short_desc_widget = CreatorShortDescWidget(
|
||||
creator_attrs_widget
|
||||
)
|
||||
|
||||
separator_widget = QtWidgets.QWidget(self)
|
||||
separator_widget.setObjectName("Separator")
|
||||
separator_widget.setMinimumHeight(2)
|
||||
separator_widget.setMaximumHeight(2)
|
||||
|
||||
# Precreate attributes widget
|
||||
pre_create_widget = PreCreateWidget(creator_attrs_widget)
|
||||
|
||||
creator_attrs_layout = QtWidgets.QVBoxLayout(creator_attrs_widget)
|
||||
creator_attrs_layout.setContentsMargins(0, 0, 0, 0)
|
||||
creator_attrs_layout.addWidget(creator_short_desc_widget, 0)
|
||||
creator_attrs_layout.addWidget(separator_widget, 0)
|
||||
creator_attrs_layout.addWidget(pre_create_widget, 1)
|
||||
# -------------------------------------
|
||||
|
||||
# --- Detailed information about creator ---
|
||||
# Detailed description of creator
|
||||
detail_description_widget = QtWidgets.QTextEdit(self)
|
||||
detail_description_widget.setObjectName("InfoText")
|
||||
detail_description_widget.setTextInteractionFlags(
|
||||
QtCore.Qt.TextBrowserInteraction
|
||||
)
|
||||
detail_description_widget.setVisible(False)
|
||||
# -------------------------------------------
|
||||
|
||||
splitter_widget = QtWidgets.QSplitter(self)
|
||||
splitter_widget.addWidget(context_widget)
|
||||
splitter_widget.addWidget(mid_widget)
|
||||
splitter_widget.addWidget(pre_create_widget)
|
||||
splitter_widget.addWidget(creator_attrs_widget)
|
||||
splitter_widget.addWidget(detail_description_widget)
|
||||
splitter_widget.setStretchFactor(0, 1)
|
||||
splitter_widget.setStretchFactor(1, 1)
|
||||
splitter_widget.setStretchFactor(2, 1)
|
||||
splitter_widget.setStretchFactor(3, 1)
|
||||
|
||||
layout = QtWidgets.QHBoxLayout(self)
|
||||
layout.addWidget(splitter_widget, 1)
|
||||
|
||||
# Floating help button
|
||||
help_btn = HelpButton(self)
|
||||
|
||||
prereq_timer = QtCore.QTimer()
|
||||
prereq_timer.setInterval(50)
|
||||
prereq_timer.setSingleShot(True)
|
||||
|
||||
prereq_timer.timeout.connect(self._on_prereq_timer)
|
||||
|
||||
help_btn.clicked.connect(self._on_help_btn)
|
||||
help_btn.resized.connect(self._on_help_btn_resize)
|
||||
|
||||
create_btn.clicked.connect(self._on_create)
|
||||
variant_input.returnPressed.connect(self._on_create)
|
||||
variant_input.textChanged.connect(self._on_variant_change)
|
||||
|
|
@ -295,12 +357,9 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
|
||||
self._splitter_widget = splitter_widget
|
||||
|
||||
self._pre_create_widget = pre_create_widget
|
||||
|
||||
self._context_widget = context_widget
|
||||
self._assets_widget = assets_widget
|
||||
self._tasks_widget = tasks_widget
|
||||
self.creator_description_widget = creator_description_widget
|
||||
|
||||
self.subset_name_input = subset_name_input
|
||||
|
||||
|
|
@ -313,6 +372,11 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
self.creators_view = creators_view
|
||||
self.create_btn = create_btn
|
||||
|
||||
self._creator_short_desc_widget = creator_short_desc_widget
|
||||
self._pre_create_widget = pre_create_widget
|
||||
self._detail_description_widget = detail_description_widget
|
||||
self._help_btn = help_btn
|
||||
|
||||
self._prereq_timer = prereq_timer
|
||||
self._first_show = True
|
||||
|
||||
|
|
@ -506,10 +570,61 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
identifier = new_index.data(CREATOR_IDENTIFIER_ROLE)
|
||||
self._set_creator(identifier)
|
||||
|
||||
def _update_help_btn(self):
|
||||
pos_x = self.width() - self._help_btn.width()
|
||||
point = self._creator_short_desc_widget.rect().topRight()
|
||||
mapped_point = self._creator_short_desc_widget.mapTo(self, point)
|
||||
pos_y = mapped_point.y()
|
||||
self._help_btn.move(max(0, pos_x), max(0, pos_y))
|
||||
|
||||
def _on_help_btn_resize(self):
|
||||
self._update_help_btn()
|
||||
|
||||
def _on_help_btn(self):
|
||||
final_size = self.size()
|
||||
cur_sizes = self._splitter_widget.sizes()
|
||||
spacing = self._splitter_widget.handleWidth()
|
||||
|
||||
sizes = []
|
||||
for idx, value in enumerate(cur_sizes):
|
||||
if idx < 3:
|
||||
sizes.append(value)
|
||||
|
||||
now_visible = self._detail_description_widget.isVisible()
|
||||
if now_visible:
|
||||
width = final_size.width() - (
|
||||
spacing + self._detail_description_widget.width()
|
||||
)
|
||||
|
||||
else:
|
||||
last_size = self._detail_description_widget.sizeHint().width()
|
||||
width = final_size.width() + spacing + last_size
|
||||
sizes.append(last_size)
|
||||
|
||||
final_size.setWidth(width)
|
||||
|
||||
self._detail_description_widget.setVisible(not now_visible)
|
||||
self._splitter_widget.setSizes(sizes)
|
||||
self.resize(final_size)
|
||||
|
||||
self._help_btn.set_expanded(not now_visible)
|
||||
|
||||
def _set_creator_detailed_text(self, creator):
|
||||
if not creator:
|
||||
self._detail_description_widget.setPlainText("")
|
||||
return
|
||||
detailed_description = creator.get_detail_description() or ""
|
||||
if commonmark:
|
||||
html = commonmark.commonmark(detailed_description)
|
||||
self._detail_description_widget.setHtml(html)
|
||||
else:
|
||||
self._detail_description_widget.setMarkdown(detailed_description)
|
||||
|
||||
def _set_creator(self, identifier):
|
||||
creator = self.controller.manual_creators.get(identifier)
|
||||
|
||||
self.creator_description_widget.set_plugin(creator)
|
||||
self._creator_short_desc_widget.set_plugin(creator)
|
||||
self._set_creator_detailed_text(creator)
|
||||
self._pre_create_widget.set_plugin(creator)
|
||||
|
||||
self._selected_creator = creator
|
||||
|
|
@ -669,8 +784,14 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
if self._last_pos is not None:
|
||||
self.move(self._last_pos)
|
||||
|
||||
self._update_help_btn()
|
||||
|
||||
self.refresh()
|
||||
|
||||
def resizeEvent(self, event):
|
||||
super(CreateDialog, self).resizeEvent(event)
|
||||
self._update_help_btn()
|
||||
|
||||
def _on_create(self):
|
||||
indexes = self.creators_view.selectedIndexes()
|
||||
if not indexes or len(indexes) > 1:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from Qt import QtCore, QtGui
|
||||
|
||||
from openpype.tools.utils.tasks_widget import TasksWidget, TASK_NAME_ROLE
|
||||
from openpype.tools.utils.lib import get_task_icon
|
||||
|
||||
|
||||
class TasksModel(QtGui.QStandardItemModel):
|
||||
|
|
@ -118,6 +119,8 @@ class TasksModel(QtGui.QStandardItemModel):
|
|||
|
||||
item = QtGui.QStandardItem(task_name)
|
||||
item.setData(task_name, TASK_NAME_ROLE)
|
||||
if task_name:
|
||||
item.setData(get_task_icon(), QtCore.Qt.DecorationRole)
|
||||
self._items_by_name[task_name] = item
|
||||
new_items.append(item)
|
||||
|
||||
|
|
|
|||
|
|
@ -982,7 +982,7 @@ class GlobalAttrsWidget(QtWidgets.QWidget):
|
|||
btns_layout.addWidget(cancel_btn)
|
||||
|
||||
main_layout = QtWidgets.QFormLayout(self)
|
||||
main_layout.addRow("Name", variant_input)
|
||||
main_layout.addRow("Variant", variant_input)
|
||||
main_layout.addRow("Asset", asset_value_widget)
|
||||
main_layout.addRow("Task", task_value_widget)
|
||||
main_layout.addRow("Family", family_value_widget)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from .lib import (
|
|||
set_style_property,
|
||||
DynamicQThread,
|
||||
qt_app_context,
|
||||
get_asset_icon,
|
||||
)
|
||||
|
||||
from .models import (
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ from .views import (
|
|||
)
|
||||
from .widgets import PlaceholderLineEdit
|
||||
from .models import RecursiveSortFilterProxyModel
|
||||
from .lib import DynamicQThread
|
||||
from .lib import (
|
||||
DynamicQThread,
|
||||
get_asset_icon
|
||||
)
|
||||
|
||||
if Qt.__binding__ == "PySide":
|
||||
from PySide.QtGui import QStyleOptionViewItemV4
|
||||
|
|
@ -508,25 +511,9 @@ class AssetModel(QtGui.QStandardItemModel):
|
|||
item.setData(asset_label, QtCore.Qt.DisplayRole)
|
||||
item.setData(asset_label, ASSET_LABEL_ROLE)
|
||||
|
||||
icon_color = asset_data.get("color") or style.colors.default
|
||||
icon_name = asset_data.get("icon")
|
||||
if not icon_name:
|
||||
# Use default icons if no custom one is specified.
|
||||
# If it has children show a full folder, otherwise
|
||||
# show an open folder
|
||||
if item.rowCount() > 0:
|
||||
icon_name = "folder"
|
||||
else:
|
||||
icon_name = "folder-o"
|
||||
|
||||
try:
|
||||
# font-awesome key
|
||||
full_icon_name = "fa.{0}".format(icon_name)
|
||||
icon = qtawesome.icon(full_icon_name, color=icon_color)
|
||||
item.setData(icon, QtCore.Qt.DecorationRole)
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
has_children = item.rowCount() > 0
|
||||
icon = get_asset_icon(asset_data, has_children)
|
||||
item.setData(icon, QtCore.Qt.DecorationRole)
|
||||
|
||||
def _threaded_fetch(self):
|
||||
asset_docs = self._fetch_asset_docs()
|
||||
|
|
|
|||
|
|
@ -98,6 +98,58 @@ application = qt_app_context
|
|||
|
||||
class SharedObjects:
|
||||
jobs = {}
|
||||
icons = {}
|
||||
|
||||
|
||||
def get_qta_icon_by_name_and_color(icon_name, icon_color):
|
||||
if not icon_name or not icon_color:
|
||||
return None
|
||||
|
||||
full_icon_name = "{0}-{1}".format(icon_name, icon_color)
|
||||
if full_icon_name in SharedObjects.icons:
|
||||
return SharedObjects.icons[full_icon_name]
|
||||
|
||||
variants = [icon_name]
|
||||
qta_instance = qtawesome._instance()
|
||||
for key in qta_instance.charmap.keys():
|
||||
variants.append("{0}.{1}".format(key, icon_name))
|
||||
|
||||
icon = None
|
||||
for variant in variants:
|
||||
try:
|
||||
icon = qtawesome.icon(variant, color=icon_color)
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
SharedObjects.icons[full_icon_name] = icon
|
||||
return icon
|
||||
|
||||
|
||||
def get_asset_icon(asset_doc, has_children=False):
|
||||
asset_data = asset_doc.get("data") or {}
|
||||
icon_color = asset_data.get("color") or style.colors.default
|
||||
icon_name = asset_data.get("icon")
|
||||
if not icon_name:
|
||||
# Use default icons if no custom one is specified.
|
||||
# If it has children show a full folder, otherwise
|
||||
# show an open folder
|
||||
if has_children:
|
||||
icon_name = "folder"
|
||||
else:
|
||||
icon_name = "folder-o"
|
||||
|
||||
return get_qta_icon_by_name_and_color(icon_name, icon_color)
|
||||
|
||||
|
||||
def get_task_icon():
|
||||
"""Get icon for a task.
|
||||
|
||||
TODO: Get task icon based on data in database.
|
||||
|
||||
Icon should be defined by task type which is stored on project.
|
||||
"""
|
||||
return get_qta_icon_by_name_and_color("fa.male", style.colors.default)
|
||||
|
||||
|
||||
def schedule(func, time, channel="default"):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue