class SymmeshView(base.BaseWidget): def __init__(self, model, controller, parent=None): self._model = model self._controller = controller super(SymmeshView, self).__init__(parent=parent) self.refresh() def ui(self): super(SymmeshView, self).ui() top_layout = layouts.GridLayout() mirror_axis_lbl = label.BaseLabel('Mirror Axis: ', parent=self) self._axis_radio_grp = QButtonGroup() self._yz_radio = buttons.BaseRadioButton(consts.AXIS[0], parent=self) self._xz_radio = buttons.BaseRadioButton(consts.AXIS[1], parent=self) self._xy_radio = buttons.BaseRadioButton(consts.AXIS[2], parent=self) self._radios = [self._yz_radio, self._xz_radio, self._xy_radio] self._axis_radio_grp.addButton(self._yz_radio) self._axis_radio_grp.addButton(self._xz_radio) self._axis_radio_grp.addButton(self._xy_radio) axis_radio_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) axis_radio_layout.addWidget(self._yz_radio) axis_radio_layout.addWidget(self._xz_radio) axis_radio_layout.addWidget(self._xy_radio) axis_radio_layout.addStretch() global_tolerance_lbl = label.BaseLabel('Global Tolerance: ', parent=self) self._global_tolerance_spn = spinbox.BaseDoubleSpinBox(parent=self) self._global_tolerance_spn.setDecimals(4) self._global_tolerance_spn.setValue(0.0010) top_layout.addWidget(mirror_axis_lbl, 0, 0, Qt.AlignRight) top_layout.addLayout(axis_radio_layout, 0, 1) top_layout.addWidget(global_tolerance_lbl, 1, 0) top_layout.addWidget(self._global_tolerance_spn, 1, 1) options_cbx_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) self._neg_to_pos_cbx = checkbox.BaseCheckBox('Operate -X to +X', parent=self) self._use_pivot_as_origin_cbx = checkbox.BaseCheckBox('Use Pivot as Origin', parent=self) self._use_pivot_as_origin_cbx.setChecked(True) options_cbx_layout.addWidget(self._neg_to_pos_cbx) options_cbx_layout.addItem(QSpacerItem(10, 0, QSizePolicy.Fixed, QSizePolicy.Fixed)) options_cbx_layout.addWidget(self._use_pivot_as_origin_cbx) options_cbx_layout.addStretch() select_geo_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) self._select_geo_line = lineedit.BaseLineEdit(parent=self) self._select_geo_line.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self._select_geo_line.setReadOnly(True) self._select_base_geo_btn = buttons.BaseButton('Select Base Geo', parent=self) self._select_base_geo_btn.setIcon(resources.icon('cursor')) select_geo_layout.addWidget(self._select_geo_line) select_geo_layout.addWidget(self._select_base_geo_btn) self._symmetry_message = message.BaseMessage('', parent=self).small() selection_widget = QWidget(parent=self) selection_layout = layouts.FlowLayout() selection_widget.setLayout(selection_layout) mirror_flip_widget = QWidget(parent=self) mirror_flip_layout = layouts.FlowLayout() mirror_flip_widget.setLayout(mirror_flip_layout) revert_widget = QWidget(parent=self) revert_layout = layouts.FlowLayout() revert_widget.setLayout(revert_layout) self._check_symmetry_btn = buttons.BaseButton('Check Symmetry', parent=self) self._selection_mirror_btn = buttons.BaseButton('Selection Mirror', parent=self) self._select_moved_vertices_btn = buttons.BaseButton('Select Moved Vertices', parent=self) self._mirror_selected_btn = buttons.BaseButton('Mirror Selected', parent=self) self._flip_selected_btn = buttons.BaseButton('Flip Selected', parent=self) self._revert_selected_to_base = buttons.BaseButton('Revert Selected to Base', parent=self) self._revert_bias_slider = sliders.HoudiniDoubleSlider(parent=self, slider_range=[0.0, 1.0]) # TODO: Implement this feature self._live_revert_bias_cbx = checkbox.BaseCheckBox('Live', parent=self) self._live_revert_bias_cbx.setVisible(False) self._check_symmetry_btn.setIcon(resources.icon('refresh')) self._selection_mirror_btn.setIcon(resources.icon('vertex')) self._select_moved_vertices_btn.setIcon(resources.icon('cursor')) self._mirror_selected_btn.setIcon(resources.icon('mirror')) self._flip_selected_btn.setIcon(resources.icon('flip_vertical')) self._revert_selected_to_base.setIcon(resources.icon('rollback')) selection_layout.addWidget(self._check_symmetry_btn) selection_layout.addWidget(self._selection_mirror_btn) selection_layout.addWidget(self._select_moved_vertices_btn) mirror_flip_layout.addWidget(self._mirror_selected_btn) mirror_flip_layout.addWidget(self._flip_selected_btn) revert_layout.addWidget(self._revert_selected_to_base) revert_layout.addWidget(self._revert_bias_slider) revert_layout.addWidget(self._live_revert_bias_cbx) self.main_layout.addLayout(top_layout) self.main_layout.addLayout(options_cbx_layout) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addLayout(select_geo_layout) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addWidget(self._symmetry_message) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addWidget(selection_widget) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addWidget(mirror_flip_widget) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addWidget(revert_widget) self.main_layout.addStretch() def setup_signals(self): self._axis_radio_grp.buttonToggled.connect(self._controller.clear_selection) self._global_tolerance_spn.valueChanged.connect(self._controller.set_global_tolerance) self._select_base_geo_btn.clicked.connect(self._controller.set_base_geo_from_selection) self._neg_to_pos_cbx.toggled.connect(self._controller.set_operate_positive_to_negative_x_axis) self._use_pivot_as_origin_cbx.toggled.connect(self._controller.set_use_pivot_as_origin) self._check_symmetry_btn.clicked.connect(self._controller.check_symmetry) self._selection_mirror_btn.clicked.connect(self._controller.selection_mirror) self._select_moved_vertices_btn.clicked.connect(self._controller.select_moved_vertices) self._mirror_selected_btn.clicked.connect(self._controller.mirror_selected) self._flip_selected_btn.clicked.connect(self._controller.flip_selected) self._revert_selected_to_base.clicked.connect(self._controller.revert_selected_to_base) self._revert_bias_slider.valueChanged.connect(self._controller.set_revert_bias) self._live_revert_bias_cbx.toggled.connect(self._controller.set_live_revert_bias) self._model.globalToleranceChanged.connect(self._on_global_tolerance_changed) self._model.operateFromPositiveToNegativeXAxisChanged.connect( self._on_operate_positive_to_negative_x_axis_changed) self._model.usePivotAsOriginChanged.connect(self._on_use_pivot_as_origin_changed) self._model.baseGeoChanged.connect(self._on_base_geo_changed) self._model.revertBiasChanged.connect(self._on_revert_bias_changed) self._model.liveRevertBiasChanged.connect(self._on_live_revert_bias_changed) self._model.isSymmetricChanged.connect(self._on_refresh_symmetric_message) def refresh(self): self._radios[self._model.mirror_axis].setChecked(True) self._global_tolerance_spn.setValue(self._model.global_tolerance) self._neg_to_pos_cbx.setChecked(self._model.operate_from_positive_to_negative_x_axis) self._use_pivot_as_origin_cbx.setChecked(self._model.use_pivot_as_origin) self._select_geo_line.setText(self._model.base_geo) self._revert_bias_slider.set_value(self._model.revert_bias) self._on_refresh_symmetric_message(self._model.is_symmetric) def _on_base_geo_changed(self, geo_name): """ Internal callbaack function that is called when the selected model is updated in the model :param geo_name: str, name of the selected geometry """ short_geo_name = self._controller.client.node_short_name(geo_name) self._select_geo_line.setText(short_geo_name) enabled = bool(geo_name) self._check_symmetry_btn.setEnabled(enabled) self._selection_mirror_btn.setEnabled(enabled) self._select_moved_vertices_btn.setEnabled(enabled) self._mirror_selected_btn.setEnabled(enabled) self._flip_selected_btn.setEnabled(enabled) self._revert_selected_to_base.setEnabled(enabled) def _on_global_tolerance_changed(self, tolerance_value): """ Internal callback function that is called when global tolerance value is updated in the model :param tolerance_value: float, global tolerance value used to check symmetry of the geometry """ with qt_contexts.block_signals(self._model): self._global_tolerance_spn.setValue(tolerance_value) def _on_operate_positive_to_negative_x_axis_changed(self, flag): """ Internal callback function that is called when operate positive ot negate x axis flag changes in the model :param flag: bool """ with qt_contexts.block_signals(self._model): self._neg_to_pos_cbx.setChecked(flag) def _on_use_pivot_as_origin_changed(self, flag): """ Internal callback function that is called when use pivot as origin flag changes in the model :param flag: bool """ with qt_contexts.block_signals(self._model): self._use_pivot_as_origin_cbx.setChecked(flag) def _on_revert_bias_changed(self, value): """ Internal callback function that is called when revert bias value changes in the model :param value: float, value that sets how much the revert to base geo should be applied to selected vertices """ with qt_contexts.block_signals(self._model): self._revert_bias_slider.set_value(value) def _on_live_revert_bias_changed(self, flag): """ Internal callback function that is called when live revert bias flag changes in the model :param flag: bool, Whether or not revert bias should be applied while its value changes """ with qt_contexts.block_signals(self._model): self._live_revert_bias_cbx.setChecked(flag) def _on_refresh_symmetric_message(self, flag): selected_geo = self._model.base_geo if not selected_geo: msg = 'Select Base geometry please' theme_type = message.MessageTypes.INFO else: if flag: msg = 'Base geometry is symmetrical' theme_type = message.MessageTypes.SUCCESS else: msg = 'Base geometry is not symmetrical' theme_type = message.MessageTypes.WARNING self._symmetry_message.text = msg self._symmetry_message.theme_type = theme_type
class BreadcrumbWidget(base.BaseWidget, object): """ Widget that display current location withing a hierarchy It allows going back/forward inside a hierarchy """ def __init__(self, separator=None, parent=None): super(BreadcrumbWidget, self).__init__(parent=parent) current_theme = self.theme() separator_color = current_theme.accent_color if current_theme else '#E2AC2C' self._separator = separator or "<span style='color:{}'> ▸ </span>".format( separator_color) self._separators = list() self.setObjectName('BreadcrumbWidget') self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) def get_main_layout(self): main_layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) main_layout.addStretch() return main_layout def ui(self): super(BreadcrumbWidget, self).ui() self._button_group = QButtonGroup() def set_items(self, data_list): """ Sets the the items of the breadcrumb cleaning old ones :param data_list: :return: """ for btn in self._button_group.buttons(): self._button_group.removeButton(btn) self.main_layout.removeWidget(btn) btn.setVisible(False) btn.deleteLater() for sep in self._separators: self.main_layout.removeWidget(sep) sep.setVisible(False) sep.deleteLater() python.clear_list(self._separators) for index, data_dict in enumerate(data_list): self.add_item(data_dict, index) def add_item(self, data_dict, index=None): """ Adds a new item to the breadcrumb :param data_dict: dict :param index: int """ btn = buttons.BaseToolButton() btn.setText(data_dict.get('text')) if data_dict.get('image'): btn.image(data_dict.get('image')) if data_dict.get('tooltip'): btn.setProperty('toolTip', data_dict.get('tooltip')) if data_dict.get('clicked'): btn.clicked.connect(data_dict.get('clicked')) if data_dict.get('text'): if data_dict.get('svg') or data_dict.get('icon'): btn.text_beside_icon() else: btn.text_only() else: btn.icon_only() if self._button_group.buttons(): separator = label.BaseLabel(self._separator).secondary() self._separators.append(separator) self.main_layout.insertWidget(self.main_layout.count() - 1, separator) self.main_layout.insertWidget(self.main_layout.count() - 1, btn) if index is None: self._button_group.addButton(btn) else: self._button_group.addButton(btn, index) def set_from_path(self, file_path): """ Creates a proper Breadcrumb list for given path and sets the text """ self._widgets = list() file_path = os.path.dirname(file_path) folders = path.get_folders_from_path(file_path) data_list = list() for folder in folders: data_list.append({'text': folder}) self.set_items(data_list) def get_breadcumbs(self): """ Returns current list of breadcumb texts :return: list(str) """ return [btn.text() for btn in self._button_group.buttons()]
class BaseButtonGroup(base.BaseWidget, object): def __init__(self, orientation=Qt.Horizontal, parent=None): self._orientation = 'horizontal' if orientation == Qt.Horizontal else 'vertical' super(BaseButtonGroup, self).__init__(parent=parent) def get_main_layout(self): main_layout = QBoxLayout(QBoxLayout.LeftToRight if self._orientation == 'horizontal' else QBoxLayout.TopToBottom) main_layout.setContentsMargins(0, 0, 0, 0) return main_layout def ui(self): super(BaseButtonGroup, self).ui() self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self._button_group = QButtonGroup() @decorators.abstractmethod def create_button(self, data_dict): """ Must be implemented in custom button groups Creates a new button for this group :param data_dict: dict :return: new button instance """ raise NotImplementedError( 'Function create_button for class "{}" is not implemented!'.format( self.__class__.__name__)) def get_button_group(self): """ Returns button group internal object :return: QButtonGroup """ return self._button_group def clear(self): """ Clears all buttons contained in this group """ for btn in self._button_group.buttons(): self._button_group.removeButton(btn) self.main_layout.removeWidget(btn) btn.setVisible(False) btn.deleteLater() def add_button(self, data_dict, index=None): """ Adds a new button to this group :param data_dict: dict :param index: int or None :return: new added button """ if python.is_string(data_dict): data_dict = {'text': data_dict} elif isinstance(data_dict, QIcon): data_dict = {'icon': data_dict} new_btn = self.create_button(data_dict) new_btn.setProperty('combine', self._orientation) if data_dict.get('text'): new_btn.setProperty('text', data_dict.get('text')) if data_dict.get('icon'): new_btn.setProperty('icon', data_dict.get('icon')) if data_dict.get('data'): new_btn.setProperty('data', data_dict.get('data')) if data_dict.get('checked'): new_btn.setProperty('checked', data_dict.get('checked')) if data_dict.get('shortcut'): new_btn.setProperty('shortcut', data_dict.get('shortcut')) if data_dict.get('tooltip'): new_btn.setProperty('toolTip', data_dict.get('tooltip')) if data_dict.get('clicked'): new_btn.clicked.connect(data_dict.get('clicked')) if data_dict.get('toggled'): new_btn.toggled.connect(data_dict.get('toggled')) if index is None: self._button_group.addButton(new_btn) else: self._button_group.addButton(new_btn, index) if self.main_layout.count() == 0: new_btn.setChecked(True) self.main_layout.insertWidget(self.main_layout.count(), new_btn) return new_btn def set_button_list(self, button_list): """ Empties group and add all buttons given in the list of buttons :param button_list: list(dict) """ self.clear() for index, data_dict in enumerate(button_list): new_btn = self.add_button(data_dict=data_dict, index=index) if index == 0: new_btn.setProperty('position', 'left') elif index == len(button_list) - 1: new_btn.setProperty('position', 'right') else: new_btn.setProperty('position', 'center')
class MyToolBar(QWidget): """ ToolBar widget """ # signal trigger = Signal(int) def __init__(self, flags, parent=None): super(MyToolBar, self).__init__(parent) self.setWindowFlags(Qt.ToolTip) self.paddingX = 5 self.paddingY = 2 self.iconWidth = self.iconHeight = 28 self.setFixedHeight(self.iconHeight + 2 * self.paddingY) # self.setFixedWidth(300) self.rectButton = None self.ellipseButton = None self.arrowButton = None self.lineButton = None self.freePenButton = None self.textButton = None self.undoButton = None self.cancelButton = None self.okButton = None self.saveButton = None self.button_list = [] self.initWindow(flags) def initDrawButtons(self, flags): self.drawButtonGroup = QButtonGroup(self) # draw action buttons if flags & constant.RECT: self.rectButton = QPushButton(self) self.rectButton.setIcon(QIcon(":/resource/icon/rect.png")) self.rectButton.setFixedSize(self.iconWidth, self.iconHeight) self.rectButton.setCheckable(True) self.drawButtonGroup.addButton(self.rectButton) self.hlayout.addWidget(self.rectButton) self.button_list.append(self.rectButton) if flags & constant.ELLIPSE: self.ellipseButton = QPushButton(self) self.ellipseButton.setIcon(QIcon(":/resource/icon/ellipse.png")) self.ellipseButton.setFixedSize(self.iconWidth, self.iconHeight) self.ellipseButton.setCheckable(True) self.drawButtonGroup.addButton(self.ellipseButton) self.hlayout.addWidget(self.ellipseButton) self.button_list.append(self.ellipseButton) if flags & constant.ARROW: self.arrowButton = QPushButton(self) self.arrowButton.setIcon(QIcon(":/resource/icon/arrow.png")) self.arrowButton.setFixedSize(self.iconWidth, self.iconHeight) self.arrowButton.setCheckable(True) self.drawButtonGroup.addButton(self.arrowButton) self.hlayout.addWidget(self.arrowButton) self.button_list.append(self.arrowButton) if flags & constant.LINE: self.lineButton = QPushButton(self) self.lineButton.setIcon(QIcon(":/resource/icon/line.png")) self.lineButton.setFixedSize(self.iconWidth, self.iconHeight) self.lineButton.setCheckable(True) self.drawButtonGroup.addButton(self.lineButton) self.hlayout.addWidget(self.lineButton) self.button_list.append(self.lineButton) if flags & constant.FREEPEN: self.freePenButton = QPushButton(self) self.freePenButton.setIcon(QIcon(":/resource/icon/pen.png")) self.freePenButton.setFixedSize(self.iconWidth, self.iconHeight) self.freePenButton.setCheckable(True) self.drawButtonGroup.addButton(self.freePenButton) self.hlayout.addWidget(self.freePenButton) self.button_list.append(self.freePenButton) if flags & constant.TEXT: self.textButton = QPushButton(self) self.textButton.setIcon(QIcon(":/resource/icon/text.png")) self.textButton.setFixedSize(self.iconWidth, self.iconHeight) self.textButton.setCheckable(True) self.drawButtonGroup.addButton(self.textButton) self.hlayout.addWidget(self.textButton) self.button_list.append(self.textButton) self.drawButtonGroup.buttonClicked.connect(self.buttonToggled) def initOtherButtons(self, flags): # other action buttons if len(self.button_list) != 0: self.separator1 = QFrame(self) self.separator1.setFrameShape(QFrame.VLine) self.separator1.setFrameShadow(QFrame.Sunken) self.hlayout.addWidget(self.separator1) self.undoButton = QPushButton(self) self.undoButton.setIcon(QIcon(":/resource/icon/undo.png")) self.undoButton.setFixedSize(self.iconWidth, self.iconWidth) self.undoButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.undoButton) if flags & constant.SAVE_TO_FILE: self.saveButton = QPushButton(self) self.saveButton.setIcon(QIcon(":/resource/icon/save.png")) self.saveButton.setFixedSize(self.iconWidth, self.iconHeight) self.saveButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.saveButton) self.separator2 = QFrame(self) self.separator2.setFrameShape(QFrame.VLine) self.separator2.setFrameShadow(QFrame.Sunken) self.hlayout.addWidget(self.separator2) self.cancelButton = QPushButton(self) self.cancelButton.setIcon(QIcon(":/resource/icon/close.png")) self.cancelButton.setFixedSize(self.iconWidth, self.iconHeight) self.cancelButton.clicked.connect(self.otherButtonsClicked) if flags & constant.CLIPBOARD: self.okButton = QPushButton(self) self.okButton.setIcon(QIcon(":/resource/icon/check.png")) self.okButton.setFixedSize(self.iconWidth, self.iconHeight) self.okButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.okButton) self.hlayout.addWidget(self.cancelButton) def initWindow(self, flags): self.hlayout = QHBoxLayout() self.hlayout.setSpacing(2) self.hlayout.setContentsMargins(10, 2, 10, 2) self.setLayout(self.hlayout) self.initDrawButtons(flags) self.initOtherButtons(flags) # slots def buttonToggled(self, button): """ :type button: QPushButton :param button: :return: """ if button == self.rectButton: self.trigger.emit(ACTION_RECT) elif button == self.ellipseButton: self.trigger.emit(ACTION_ELLIPSE) elif button == self.arrowButton: self.trigger.emit(ACTION_ARROW) elif button == self.lineButton: self.trigger.emit(ACTION_LINE) elif button == self.freePenButton: self.trigger.emit(ACTION_FREEPEN) elif button == self.textButton: self.trigger.emit(ACTION_TEXT) else: pass def otherButtonsClicked(self): if self.sender() == self.undoButton: self.trigger.emit(ACTION_UNDO) elif self.sender() == self.cancelButton: self.trigger.emit(ACTION_CANCEL) elif self.sender() == self.okButton: self.trigger.emit(ACTION_SURE) elif self.sender() == self.saveButton: self.trigger.emit(ACTION_SAVE)
class AlembicManagerView(tool.ArtellaToolWidget, object): def __init__(self, project, config, settings, parent): super(AlembicManagerView, self).__init__(project=project, config=config, settings=settings, parent=parent) def ui(self): super(AlembicManagerView, self).ui() export_icon = resources.icon('export') import_icon = resources.icon('import') buttons_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) self.main_layout.addLayout(buttons_layout) self.main_layout.addLayout(dividers.DividerLayout()) self._exporter_btn = buttons.BaseButton('Exporter', parent=self) self._exporter_btn.setIcon(export_icon) self._exporter_btn.setMinimumWidth(80) self._exporter_btn.setCheckable(True) self._importer_btn = buttons.BaseButton('Importer', parent=self) self._importer_btn.setIcon(import_icon) self._importer_btn.setMinimumWidth(80) self._importer_btn.setCheckable(True) buttons_layout.addStretch() buttons_layout.addWidget(self._exporter_btn) buttons_layout.addWidget(self._importer_btn) self._importer_btn.setCheckable(True) self._buttons_grp = QButtonGroup(self) self._buttons_grp.setExclusive(True) self._buttons_grp.addButton(self._exporter_btn) self._buttons_grp.addButton(self._importer_btn) self._exporter_btn.setChecked(True) self._stack = stack.SlidingStackedWidget() self.main_layout.addWidget(self._stack) self._alembic_exporter = exporter.AlembicExporter(project=self.project) self._alembic_importer = importer.AlembicImporter(project=self.project) self._stack.addWidget(self._alembic_exporter) self._stack.addWidget(self._alembic_importer) def setup_signals(self): self._stack.animFinished.connect(self._on_stack_anim_finished) self._exporter_btn.clicked.connect(partial(self._on_slide_stack, 0)) self._importer_btn.clicked.connect(partial(self._on_slide_stack, 1)) self._alembic_exporter.showWarning.connect(self._on_show_warning) self._alembic_exporter.showOk.connect(self._on_show_ok) self._alembic_importer.showOk.connect(self._on_show_ok) def _on_slide_stack(self, index): """ Internal callback function that is called when stack needs to change current widget :param index: int """ if index == self._stack.currentIndex(): return for btn in self._buttons_grp.buttons(): btn.setEnabled(False) self._stack.slide_in_index(index) def _on_stack_anim_finished(self): """ Internal callback function that is called when stack anim finish """ for btn in self._buttons_grp.buttons(): btn.setEnabled(True) if self._stack.currentWidget() == self._alembic_exporter: self._alembic_exporter.refresh() def _on_show_ok(self, warning_msg): """ Internal callback function that is called when an ok message should be showed :param warning_msg: str """ logger.debug(warning_msg) self.show_ok_message(warning_msg) def _on_show_warning(self, warning_msg): """ Internal callback function that is called when a warning message should be showed :param warning_msg: str """ logger.warning(warning_msg) self.show_warning_message(warning_msg)
class RenamerView(base.BaseWidget, object): def __init__(self, model, controller, parent=None): self._model = model self._controller = controller super(RenamerView, self).__init__(parent=parent) self.refresh() @property def model(self): return self._model @property def controller(self): return self._controller def ui(self): super(RenamerView, self).ui() top_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) top_layout.setAlignment(Qt.AlignLeft) self._buttons_grp = QButtonGroup(self) self._buttons_grp.setExclusive(True) self.main_layout.addLayout(top_layout) self.main_layout.addLayout(dividers.DividerLayout()) self._categories_layout = layouts.HorizontalLayout(spacing=2, margins=(2, 2, 2, 2)) self._categories_layout.setAlignment(Qt.AlignLeft) selection_layout = layouts.HorizontalLayout(spacing=2, margins=(4, 0, 4, 0)) top_layout.addLayout(selection_layout) self._all_radio = buttons.BaseRadioButton('All', parent=self) self._all_radio.setFixedHeight(19) self._all_radio.setAutoExclusive(True) self._selected_radio = buttons.BaseRadioButton('Selected', parent=self) self._selected_radio.setFixedHeight(19) self._selected_radio.setChecked(True) self._selected_radio.setAutoExclusive(True) self._hierarchy_cbx = checkbox.BaseCheckBox('Hierarchy', parent=self) self._hierarchy_cbx.setFixedHeight(19) self._node_types_combo = combobox.BaseComboBox(parent=self) self._auto_rename_shapes_cbx = None self._auto_rename_shapes_cbx = checkbox.BaseCheckBox( 'Auto Rename Shapes', parent=self) self._auto_rename_shapes_cbx.setChecked(True) if not dcc.client().is_maya(): self._auto_rename_shapes_cbx.setVisible(False) selection_layout.addWidget(self._selected_radio) selection_layout.addWidget(self._all_radio) selection_layout.addItem( QSpacerItem(10, 0, QSizePolicy.Fixed, QSizePolicy.Fixed)) selection_layout.addWidget(self._hierarchy_cbx) selection_layout.addItem( QSpacerItem(10, 0, QSizePolicy.Fixed, QSizePolicy.Fixed)) selection_layout.addWidget(self._node_types_combo) if self._auto_rename_shapes_cbx: selection_layout.addItem( QSpacerItem(10, 0, QSizePolicy.Fixed, QSizePolicy.Fixed)) selection_layout.addWidget(self._auto_rename_shapes_cbx) self._splitter = splitter.CollapsibleSplitter(parent=self) self._splitter.setOrientation(Qt.Horizontal) self._splitter.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) self._splitter.setMinimumHeight(750) self.main_layout.addWidget(self._splitter) self._rename_tab = tabs.BaseTabWidget(parent=self) self._splitter.addWidget(self._rename_tab) self._manual_rename_widget = manualrenamewidget.ManualRenameWidget( model=self._model, controller=self._controller, parent=self) self._auto_rename_widget = autorenamewidget.AutoRenameWidget( model=self._model, controller=self._controller, parent=self) self._rename_tab.addTab(self._manual_rename_widget, 'Manual') self._rename_tab.addTab(self._auto_rename_widget, 'Auto') self._stack = stack.SlidingStackedWidget() # splitter_right_widget = QWidget() # splitter_right_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) # splitter_right_layout.addLayout(self._categories_layout) # splitter_right_layout.addWidget(self._stack) # splitter_right_widget.setLayout(splitter_right_layout) # self._splitter.addWidget(splitter_right_widget) # # no_items_widget = QFrame() # no_items_widget.setFrameShape(QFrame.StyledPanel) # no_items_widget.setFrameShadow(QFrame.Sunken) # no_items_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) # no_items_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) # no_items_widget.setLayout(no_items_layout) # no_items_lbl = label.BaseLabel() # no_items_pixmap = tp.ResourcesMgr().pixmap('no_items') # no_items_lbl.setPixmap(no_items_pixmap) # no_items_lbl.setAlignment(Qt.AlignCenter) # no_items_layout.addItem(QSpacerItem(0, 10, QSizePolicy.Preferred, QSizePolicy.Expanding)) # no_items_layout.addWidget(no_items_lbl) # no_items_layout.addItem(QSpacerItem(0, 10, QSizePolicy.Preferred, QSizePolicy.Expanding)) # # self._stack.addWidget(no_items_widget) self._splitter.handle(0).collapse() self._splitter.setSizes([1, 0]) def setup_signals(self): self._stack.animFinished.connect(self._on_stack_anim_finished) self._rename_tab.currentChanged.connect(self._on_tab_changed) self._selected_radio.clicked.connect(self._controller.set_selected) self._all_radio.clicked.connect(self._controller.set_all_selection) self._hierarchy_cbx.toggled.connect( self._controller.hierarchy_check_toggle) self._node_types_combo.currentIndexChanged.connect( self._controller.set_filter_type) self._auto_rename_shapes_cbx.toggled.connect( self._controller.auto_rename_shapes_check_toggle) self._model.hierarchyCheckChanged.connect( self._on_toggle_hierarchy_cbx) self._model.renameShapeChanged.connect( self._on_toggle_auto_rename_shape_cbx) self._model.filterTypeChanged.connect(self._on_filter_type_changed) def refresh(self): """ Syncs view to the current state of its model """ self._hierarchy_cbx.setChecked(self._model.hierarchy_check) self._node_types_combo.clear() for btn in self._buttons_grp.buttons(): self._buttons_grp.removeButton(btn) node_types = self._model.node_types if not node_types: self._node_types_combo.setVisible(False) else: self._node_types_combo.setVisible(True) for node_type in node_types: self._node_types_combo.addItem(str(node_type).split('.')[-1]) categories = self._model.categories or dict() nodes_to_discard = self._model.nodes_to_discard types_to_discard = self._model.types_to_discard for node_type in types_to_discard: nodes_to_discard.extend(dcc.list_nodes(node_type=node_type)) for i, category in enumerate(categories): for category_name, category_data in category.items(): title = category_data.get('title', category) icon = category_data.get('icon', None) types = category_data.get('types', dict()) category_btn = buttons.BaseButton(title) category_btn.setCheckable(True) if icon: category_btn.setIcon(resources.icon(icon)) if i == 0: category_btn.setChecked(True) self._buttons_grp.addButton(category_btn) self._categories_layout.addWidget(category_btn) category_widget = categorywidget.CategoryWidget( types=types, nodes_to_discard=nodes_to_discard) self._stack.addWidget(category_widget) # category_widget.doRefresh.connect(self._on_refresh_category) # category_widget.doPreview.connect(self._set_preview_names) # category_widget.togglePreview.connect(self.update_current_items) # category_widget.doRename.connect(self._on_rename) # category_btn.clicked.connect(partial(self._on_category_selected, i + 1)) self._auto_rename_widget.refresh() self._controller.update_rules() def _on_stack_anim_finished(self, index): """ Internal callback function that is called when stack animation is completed :param index: :return: """ for btn in self._buttons_grp.buttons(): btn.setEnabled(True) category_widget = self._stack.current_widget if not category_widget: return # self._on_refresh_category(category_widget) def _on_tab_changed(self, tab_index): """ Internal callback function that is called when tab widget is changed by the user :param tab_index: int """ if tab_index != 1: return self._controller.update_rules() def _on_toggle_hierarchy_cbx(self, flag): """ Internal callback function called when the user toggles hierarchy check box :param flag: bool """ self._hierarchy_cbx.setChecked(flag) def _on_toggle_auto_rename_shape_cbx(self, flag): """ Internal callback function called when the user toggles auto rename shape check box :param flag: bool """ self._auto_rename_shapes_cbx.setChecked(flag) def _on_filter_type_changed(self, value): """ Internal callback function that is called when user changes the filter type combo box :param value: str """ self._node_types_combo.setCurrentText(value)
class PenSetWidget(QWidget): penSizeTrigger = Signal(int) penColorTrigger = Signal(str) fontChangeTrigger = Signal(QFont) def __init__(self, parent=None): super(PenSetWidget, self).__init__(parent) self.paddingX = 5 self.paddingY = 2 self.iconWidth = self.iconHeight = 24 self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.setWindowFlags(Qt.ToolTip) self.initWindows() self.prevSizeButton = self.penSize1 self.penSize1.setChecked(True) self.presentColor.setStyleSheet( 'QPushButton { background-color: %s; }' % PENCOLOR) def generateButtons(self, parent=None): """ Generate buttons due to colorDic """ self.colorButtons = [] for color in self.colorList: button = QPushButton(parent) button.setObjectName(color[0]) button.setStyleSheet('QPushButton { background-color: %s; }' % color[1]) button.setFixedSize(self.iconWidth / 2, self.iconHeight / 2) button.setCheckable(True) self.colorButtons.append(button) def initWindows(self): self.mainLayout = QHBoxLayout() self.setLayout(self.mainLayout) self.mainLayout.setSpacing(0) self.mainLayout.setContentsMargins(5, 2, 5, 2) self.initPenSizeButtons() self.initFontWidget() self.initPenColorButtons() self.separator = QFrame(self) self.separator.setFrameShape(QFrame.VLine) self.separator.setFrameShadow(QFrame.Sunken) self.mainLayout.addWidget(self.penSize) self.mainLayout.addWidget(self.changeFontButton) self.mainLayout.addWidget(self.separator) self.mainLayout.addWidget(self.colorSet) def initPenSizeButtons(self): self.penSize = QWidget(self) self.penSizeLayout = QHBoxLayout() self.penSize.setLayout(self.penSizeLayout) # adjust pen size self.penSize1 = QPushButton(self.penSize) self.penSize1.setIcon(QIcon(":/resource/icon/pensize1.png")) self.penSize1.setObjectName('1') self.penSize1.setFixedSize(self.iconWidth, self.iconHeight) self.penSize1.setCheckable(True) self.penSize2 = QPushButton(self.penSize) self.penSize2.setIcon(QIcon(":/resource/icon/pensize2.png")) self.penSize2.setObjectName('2') self.penSize2.setFixedSize(self.iconWidth, self.iconHeight) self.penSize2.setCheckable(True) self.penSize3 = QPushButton(self.penSize) self.penSize3.setIcon(QIcon(":/resource/icon/pensize3.png")) self.penSize3.setObjectName('3') self.penSize3.setFixedSize(self.iconWidth, self.iconHeight) self.penSize3.setCheckable(True) self.sizeButtonGroup = QButtonGroup(self.penSize) self.sizeButtonGroup.addButton(self.penSize1) self.sizeButtonGroup.addButton(self.penSize2) self.sizeButtonGroup.addButton(self.penSize3) self.sizeButtonGroup.buttonClicked.connect(self.sizeButtonToggled) self.penSizeLayout.addWidget(self.penSize1) self.penSizeLayout.addWidget(self.penSize2) self.penSizeLayout.addWidget(self.penSize3) self.penSizeLayout.setSpacing(5) self.penSizeLayout.setContentsMargins(0, 0, 0, 0) def initPenColorButtons(self): self.colorSet = QWidget(self) self.colorLayout = QHBoxLayout() self.colorLayout.setSpacing(5) self.colorLayout.setContentsMargins(5, 0, 5, 0) self.colorSet.setLayout(self.colorLayout) self.presentColor = QPushButton(self.colorSet) self.presentColor.setFixedSize(self.iconWidth, self.iconHeight) self.presentColor.setEnabled(False) # adjust pen color self.colorPick = QWidget(self.colorSet) self.colorGrid = QGridLayout() self.colorGrid.setSpacing(0) self.colorGrid.setContentsMargins(5, 0, 5, 0) self.colorPick.setLayout(self.colorGrid) self.colorList = [('white', '#ffffff'), ('red', '#ff0000'), ('green', '#00ff00'), ('blue', '#0000ff'), ('cyan', '#00ffff'), ('magenta', '#ff00ff'), ('yellow', '#ffff00'), ('gray', '#a0a0a4'), ('black', '#000000'), ('darkRed', '#800000'), ('darkGreen', '#008000'), ('darkBlue', '#000080'), ('darkCyan', '#008080'), ('darkMagenta', '#800080'), ('darkYellow', '#808000'), ('darkGray', '#808080')] self.generateButtons() self.colorButtonGroup = QButtonGroup(self) for button in self.colorButtons: self.colorButtonGroup.addButton(button) self.colorButtonGroup.buttonClicked.connect(self.colorButtonToggled) # set the layout tmp = 0 for x in range(0, 2): for y in range(0, int(len(self.colorList) / 2)): self.colorGrid.addWidget(self.colorButtons[tmp], x, y) tmp += 1 self.colorGrid.setSpacing(0) self.colorGrid.setContentsMargins(0, 0, 0, 0) self.colorLayout.addWidget(self.presentColor) self.colorLayout.addWidget(self.colorPick) def initFontWidget(self): self.fontDialog = QFontDialog() self.changeFontButton = QPushButton(self) self.fontDialog.setCurrentFont(QFont('Sans serif')) self.changeFontButton.setText('{0} {1}'.format( self.fontDialog.currentFont().family(), self.fontDialog.currentFont().pointSize())) self.changeFontButton.clicked.connect(self.fontButtonClicked) def showFontWidget(self): self.changeFontButton.show() self.penSize1.hide() self.penSize2.hide() self.penSize3.hide() def showPenWidget(self): self.changeFontButton.hide() self.penSize1.show() self.penSize2.show() self.penSize3.show() # slots def colorButtonToggled(self, button): self.presentColor.setStyleSheet( 'QPushButton { background-color: %s; }' % button.objectName()) self.penColorTrigger.emit(button.objectName()) def sizeButtonToggled(self, button): self.penSizeTrigger.emit(int(button.objectName()) * 2) def fontButtonClicked(self): ok = True font = QFontDialog.getFont(self) if font[1]: self.changeFontButton.setText('{0} {1}'.format( font[0].family(), font[0].pointSize())) self.fontChangeTrigger.emit(font[0])
def init_ui(self, name): self.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel) self.graphicsView = GraphicsView(self) self.graphicsView.setRenderHint(QPainter.Antialiasing, False) self.graphicsView.setDragMode(QGraphicsView.RubberBandDrag) self.graphicsView.setOptimizationFlags(QGraphicsView.DontSavePainterState) self.graphicsView.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate) self.graphicsView.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) size = self.style().pixelMetric(QStyle.PM_ToolBarIconSize) iconSize = QSize(size, size) zoomInIcon = QToolButton() zoomInIcon.setAutoRepeat(True) zoomInIcon.setAutoRepeatInterval(33) zoomInIcon.setAutoRepeatDelay(0) zoomInIcon.setIcon(QIcon(":/zoomin.png")) zoomInIcon.setIconSize(iconSize) zoomOutIcon = QToolButton() zoomOutIcon.setAutoRepeat(True) zoomOutIcon.setAutoRepeatInterval(33) zoomOutIcon.setAutoRepeatDelay(0) zoomOutIcon.setIcon(QIcon(":/zoomout.png")) zoomOutIcon.setIconSize(iconSize) self.zoomSlider = QSlider() self.zoomSlider.setMinimum(0) self.zoomSlider.setMaximum(500) self.zoomSlider.setValue(250) self.zoomSlider.setTickPosition(QSlider.TicksRight) # Zoom slider layout zoomSliderLayout = QVBoxLayout() zoomSliderLayout.addWidget(zoomInIcon) zoomSliderLayout.addWidget(self.zoomSlider) zoomSliderLayout.addWidget(zoomOutIcon) rotateLeftIcon = QToolButton() rotateLeftIcon.setIcon(QIcon(":/rotateleft.png")) rotateLeftIcon.setIconSize(iconSize) rotateRightIcon = QToolButton() rotateRightIcon.setIcon(QIcon(":/rotateright.png")) rotateRightIcon.setIconSize(iconSize) self.rotateSlider = QSlider() self.rotateSlider.setOrientation(Qt.Horizontal) self.rotateSlider.setMinimum(-360) self.rotateSlider.setMaximum(360) self.rotateSlider.setValue(0) self.rotateSlider.setTickPosition(QSlider.TicksBelow) # Rotate slider layout rotateSliderLayout = QHBoxLayout() rotateSliderLayout.addWidget(rotateLeftIcon) rotateSliderLayout.addWidget(self.rotateSlider) rotateSliderLayout.addWidget(rotateRightIcon) self.resetButton = QToolButton() self.resetButton.setText("0") self.resetButton.setEnabled(False) # Label layout labelLayout = QHBoxLayout() self.label = QLabel(name) self.label2 = QLabel("Pointer Mode") self.selectModeButton = QToolButton() self.selectModeButton.setText("Select") self.selectModeButton.setCheckable(True) self.selectModeButton.setChecked(True) self.dragModeButton = QToolButton() self.dragModeButton.setText("Drag") self.dragModeButton.setCheckable(True) self.dragModeButton.setChecked(False) self.antialiasButton = QToolButton() self.antialiasButton.setText("Antialiasing") self.antialiasButton.setCheckable(True) self.antialiasButton.setChecked(False) self.openGlButton = QToolButton() self.openGlButton.setText("OpenGL") self.openGlButton.setCheckable(True) self.openGlButton.setEnabled(QGLFormat.hasOpenGL()) pointerModeGroup = QButtonGroup() pointerModeGroup.setExclusive(True) pointerModeGroup.addButton(self.selectModeButton) pointerModeGroup.addButton(self.dragModeButton) labelLayout.addWidget(self.label) labelLayout.addStretch() labelLayout.addWidget(self.label2) labelLayout.addWidget(self.selectModeButton) labelLayout.addWidget(self.dragModeButton) labelLayout.addStretch() labelLayout.addWidget(self.antialiasButton) labelLayout.addWidget(self.openGlButton) topLayout = QGridLayout() topLayout.addLayout(labelLayout, 0, 0) topLayout.addWidget(self.graphicsView, 1, 0) topLayout.addLayout(zoomSliderLayout, 1, 1) topLayout.addLayout(rotateSliderLayout, 2, 0) topLayout.addWidget(self.resetButton, 2, 1) self.setLayout(topLayout) self.resetButton.clicked.connect(self.resetView) self.zoomSlider.valueChanged.connect(self.setupTransform) self.rotateSlider.valueChanged.connect(self.setupTransform) self.graphicsView.verticalScrollBar().valueChanged.connect(self.setResetButtonEnabled) self.graphicsView.horizontalScrollBar().valueChanged.connect(self.setResetButtonEnabled) self.selectModeButton.toggled.connect(self.togglePointerMode) self.dragModeButton.toggled.connect(self.togglePointerMode) self.antialiasButton.toggled.connect(self.toggleAntialiasing) self.openGlButton.toggled.connect(self.toggleOpenGL) rotateLeftIcon.clicked.connect(self.rotateLeft) rotateRightIcon.clicked.connect(self.rotateRight) zoomInIcon.clicked.connect(self.zoomIn) zoomOutIcon.clicked.connect(self.zoomOut) self.setupTransform()
def ui(self): super(NumberSideView, self).ui() rename_mult_layout = layouts.HorizontalLayout(spacing=5, margins=(0, 0, 0, 0)) rename_mult_layout.setAlignment(Qt.AlignLeft) self.main_layout.addLayout(rename_mult_layout) self._rename_mult_cbx = checkbox.BaseCheckBox(parent=self) self._rename_mult_cbx.setChecked(True) self._rename_mult_method_lbl = label.BaseLabel('Number: ', parent=self) self._renamer_mult_method_combo = combobox.BaseComboBox(parent=self) self._renamer_mult_method_combo.addItem('Numbers (0-9)') self._renamer_mult_method_combo.addItem('Letters (a-z)') rename_mult_layout.addWidget(self._rename_mult_cbx) rename_mult_layout.addWidget(self._rename_mult_method_lbl) rename_mult_layout.addWidget(self._renamer_mult_method_combo) self._frame_pad_lbl = label.BaseLabel('Pad: ', parent=self) self._frame_pad_spin = spinbox.BaseSpinBox(parent=self) self._frame_pad_spin.setValue(2) self._frame_pad_spin.setFocusPolicy(Qt.NoFocus) self._frame_pad_spin.setMinimum(1) self._frame_pad_spin.setMaximum(10) self._frame_combo = combobox.BaseComboBox(parent=self) self._frame_combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self._frame_combo.addItems(['Replace', 'Append', 'Change Pad']) self._frame_btn = buttons.BaseButton() self._frame_btn.setIcon(resources.icon('numbered_list')) rename_mult_layout.addWidget(self._frame_pad_lbl) rename_mult_layout.addWidget(self._frame_pad_spin) rename_mult_layout.addWidget(self._frame_combo) lower_upper_grp = QButtonGroup(self) self._lower_radio = buttons.BaseRadioButton('Lower', parent=self) self._upper_radio = buttons.BaseRadioButton('Upper', parent=self) lower_upper_grp.addButton(self._lower_radio) lower_upper_grp.addButton(self._upper_radio) self._lower_radio.setVisible(False) self._upper_radio.setVisible(False) self._lower_radio.setFixedHeight(19) self._upper_radio.setFixedHeight(19) self._upper_radio.setAutoExclusive(True) self._lower_radio.setAutoExclusive(True) self._lower_radio.setChecked(True) self._lower_radio.setEnabled(False) self._upper_radio.setEnabled(False) rename_mult_layout.addWidget(self._lower_radio) rename_mult_layout.addWidget(self._upper_radio) rename_mult_layout.addWidget(self._frame_btn) self.main_layout.addLayout(dividers.DividerLayout()) side_layout = layouts.HorizontalLayout(spacing=2, margins=(0, 0, 0, 0)) side_layout.setAlignment(Qt.AlignLeft) self.main_layout.addLayout(side_layout) self._side_cbx = checkbox.BaseCheckBox(parent=self) self._side_cbx.setChecked(True) side_layout.addWidget(self._side_cbx) self._side_lbl = label.BaseLabel('Side: ', parent=self) self._none_side = buttons.BaseRadioButton('None', parent=self) self._right_side = buttons.BaseRadioButton('Right', parent=self) self._center_side = buttons.BaseRadioButton('Center', parent=self) self._mid_side = buttons.BaseRadioButton('Mid', parent=self) self._left_side = buttons.BaseRadioButton('Left', parent=self) self._none_side.setFixedHeight(15) self._right_side.setFixedHeight(15) self._center_side.setFixedHeight(15) self._mid_side.setFixedHeight(15) self._left_side.setFixedHeight(15) side_layout.addWidget(self._side_lbl) side_layout.addWidget(self._none_side) side_layout.addWidget(self._right_side) side_layout.addWidget(self._center_side) side_layout.addWidget(self._mid_side) side_layout.addWidget(self._left_side) self._none_side.setAutoExclusive(True) self._right_side.setAutoExclusive(True) self._center_side.setAutoExclusive(True) self._mid_side.setAutoExclusive(True) self._left_side.setAutoExclusive(True) self._none_side.setChecked(True) self._capital_side = checkbox.BaseCheckBox('Capital?', parent=self) self._side_btn = buttons.BaseButton(parent=self) self._side_btn.setIcon(resources.icon('font_size')) side_layout.addStretch() side_layout.addWidget(self._capital_side) side_layout.addStretch() side_layout.addWidget(self._side_btn)