aboutsummaryrefslogtreecommitdiff
path: root/scripts/artv2/tools/rigging/rig_builder/add_component_widget.py
blob: 96005f11acfb746b6e0441d148347aa753d1c8d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# -*- coding: utf-8 -*-

"""
:author:
    Jeremy Ernst
:description:
    This module contains a class that displays a user interface for adding/creating a component and supplying an
    optional prefix, suffix, as well as a required parent. If the component class has sides, then an option for
    choosing a side will be present.
"""

import os
from functools import partial
from artv2.third_party.Qt import QtWidgets, QtCore, QtGui
import artv2.utilities.interface_utilities as interface_utils
import artv2.utilities.component_utilities as component_utils
import artv2.tools.rigging.rig_builder.parent_list_widget as parent_list
import artv2.utilities.error_utilities as error_utils


class AddComponentWidget(interface_utils.ARTv2Window):
    """
    This class displays a user interface for adding/creating a component and supplying information needed for the
    constructor of the component, like the prefix and suffix. A widget for obtaining the parent joint is also
    provided, as is a widget for choosing a side if the component has sides. It is instantiated from the
    AvailableComponentsWidget class.

    :param component_data: list of information for the component. [component category, module to import,
                           component class]
    :param parent_inst: the AvailableComponentsWidget instance this class was instantiated from.
    :param parent: the parent widget of this class, which will be a RigBuilderUI instance.


    .. figure:: /images/available_components_widget.png
        :width: 197px
        :align: center
        :height: 334px
        :figclass: align-center

        The area in red is the AvailableComponentsWidget class. If you click on an item in this widget, it will then
        launch the AddComponentWidget, seen below.

    .. figure:: /images/add_component_widget.png
        :width: 254px
        :align: center
        :height: 207px
        :figclass: align-center

        Once an item is clicked in the AvailableComponentsWidget, the AddComponentWidget will be displayed.

    """

    SETTINGS_NAME = "AddComponentWIN"
    WINDOW_NAME = "artv2_add_component_window"

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    def __init__(self, component_data, parent_inst, parent=None):

        super(AddComponentWidget, self).__init__(220, 180, "Add Component", parent)

        self.component_data = component_data
        self.parent_inst = parent_inst
        self._build_interface()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    def _build_interface(self):

        main_widget = QtWidgets.QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QtWidgets.QVBoxLayout(main_widget)

        prefix_layout = QtWidgets.QHBoxLayout()
        main_layout.addLayout(prefix_layout)
        prefix_label = QtWidgets.QLabel("Prefix:")
        prefix_label.setMinimumWidth(interface_utils.scale_by_dpi(40))
        prefix_label.setMaximumWidth(interface_utils.scale_by_dpi(40))
        self.prefix_field = QtWidgets.QLineEdit()
        prefix_layout.addWidget(prefix_label)
        prefix_layout.addWidget(self.prefix_field)

        suffix_layout = QtWidgets.QHBoxLayout()
        main_layout.addLayout(suffix_layout)
        suffix_label = QtWidgets.QLabel("Suffix:")
        suffix_label.setMinimumWidth(interface_utils.scale_by_dpi(40))
        suffix_label.setMaximumWidth(interface_utils.scale_by_dpi(40))
        self.suffix_field = QtWidgets.QLineEdit()
        suffix_layout.addWidget(suffix_label)
        suffix_layout.addWidget(self.suffix_field)

        parent_layout = QtWidgets.QHBoxLayout()
        main_layout.addLayout(parent_layout)
        parent_label = QtWidgets.QLabel("Parent:")
        parent_label.setMinimumWidth(interface_utils.scale_by_dpi(40))
        parent_label.setMaximumWidth(interface_utils.scale_by_dpi(40))
        parent_layout.addWidget(parent_label)

        self.parent_field = QtWidgets.QLineEdit()
        parent_button = QtWidgets.QPushButton()
        parent_button.setMinimumWidth(interface_utils.scale_by_dpi(25))
        parent_button.setMaximumWidth(interface_utils.scale_by_dpi(25))
        parent_button.setMinimumHeight(interface_utils.scale_by_dpi(25))
        parent_button.setMaximumHeight(interface_utils.scale_by_dpi(25))
        icon = QtGui.QIcon(os.path.join(self.icon_path, "general/search.png"))
        parent_button.setIconSize(QtCore.QSize(21, 21))
        parent_button.setIcon(icon)

        parent_layout.addWidget(self.parent_field)
        parent_layout.addWidget(parent_button)

        completer = QtWidgets.QCompleter(component_utils.get_all_created_joints())
        completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.parent_field.setCompleter(completer)

        parent_button.clicked.connect(self._launch_parent_list)
        side_layout = QtWidgets.QHBoxLayout()
        main_layout.addLayout(side_layout)

        if getattr(self.component_data[2], "has_sides"):
            side_label = QtWidgets.QLabel("Side:")
            side_label.setMinimumWidth(interface_utils.scale_by_dpi(40))
            side_label.setMaximumWidth(interface_utils.scale_by_dpi(40))
            left_side = QtWidgets.QRadioButton("Left")
            left_side.setChecked(True)
            right_side = QtWidgets.QRadioButton("Right")
            side_layout.addWidget(side_label)
            side_layout.addWidget(left_side)
            side_layout.addWidget(right_side)

        else:
            spacer = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
            main_layout.addSpacerItem(spacer)

        button_layout = QtWidgets.QHBoxLayout()
        main_layout.addLayout(button_layout)
        cancel_button = QtWidgets.QPushButton("Cancel")
        cancel_button.clicked.connect(self.close)
        add_button = QtWidgets.QPushButton("Add Component")
        add_button.clicked.connect(partial(self._add_component, side_layout))
        button_layout.addWidget(cancel_button)
        button_layout.addWidget(add_button)

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    def _launch_parent_list(self):

        widget = parent_list.ChooseParentList(self)
        pos = QtGui.QCursor.pos()
        widget.move(pos.x() + 10, pos.y() + 10)
        widget.exec_()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    def _add_component(self, radio_layout):

        side = None

        if self.parent_field.text() in component_utils.get_all_created_joints():
            if getattr(self.component_data[2], "has_sides"):
                for i in range(radio_layout.count()):
                    if isinstance(radio_layout.itemAt(i).widget(), QtWidgets.QRadioButton):
                        if radio_layout.itemAt(i).widget().isChecked():
                            side = radio_layout.itemAt(i).widget().text().lower()

            inst = self.component_data[2](prefix=self.prefix_field.text(), suffix=self.suffix_field.text())
            if inst.network_node:
                if "_unique_name" in inst.__dict__.keys():
                    if side == "right":
                        inst.set_side(side)
                    inst.parent = self.parent_field.text()
                    inst.joint_mover.aim_helper.toggle_aim_mode()
                    self.close()
                    self.parent_inst.component_added.emit()
        else:
            error_utils.raise_error("No such parent joint exists.")