示例#1
0
    def onUpdatePropertyView(self, formLayout):
        # name
        le_name = QLineEdit(self.getName())
        le_name.setReadOnly(True)
        if self.label().IsRenamable():
            le_name.setReadOnly(False)
            le_name.returnPressed.connect(lambda: self.setName(le_name.text()))
        formLayout.addRow("Name", le_name)

        # uid
        leUid = QLineEdit(str(self.uid))
        leUid.setReadOnly(True)
        #formLayout.addRow("Uuid", leUid)

        # type
        leType = QLineEdit(self.__class__.__name__)
        leType.setReadOnly(True)
        formLayout.addRow("Type", leType)

        # pos
        #le_pos = QLineEdit("{0} x {1}".format(self.pos().x(), self.pos().y()))
        #formLayout.addRow("Pos", le_pos)

        # inputs
        if len([i for i in self.inputs.values()]) != 0:
            for inp in self.inputs.values():
                dataSetter = inp.call if inp.dataType == DataTypes.Exec else inp.setData
                if not inp.hasConnections():
                    w = getInputWidget(inp.dataType, dataSetter,
                                       inp.defaultValue(), inp.getUserStruct())
                    if w:
                        w.setWidgetValue(inp.currentData())
                        w.setObjectName(inp.getName())
                        formLayout.addRow(inp.name, w)
                        if inp.hasConnections():
                            w.setEnabled(False)
                            w.hide()
        if self.asGraphSides:
            # outputs

            if len([i for i in self.outputs.values()]) != 0:
                for out in self.outputs.values():
                    dataSetter = out.call if out.dataType == DataTypes.Exec else out.setData
                    w = getInputWidget(out.dataType, dataSetter,
                                       out.defaultValue(), out.getUserStruct())
                    if w:
                        w.setWidgetValue(out.currentData())
                        w.setObjectName(out.getName())
                        formLayout.addRow(out.name, w)
                        if out.hasConnections():
                            w.setEnabled(True)

        doc_lb = QLabel()
        doc_lb.setStyleSheet("background-color: black;")
        doc_lb.setText("Description")
        #formLayout.addRow("", doc_lb)
        doc = QTextBrowser()
        doc.setOpenExternalLinks(True)
        doc.setHtml(self.description())
示例#2
0
    def onUpdatePropertyView(self, formLayout):

        # name
        le_name = QLineEdit(self.getName())
        le_name.setReadOnly(True)
        if self.label().IsRenamable():
            le_name.setReadOnly(False)
            le_name.returnPressed.connect(lambda: self.setName(le_name.text()))
        formLayout.addRow("Name", le_name)

        # uid
        leUid = QLineEdit(str(self.uid))
        leUid.setReadOnly(True)
        formLayout.addRow("Uuid", leUid)

        # type
        leType = QLineEdit(self.__class__.__name__)
        leType.setReadOnly(True)
        formLayout.addRow("Type", leType)

        # pos
        le_pos = QLineEdit("{0} x {1}".format(self.pos().x(), self.pos().y()))
        formLayout.addRow("Pos", le_pos)

        pb = QPushButton("...")
        pb.clicked.connect(self.onChangeColor)
        formLayout.addRow("Color", pb)

        doc_lb = QLabel()
        doc_lb.setStyleSheet("background-color: black;")
        doc_lb.setText("Description")
        formLayout.addRow("", doc_lb)
        doc = QTextBrowser()
        doc.setOpenExternalLinks(True)
        doc.setHtml(self.description())
        formLayout.addRow("", doc)
示例#3
0
class DockTitleBar(QWidget, object):
    def __init__(self, dock_widget, renamable=False):
        super(DockTitleBar, self).__init__(dock_widget)

        self._renamable = renamable

        main_layout = QHBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 1)
        self.setLayout(main_layout)

        self._buttons_box = QGroupBox('')
        self._buttons_box.setObjectName('Docked')
        self._buttons_layout = QHBoxLayout()
        self._buttons_layout.setSpacing(1)
        self._buttons_layout.setMargin(2)
        self._buttons_box.setLayout(self._buttons_layout)
        main_layout.addWidget(self._buttons_box)

        self._title_label = QLabel(self)
        self._title_label.setStyleSheet('background: transparent')
        self._title_edit = QLineEdit(self)
        self._title_edit.setVisible(False)

        self._button_size = QSize(14, 14)

        self._dock_btn = QToolButton(self)
        self._dock_btn.setIcon(resources.icon('restore_window', theme='color'))
        self._dock_btn.setMaximumSize(self._button_size)
        self._dock_btn.setAutoRaise(True)
        self._close_btn = QToolButton(self)
        self._close_btn.setIcon(resources.icon('close_window', theme='color'))
        self._close_btn.setMaximumSize(self._button_size)
        self._close_btn.setAutoRaise(True)

        self._buttons_layout.addSpacing(2)
        self._buttons_layout.addWidget(self._title_label)
        self._buttons_layout.addWidget(self._title_edit)
        self._buttons_layout.addStretch()
        self._buttons_layout.addSpacing(5)
        self._buttons_layout.addWidget(self._dock_btn)
        self._buttons_layout.addWidget(self._close_btn)

        self._buttons_box.mouseDoubleClickEvent = self.mouseDoubleClickEvent
        self._buttons_box.mousePressEvent = self.mousePressEvent
        self._buttons_box.mouseMoveEvent = self.mouseMoveEvent
        self._buttons_box.mouseReleaseEvent = self.mouseReleaseEvent

        dock_widget.featuresChanged.connect(self._on_dock_features_changed)
        self._title_edit.editingFinished.connect(self._on_finish_edit)
        self._dock_btn.clicked.connect(self._on_dock_btn_clicked)
        self._close_btn.clicked.connect(self._on_close_btn_clicked)

        self._on_dock_features_changed(dock_widget.features())
        self.set_title(dock_widget.windowTitle())
        dock_widget.installEventFilter(self)
        dock_widget.topLevelChanged.connect(self._on_change_floating_style)

    @property
    def renamable(self):
        return self._renamable

    @renamable.setter
    def renamable(self, flag):
        self._renamable = flag

    def eventFilter(self, obj, event):
        if event.type() == QEvent.WindowTitleChange:
            self.set_title(obj.windowTitle())
        return super(DockTitleBar, self).eventFilter(obj, event)

    def mouseMoveEvent(self, event):
        event.ignore()

    def mousePressEvent(self, event):
        event.ignore()

    def mouseReleaseEvent(self, event):
        event.ignore()

    def mouseDoubleClickEvent(self, event):
        if event.pos().x() <= self._title_label.width() and self._renamable:
            self._start_edit()
        else:
            super(DockTitleBar, self).mouseDoubleClickEvent(event)

    def update(self, *args, **kwargs):
        self._on_change_floating_style(self.parent().isFloating())
        super(DockTitleBar, self).update(*args, **kwargs)

    def set_title(self, title):
        self._title_label.setText(title)
        self._title_edit.setText(title)

    def add_button(self, button):
        button.setAutoRaise(True)
        button.setMaximumSize(self._button_size)
        self._buttons_layout.insertWidget(5, button)

    def _start_edit(self):
        self._title_label.hide()
        self._title_edit.show()
        self._title_edit.setFocus()

    def _finish_edit(self):
        self._title_edit.hide()
        self._title_label.show()
        self.parent().setWindowTitle(self._title_edit.text())

    def _on_dock_features_changed(self, features):
        if not features & QDockWidget.DockWidgetVerticalTitleBar:
            self._close_btn.setVisible(features
                                       & QDockWidget.DockWidgetClosable)
            self._dock_btn.setVisible(features
                                      & QDockWidget.DockWidgetFloatable)
        else:
            raise ValueError('Vertical title bar is not supported!')

    def _on_finish_edit(self):
        self._finish_edit()

    def _on_dock_btn_clicked(self):
        self.parent().setFloating(not self.parent().isFloating())

    def _on_close_btn_clicked(self):
        self.parent().toggleViewAction().setChecked(False)
        self.parent().close()

    def _on_change_floating_style(self, state):
        pass
示例#4
0
class BaseColorDialog(BaseDialog, object):

    def_title = 'Select Color'

    maya_colors = [(.467, .467, .467), (.000, .000, .000), (.247, .247, .247),
                   (.498, .498, .498), (0.608, 0, 0.157), (0, 0.016, 0.373),
                   (0, 0, 1), (0, 0.275, 0.094), (0.145, 0, 0.263),
                   (0.78, 0, 0.78), (0.537, 0.278, 0.2), (0.243, 0.133, 0.122),
                   (0.6, 0.145, 0), (1, 0, 0), (0, 1, 0), (0, 0.255, 0.6),
                   (1, 1, 1), (1, 1, 0), (0.388, 0.863, 1), (0.263, 1, 0.635),
                   (1, 0.686, 0.686), (0.89, 0.675, 0.475), (1, 1, 0.384),
                   (0, 0.6, 0.325), (0.627, 0.412, 0.188),
                   (0.62, 0.627, 0.188), (0.408, 0.627, 0.188),
                   (0.188, 0.627, 0.365), (0.188, 0.627, 0.627),
                   (0.188, 0.404, 0.627), (0.435, 0.188, 0.627),
                   (0.627, 0.188, 0.404)]

    def __init__(self, name='MayaColorDialog', parent=None, **kwargs):
        parent = parent or dcc.get_main_window()

        super(BaseColorDialog, self).__init__(name=name,
                                              parent=parent,
                                              **kwargs)

        self._color = None

    def get_color(self):
        return self._color

    color = property(get_color)

    def ui(self):

        self.color_buttons = list()

        super(BaseColorDialog, self).ui()

        grid_layout = layouts.GridLayout()
        grid_layout.setAlignment(Qt.AlignTop)
        self.main_layout.addLayout(grid_layout)
        color_index = 0
        for i in range(0, 4):
            for j in range(0, 8):
                color_btn = QPushButton()
                color_btn.setMinimumHeight(35)
                color_btn.setMinimumWidth(35)
                self.color_buttons.append(color_btn)
                color_btn.setStyleSheet(
                    'background-color:rgb(%s,%s,%s);' %
                    (self.maya_colors[color_index][0] * 255,
                     self.maya_colors[color_index][1] * 255,
                     self.maya_colors[color_index][2] * 255))
                grid_layout.addWidget(color_btn, i, j)
                color_index += 1
        selected_color_layout = layouts.HorizontalLayout()
        self.main_layout.addLayout(selected_color_layout)
        self.color_slider = QSlider(Qt.Horizontal)
        self.color_slider.setMinimum(0)
        self.color_slider.setMaximum(31)
        self.color_slider.setValue(2)
        self.color_slider.setStyleSheet(
            "QSlider::groove:horizontal {border: 1px solid #999999;height: 25px; /* the groove expands "
            "to the size of the slider by default. by giving it a height, it has a fixed size */background: "
            "qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);margin: 2px 0;}"
            "QSlider::handle:horizontal {background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4,"
            " stop:1 #8f8f8f);border: 1px solid #5c5c5c;width: 10px;margin: -2px 0; /* handle is placed by "
            "default on the contents rect of the groove. Expand outside the groove */border-radius: 1px;}"
        )
        selected_color_layout.addWidget(self.color_slider)

        color_label_layout = layouts.HorizontalLayout(margins=(10, 10, 10, 10))
        self.main_layout.addLayout(color_label_layout)

        self.color_lbl = QLabel()
        self.color_lbl.setStyleSheet(
            "border: 1px solid black; background-color:rgb(0, 0, 0);")
        self.color_lbl.setMinimumWidth(45)
        self.color_lbl.setMaximumWidth(80)
        self.color_lbl.setMinimumHeight(80)
        self.color_lbl.setAlignment(Qt.AlignCenter)
        color_label_layout.addWidget(self.color_lbl)

        bottom_layout = layouts.HorizontalLayout()
        bottom_layout.setAlignment(Qt.AlignRight)
        self.main_layout.addLayout(bottom_layout)

        self.ok_btn = QPushButton('Ok')
        self.cancel_btn = QPushButton('Cancel')
        bottom_layout.addLayout(dividers.DividerLayout())
        bottom_layout.addWidget(self.ok_btn)
        bottom_layout.addWidget(self.cancel_btn)

    def setup_signals(self):

        for i, btn in enumerate(self.color_buttons):
            btn.clicked.connect(partial(self._on_set_color, i))
        self.color_slider.valueChanged.connect(self._on_set_color)

        self.ok_btn.clicked.connect(self._on_ok_btn)
        self.cancel_btn.clicked.connect(self._on_cancel_btn)

    def _on_set_color(self, color_index):
        self.color_lbl.setStyleSheet('background-color:rgb(%s,%s,%s);' %
                                     (self.maya_colors[color_index][0] * 255,
                                      self.maya_colors[color_index][1] * 255,
                                      self.maya_colors[color_index][2] * 255))
        self.color_slider.setValue(color_index)

    def _on_set_slider(self, color_index):
        self._set_color(color_index=color_index)

    def _on_ok_btn(self):
        self._color = self.color_slider.value()
        self.close()

    def _on_cancel_btn(self):
        self._color = None
        self.close()
示例#5
0
    def _addPin(self,
                pinDirection,
                dataType,
                foo,
                hideLabel=False,
                bCreateInputWidget=True,
                name='',
                index=-1,
                userStructClass=ENone,
                defaultValue=None):
        # check if pins with this name already exists and get uniq name
        name = self.getUniqPinName(name)

        p = CreatePin(name,
                      self,
                      dataType,
                      pinDirection,
                      userStructClass=userStructClass)
        if defaultValue is not None:
            p.setDefaultValue(defaultValue)

        self.graph().pins[p.uid] = p

        if pinDirection == PinDirection.Input and foo is not None:
            p.call = foo

        connector_name = QGraphicsProxyWidget()
        connector_name.setObjectName('{0}PinConnector'.format(name))
        connector_name.setContentsMargins(0, 0, 0, 0)

        lblName = name
        if hideLabel:
            lblName = ''
            p.bLabelHidden = True

        lbl = QLabel(lblName)
        p.nameChanged.connect(lbl.setText)
        lbl.setContentsMargins(0, 0, 0, 0)
        lbl.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        font = QtGui.QFont('Consolas')
        color = Colors.PinNameColor
        font.setPointSize(6)
        lbl.setFont(font)
        style = 'color: rgb({0}, {1}, {2}, {3});'.format(
            color.red(), color.green(), color.blue(), color.alpha())
        lbl.setStyleSheet(style)
        connector_name.setWidget(lbl)
        if pinDirection == PinDirection.Input:
            container = self.addContainer(pinDirection)
            if hideLabel:
                container.setMinimumWidth(15)
            lbl.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
            container.layout().addItem(p)
            p._container = container
            container.layout().addItem(connector_name)

            self.inputs[p.uid] = p
            self.inputsLayout.insertItem(index, container)
            container.adjustSize()
        elif pinDirection == PinDirection.Output:
            container = self.addContainer(pinDirection)
            if hideLabel:
                container.setMinimumWidth(15)
            lbl.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTop)
            container.layout().addItem(connector_name)
            container.layout().addItem(p)
            p._container = container
            self.outputs[p.uid] = p
            self.outputsLayout.insertItem(index, container)
            container.adjustSize()
        p.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        # create member if created in runtime
        if not hasattr(self, name):
            setattr(self, name, p)
        return p
示例#6
0
class UIVariable(QWidget, IPropertiesViewSupport):
    def __init__(self, rawVariable, variablesWidget, parent=None):
        super(UIVariable, self).__init__(parent)
        self._rawVariable = rawVariable
        self.variablesWidget = variablesWidget
        # ui
        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setSpacing(1)
        self.horizontalLayout.setContentsMargins(1, 1, 1, 1)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.widget = TypeWidget(
            findPinClassByType(self._rawVariable.dataType).color(), self)
        self.widget.setObjectName("widget")
        self.horizontalLayout.addWidget(self.widget)
        self.labelName = QLabel(self)
        self.labelName.setStyleSheet("background:transparent")
        self.labelName.setObjectName("labelName")
        self.horizontalLayout.addWidget(self.labelName)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        # find refs
        self.pbFindRefs = QPushButton("")
        self.pbFindRefs.setIcon(
            QtGui.QIcon(":/searching-magnifying-glass.png"))
        self.pbFindRefs.setObjectName("pbFindRefs")
        self.horizontalLayout.addWidget(self.pbFindRefs)
        self.pbFindRefs.clicked.connect(self.onFindRefsClicked)
        #  kill variable
        self.pbKill = QPushButton("")
        self.pbKill.setIcon(QtGui.QIcon(":/delete_icon.png"))
        self.pbKill.setObjectName("pbKill")
        self.horizontalLayout.addWidget(self.pbKill)
        self.pbKill.clicked.connect(self.onKillClicked)

        QtCore.QMetaObject.connectSlotsByName(self)
        self.setName(self._rawVariable.name)
        self._rawVariable.setWrapper(self)

    def onStructureChanged(self, name):
        self._rawVariable.structure = PinStructure[name]
        self.variablesWidget.pyFlowInstance.onRequestFillProperties(
            self.createPropertiesWidget)
        EditorHistory().saveState("Change variable struct", modify=True)

    def setDataType(self, dataType):
        self.dataType = dataType
        self._rawVariable.dataType = dataType
        EditorHistory().saveState("Change variable data type", modify=True)

    def createPropertiesWidget(self, propertiesWidget):
        baseCategory = CollapsibleFormWidget(headName="Base", modify=True)
        # name
        le_name = QLineEdit(self._rawVariable.name)
        le_name.returnPressed.connect(lambda: self.setName(le_name.text()))
        baseCategory.addWidget("Name", le_name)

        # data type
        cbTypes = EnumComboBox([
            pin.__name__ for pin in getAllPinClasses() if pin.IsValuePin()
            if pin.__name__ != "AnyPin"
        ])
        cbTypes.setCurrentIndex(cbTypes.findText(self.dataType))
        cbTypes.setEditable(False)
        cbTypes.changeCallback.connect(self.setDataType)
        propertiesWidget.addWidget(baseCategory)

        # structure type
        cbStructure = EnumComboBox(
            [i.name for i in (PinStructure.Single, PinStructure.Array)])
        cbStructure.setEditable(False)
        cbStructure.setCurrentIndex(
            cbStructure.findText(self._rawVariable.structure.name))
        cbStructure.changeCallback.connect(self.onStructureChanged)
        propertiesWidget.addWidget(baseCategory)
        baseCategory.addWidget("Type", cbTypes)
        baseCategory.addWidget("Structure", cbStructure)

        valueCategory = CollapsibleFormWidget(headName="Value")

        # current value
        if self._rawVariable.structure == PinStructure.Single:
            if not type(self._rawVariable.value) in {list, set, dict, tuple}:

                def valSetter(x):
                    self._rawVariable.value = x

                w = createInputWidget(
                    self._rawVariable.dataType, valSetter,
                    getPinDefaultValueByType(self._rawVariable.dataType))
                if w:
                    w.setWidgetValue(self._rawVariable.value)
                    w.setObjectName(self._rawVariable.name)
                    valueCategory.addWidget(self._rawVariable.name, w)

        # access level
        cb = QComboBox()
        cb.addItem('public', 0)
        cb.addItem('private', 1)
        cb.addItem('protected', 2)

        def accessLevelChanged(x):
            self._rawVariable.accessLevel = AccessLevel[x]
            EditorHistory().saveState("Change variable access level",
                                      modify=True)

        cb.currentTextChanged.connect(accessLevelChanged)
        cb.setCurrentIndex(self._rawVariable.accessLevel)
        valueCategory.addWidget('Access level', cb)
        propertiesWidget.addWidget(valueCategory)

    def onFindRefsClicked(self):
        from PyFlow.App import PyFlow
        refs = [n.getWrapper() for n in self._rawVariable.findRefs()]
        app = self.variablesWidget.pyFlowInstance
        if "Search results" not in [
                t.name() for t in app.getRegisteredTools()
        ]:
            app.invokeDockToolByName("PyFlowBase", "Search results")
        self.variablesWidget.pyFlowInstance.getCanvas(
        ).requestShowSearchResults.emit(refs)

    def onKillClicked(self):
        # check refs and ask user what to do
        refs = self._rawVariable.findRefs()
        if len(refs) > 0:
            item, accepted = QInputDialog.getItem(
                None,
                'Decide!',
                'What to do with getters and setters in canvas?',
                ['kill', 'leave'],
                editable=False)
            if accepted:
                self.variablesWidget.killVar(self)
                if item == 'kill':
                    for i in refs:
                        i.kill()
                elif item == 'leave':
                    for i in refs:
                        i.var = None
        else:
            self.variablesWidget.killVar(self)

    @property
    def dataType(self):
        return self._rawVariable.dataType

    @dataType.setter
    def dataType(self, value):
        self._rawVariable.dataType = value
        self.widget.color = findPinClassByType(
            self._rawVariable.dataType).color()
        self.widget.update()
        self.variablesWidget.onUpdatePropertyView(self)

    @property
    def packageName(self):
        return self._rawVariable.packageName

    @property
    def accessLevel(self):
        return self._rawVariable.accessLevel

    @accessLevel.setter
    def accessLevel(self, value):
        self._rawVariable.accessLevel = value

    @property
    def uid(self):
        return self._rawVariable.uid

    @uid.setter
    def uid(self, value):
        self._rawVariable.uid = value
        if self._rawVariable.uid in self.graph.getVars():
            self.graph.getVars().pop(self._rawVariable.uid)
            self.graph.getVars()[self._rawVariable.uid] = self._rawVariable

    @staticmethod
    def jsonTemplate():
        template = {
            'name': None,
            'uuid': None,
            'value': None,
            'type': None,
            'package': None,
            'accessLevel': None
        }
        return template

    def serialize(self):
        pinClass = findPinClassByType(self._rawVariable.dataType)

        template = UIVariable.jsonTemplate()
        template['name'] = self._rawVariable.name
        template['uuid'] = str(self._rawVariable.uid)

        if self._rawVariable.dataType == "AnyPin":
            # don't save any variables
            # value will be calculated for this type of variables
            template['value'] = None
        else:
            template['value'] = json.dumps(self._rawVariable.value,
                                           cls=pinClass.jsonEncoderClass())

        template['type'] = self._rawVariable.dataType
        template['package'] = self._rawVariable.packageName
        template['accessLevel'] = self._rawVariable.accessLevel.value
        return template

    @staticmethod
    def deserialize(data, graph):
        pinClass = findPinClassByType(data['dataType'])

        varUid = uuid.UUID(data['uuid'])
        var = graph.getApp().variablesWidget.createVariable(
            dataType=data['dataType'],
            accessLevel=AccessLevel(data['accessLevel']),
            uid=varUid)
        var.setName(data['name'])
        var.setDataType(data['dataType'])

        if data['dataType'] == 'AnyPin':
            var.value = getPinDefaultValueByType('AnyPin')
        else:
            var.value = json.loads(data['value'],
                                   cls=pinClass.jsonDecoderClass())

        return var

    @property
    def value(self):
        return self._rawVariable.value

    @value.setter
    def value(self, data):
        self._rawVariable.value = data

    def mousePressEvent(self, event):
        super(UIVariable, self).mousePressEvent(event)
        self.variablesWidget.onUpdatePropertyView(self)

    def setName(self, name):
        self._rawVariable.name = name
        self.labelName.setText(self._rawVariable.name)