Add height, width and fps setup to project manager (#5075)

* add width, height and fps setup

* add corresponding ui tweaks

* update docstring

* remove unnecessary fallbacks

* remove print

* hound

* remove whitespace

* revert operations change

* wip commit project update with new data

* formatting

* update the project data correctly

* Update openpype/tools/project_manager/project_manager/widgets.py

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* show default settings, use spinbox to validate values
add pixel aspec, frame start, frame end

* formatting

* get default anatomy settings properly

* check if singlestep is set

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* not used

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* mindless code copying is evil, removed unnecesary parts

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* Update openpype/tools/project_manager/project_manager/widgets.py

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* Update openpype/tools/project_manager/project_manager/widgets.py

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* remove unused import

* use integer or float instead of text

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>

* import PixmapLabel from 'utils'

* fix spinbox field length for macos

* set aspect decimals to 2

* remove set size policy

* set field growth policy for macos

* add newline

---------

Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com>
This commit is contained in:
Alexey Bogomolov 2023-06-19 14:15:34 +03:00 committed by GitHub
parent 3631cc5f40
commit a4c63c12cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 53 deletions

View file

@ -220,7 +220,6 @@ def new_representation_doc(
"parent": version_id,
"name": name,
"data": data,
# Imprint shortcut to context for performance reasons.
"context": context
}
@ -708,7 +707,11 @@ class OperationsSession(object):
return operation
def create_project(project_name, project_code, library_project=False):
def create_project(
project_name,
project_code,
library_project=False,
):
"""Create project using OpenPype settings.
This project creation function is not validating project document on
@ -752,7 +755,7 @@ def create_project(project_name, project_code, library_project=False):
"name": project_name,
"data": {
"code": project_code,
"library_project": library_project
"library_project": library_project,
},
"schema": CURRENT_PROJECT_SCHEMA
}

View file

@ -1,4 +1,5 @@
import re
import platform
from openpype.client import get_projects, create_project
from .constants import (
@ -8,13 +9,16 @@ from .constants import (
from openpype.client.operations import (
PROJECT_NAME_ALLOWED_SYMBOLS,
PROJECT_NAME_REGEX,
OperationsSession,
)
from openpype.style import load_stylesheet
from openpype.pipeline import AvalonMongoDB
from openpype.tools.utils import (
PlaceholderLineEdit,
get_warning_pixmap
get_warning_pixmap,
PixmapLabel,
)
from openpype.settings.lib import get_default_anatomy_settings
from qtpy import QtWidgets, QtCore, QtGui
@ -35,7 +39,7 @@ class NameTextEdit(QtWidgets.QLineEdit):
sub_regex = "[^{}]+".format(NAME_ALLOWED_SYMBOLS)
new_before_text = re.sub(sub_regex, "", before_text)
new_after_text = re.sub(sub_regex, "", after_text)
idx -= (len(before_text) - len(new_before_text))
idx -= len(before_text) - len(new_before_text)
self.setText(new_before_text + new_after_text)
self.setCursorPosition(idx)
@ -141,13 +145,40 @@ class CreateProjectDialog(QtWidgets.QDialog):
inputs_widget = QtWidgets.QWidget(self)
project_name_input = QtWidgets.QLineEdit(inputs_widget)
project_code_input = QtWidgets.QLineEdit(inputs_widget)
project_width_input = NumScrollWidget(0, 9999999)
project_height_input = NumScrollWidget(0, 9999999)
project_fps_input = FloatScrollWidget(1, 9999999, decimals=3, step=1)
project_aspect_input = FloatScrollWidget(
0, 9999999, decimals=2, step=0.1
)
project_frame_start_input = NumScrollWidget(-9999999, 9999999)
project_frame_end_input = NumScrollWidget(-9999999, 9999999)
default_project_data = self.get_default_attributes()
project_width_input.setValue(default_project_data["resolutionWidth"])
project_height_input.setValue(default_project_data["resolutionHeight"])
project_fps_input.setValue(default_project_data["fps"])
project_aspect_input.setValue(default_project_data["pixelAspect"])
project_frame_start_input.setValue(default_project_data["frameStart"])
project_frame_end_input.setValue(default_project_data["frameEnd"])
library_project_input = QtWidgets.QCheckBox(inputs_widget)
inputs_layout = QtWidgets.QFormLayout(inputs_widget)
if platform.system() == "Darwin":
inputs_layout.setFieldGrowthPolicy(
QtWidgets.QFormLayout.AllNonFixedFieldsGrow
)
inputs_layout.setContentsMargins(0, 0, 0, 0)
inputs_layout.addRow("Project name:", project_name_input)
inputs_layout.addRow("Project code:", project_code_input)
inputs_layout.addRow("Library project:", library_project_input)
inputs_layout.addRow("Width:", project_width_input)
inputs_layout.addRow("Height:", project_height_input)
inputs_layout.addRow("FPS:", project_fps_input)
inputs_layout.addRow("Aspect:", project_aspect_input)
inputs_layout.addRow("Frame Start:", project_frame_start_input)
inputs_layout.addRow("Frame End:", project_frame_end_input)
project_name_label = QtWidgets.QLabel(self)
project_code_label = QtWidgets.QLabel(self)
@ -183,6 +214,12 @@ class CreateProjectDialog(QtWidgets.QDialog):
self.project_name_input = project_name_input
self.project_code_input = project_code_input
self.library_project_input = library_project_input
self.project_width_input = project_width_input
self.project_height_input = project_height_input
self.project_fps_input = project_fps_input
self.project_aspect_input = project_aspect_input
self.project_frame_start_input = project_frame_start_input
self.project_frame_end_input = project_frame_end_input
self.ok_btn = ok_btn
@ -190,6 +227,10 @@ class CreateProjectDialog(QtWidgets.QDialog):
def project_name(self):
return self.project_name_input.text()
def get_default_attributes(self):
settings = get_default_anatomy_settings()
return settings["attributes"]
def _on_project_name_change(self, value):
if self._project_code_value is None:
self._ignore_code_change = True
@ -215,12 +256,12 @@ class CreateProjectDialog(QtWidgets.QDialog):
is_valid = False
elif value in self.invalid_project_names:
message = "Project name \"{}\" already exist".format(value)
message = 'Project name "{}" already exist'.format(value)
is_valid = False
elif not PROJECT_NAME_REGEX.match(value):
message = (
"Project name \"{}\" contain not supported symbols"
'Project name "{}" contain not supported symbols'
).format(value)
is_valid = False
@ -237,12 +278,12 @@ class CreateProjectDialog(QtWidgets.QDialog):
is_valid = False
elif value in self.invalid_project_names:
message = "Project code \"{}\" already exist".format(value)
message = 'Project code "{}" already exist'.format(value)
is_valid = False
elif not PROJECT_NAME_REGEX.match(value):
message = (
"Project code \"{}\" contain not supported symbols"
'Project code "{}" contain not supported symbols'
).format(value)
is_valid = False
@ -264,9 +305,35 @@ class CreateProjectDialog(QtWidgets.QDialog):
project_name = self.project_name_input.text()
project_code = self.project_code_input.text()
library_project = self.library_project_input.isChecked()
create_project(project_name, project_code, library_project)
project_width = self.project_width_input.value()
project_height = self.project_height_input.value()
project_fps = self.project_fps_input.value()
project_aspect = self.project_aspect_input.value()
project_frame_start = self.project_frame_start_input.value()
project_frame_end = self.project_frame_end_input.value()
library_project = self.library_project_input.isChecked()
project_doc = create_project(
project_name,
project_code,
library_project,
)
update_data = {
"data.resolutionWidth": project_width,
"data.resolutionHeight": project_height,
"data.fps": project_fps,
"data.pixelAspect": project_aspect,
"data.frameStart": project_frame_start,
"data.frameEnd": project_frame_end,
}
session = OperationsSession()
session.update_entity(
project_name,
project_doc["type"],
project_doc["_id"],
update_data,
)
session.commit()
self.done(1)
def _get_existing_projects(self):
@ -288,45 +355,15 @@ class CreateProjectDialog(QtWidgets.QDialog):
return project_names, project_codes
# TODO PixmapLabel should be moved to 'utils' in other future PR so should be
# imported from there
class PixmapLabel(QtWidgets.QLabel):
"""Label resizing image to height of font."""
def __init__(self, pixmap, parent):
super(PixmapLabel, self).__init__(parent)
self._empty_pixmap = QtGui.QPixmap(0, 0)
self._source_pixmap = pixmap
def set_source_pixmap(self, pixmap):
"""Change source image."""
self._source_pixmap = pixmap
self._set_resized_pix()
class ProjectManagerPixmapLabel(PixmapLabel):
def _get_pix_size(self):
size = self.fontMetrics().height() * 4
return size, size
def _set_resized_pix(self):
if self._source_pixmap is None:
self.setPixmap(self._empty_pixmap)
return
width, height = self._get_pix_size()
self.setPixmap(
self._source_pixmap.scaled(
width,
height,
QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation
)
)
def resizeEvent(self, event):
self._set_resized_pix()
super(PixmapLabel, self).resizeEvent(event)
class ConfirmProjectDeletion(QtWidgets.QDialog):
"""Dialog which confirms deletion of a project."""
def __init__(self, project_name, parent):
super(ConfirmProjectDeletion, self).__init__(parent)
@ -335,23 +372,26 @@ class ConfirmProjectDeletion(QtWidgets.QDialog):
top_widget = QtWidgets.QWidget(self)
warning_pixmap = get_warning_pixmap()
warning_icon_label = PixmapLabel(warning_pixmap, top_widget)
warning_icon_label = ProjectManagerPixmapLabel(
warning_pixmap, top_widget
)
message_label = QtWidgets.QLabel(top_widget)
message_label.setWordWrap(True)
message_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)
message_label.setText((
"<b>WARNING: This cannot be undone.</b><br/><br/>"
"Project <b>\"{}\"</b> with all related data will be"
" permanently removed from the database. (This action won't remove"
" any files on disk.)"
).format(project_name))
message_label.setText(
(
"<b>WARNING: This cannot be undone.</b><br/><br/>"
'Project <b>"{}"</b> with all related data will be'
" permanently removed from the database."
" (This action won't remove any files on disk.)"
).format(project_name)
)
top_layout = QtWidgets.QHBoxLayout(top_widget)
top_layout.setContentsMargins(0, 0, 0, 0)
top_layout.addWidget(
warning_icon_label, 0,
QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter
warning_icon_label, 0, QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter
)
top_layout.addWidget(message_label, 1)
@ -359,7 +399,7 @@ class ConfirmProjectDeletion(QtWidgets.QDialog):
confirm_input = PlaceholderLineEdit(self)
confirm_input.setPlaceholderText(
"Type \"{}\" to confirm...".format(project_name)
'Type "{}" to confirm...'.format(project_name)
)
cancel_btn = QtWidgets.QPushButton("Cancel", self)
@ -429,6 +469,7 @@ class ConfirmProjectDeletion(QtWidgets.QDialog):
class SpinBoxScrollFixed(QtWidgets.QSpinBox):
"""QSpinBox which only allow edits change with scroll wheel when active"""
def __init__(self, *args, **kwargs):
super(SpinBoxScrollFixed, self).__init__(*args, **kwargs)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
@ -442,6 +483,7 @@ class SpinBoxScrollFixed(QtWidgets.QSpinBox):
class DoubleSpinBoxScrollFixed(QtWidgets.QDoubleSpinBox):
"""QDoubleSpinBox which only allow edits with scroll wheel when active"""
def __init__(self, *args, **kwargs):
super(DoubleSpinBoxScrollFixed, self).__init__(*args, **kwargs)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
@ -451,3 +493,22 @@ class DoubleSpinBoxScrollFixed(QtWidgets.QDoubleSpinBox):
event.ignore()
else:
super(DoubleSpinBoxScrollFixed, self).wheelEvent(event)
class NumScrollWidget(SpinBoxScrollFixed):
def __init__(self, minimum, maximum):
super(NumScrollWidget, self).__init__()
self.setMaximum(maximum)
self.setMinimum(minimum)
self.setButtonSymbols(QtWidgets.QSpinBox.NoButtons)
class FloatScrollWidget(DoubleSpinBoxScrollFixed):
def __init__(self, minimum, maximum, decimals, step=None):
super(FloatScrollWidget, self).__init__()
self.setMaximum(maximum)
self.setMinimum(minimum)
self.setDecimals(decimals)
if step is not None:
self.setSingleStep(step)
self.setButtonSymbols(QtWidgets.QSpinBox.NoButtons)