class FrameEditor_StyleWidget(Interface):
    def __init__(self, frame_editor):
        self.editor = frame_editor
        self.editor.observers.append(self)

        self.old_frame = None

        self.layout = QtWidgets.QGridLayout()
        self.widget = QWidget()
        self.widget.setLayout(self.layout)

        self.mesh_label = QtWidgets.QLineEdit("File:")
        self.mesh_label.setSizePolicy(QtWidgets.QSizePolicy.Ignored,
                                      QtWidgets.QSizePolicy.Fixed)
        self.mesh_button = QtWidgets.QPushButton("Open")
        self.mesh_button.clicked.connect(self.btn_open_mesh_clicked)

        self.diameter_label = QtWidgets.QLabel("Diameter:")
        self.diameter_spinbox = QtWidgets.QDoubleSpinBox()
        self.diameter_spinbox.editingFinished.connect(self.diameter_changed)

        self.length_label = QtWidgets.QLabel("Length:")
        self.length_spinbox = QtWidgets.QDoubleSpinBox()
        self.length_spinbox.editingFinished.connect(self.length_changed)

        self.width_label = QtWidgets.QLabel("Width:")
        self.width_spinbox = QtWidgets.QDoubleSpinBox()
        self.width_spinbox.editingFinished.connect(self.width_changed)

        self.height_label = QtWidgets.QLabel("Height:")
        self.height_spinbox = QtWidgets.QDoubleSpinBox()
        self.height_spinbox.editingFinished.connect(self.height_changed)

        self.color_label = QtWidgets.QLabel()
        self.color_label.setAutoFillBackground(True)
        self.update_color_label(None)
        self.color_button = QtWidgets.QPushButton("Set Color")
        self.color_button.clicked.connect(self.btn_color_clicked)

        self.layout.addWidget(self.mesh_label, 0, 0)
        self.layout.addWidget(self.mesh_button, 0, 1)
        self.layout.addWidget(self.diameter_label, 1, 0)
        self.layout.addWidget(self.diameter_spinbox, 1, 1)
        self.layout.addWidget(self.length_label, 2, 0)
        self.layout.addWidget(self.length_spinbox, 2, 1)
        self.layout.addWidget(self.width_label, 3, 0)
        self.layout.addWidget(self.width_spinbox, 3, 1)
        self.layout.addWidget(self.height_label, 4, 0)
        self.layout.addWidget(self.height_spinbox, 4, 1)
        self.layout.addWidget(self.color_label, 5, 0)
        self.layout.addWidget(self.color_button, 5, 1)

        self.update_widget(None)

    def get_widget(self):
        return self.widget

    def update(self, editor, level, elements):

        if level & 2:
            ## Check for change
            if self.editor.active_frame is not self.old_frame:
                self.update_widget(self.editor.active_frame)
                self.update_values(self.editor.active_frame)
            self.update_color_label(self.editor.active_frame)

        elif level & 4:
            if self.editor.active_frame is not None:
                self.update_values(self.editor.active_frame)
            self.update_color_label(self.editor.active_frame)

    def update_widget(self, frame):

        ## Clear layout
        #while self.layout.count():
        #    child = self.layout.takeAt(0)
        #    child.widget().deleteLater()

        self.mesh_label.hide()
        self.mesh_button.hide()
        self.diameter_label.hide()
        self.diameter_spinbox.hide()
        self.length_label.hide()
        self.length_spinbox.hide()
        self.width_label.hide()
        self.width_spinbox.hide()
        self.height_label.hide()
        self.height_spinbox.hide()

        if frame is None or frame.style == "none":
            self.widget.setEnabled(False)
            return

        if frame.style == "mesh":
            self.mesh_label.show()
            self.mesh_button.show()
        elif frame.style == "sphere":
            self.diameter_label.show()
            self.diameter_spinbox.show()
        else:
            self.length_label.show()
            self.length_spinbox.show()
            self.width_label.show()
            self.width_spinbox.show()
            if frame.style == "cube":
                self.height_label.show()
                self.height_spinbox.show()

        self.widget.setEnabled(True)

    def update_values(self, frame):
        if frame is None or frame.style == "none":
            return

        if frame.style == "mesh":
            self.mesh_label.setText(frame.path)
        elif frame.style == "sphere":
            self.diameter_spinbox.setValue(frame.diameter)
        else:
            self.length_spinbox.setValue(frame.length)
            self.width_spinbox.setValue(frame.width)
            if frame.style == "cube":
                self.height_spinbox.setValue(frame.height)

    def update_color_label(self, frame):
        if frame is None:
            values = "{}, {}, {}, {}".format(200, 200, 200, 255)
        else:
            values = "{}, {}, {}, {}".format(frame.color[0] * 255,
                                             frame.color[1] * 255,
                                             frame.color[2] * 255,
                                             frame.color[3] * 255)
        self.color_label.setStyleSheet("QLabel { background-color: rgba(" +
                                       values + "); }")

    @Slot(float)
    def diameter_changed(self):
        if self.editor.active_frame.diameter != self.diameter_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "diameter", self.diameter_spinbox.value()))

    @Slot(float)
    def length_changed(self):
        if self.editor.active_frame.length != self.length_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "length", self.length_spinbox.value()))

    @Slot(float)
    def width_changed(self):
        if self.editor.active_frame.width != self.width_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "width", self.width_spinbox.value()))

    @Slot(float)
    def height_changed(self):
        if self.editor.active_frame.height != self.height_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "height", self.height_spinbox.value()))

    @Slot()
    def btn_open_mesh_clicked(self):
        path = QtWidgets.QFileDialog.getOpenFileName(
            None, 'Open Mesh', '/home', 'Mesh Files (*.stl *.dae)')[0]
        self.editor.command(
            Command_SetGeometry(self.editor, self.editor.active_frame, "path",
                                path))

    @Slot(bool)
    def btn_color_clicked(self, checked):
        frame = self.editor.active_frame
        color = QtWidgets.QColorDialog.getColor(
            QtWidgets.QColor(frame.color[0] * 255, frame.color[1] * 255,
                             frame.color[2] * 255, frame.color[3] * 255),
            None,
            "Select Color",
            options=QtWidgets.QColorDialog.ShowAlphaChannel)
        self.editor.command(
            Command_SetStyleColor(self.editor, frame, color.getRgbF()))
Exemple #2
0
class FrameEditor_StyleWidget(Interface):
    def __init__(self, frame_editor):
        self.editor = frame_editor
        self.editor.observers.append(self)

        self.old_frame = None

        self.layout = QtWidgets.QGridLayout()
        self.widget = QWidget()
        self.widget.setLayout(self.layout)

        self.mesh_label = QtWidgets.QLineEdit("File:")
        self.mesh_label.setSizePolicy(QtWidgets.QSizePolicy.Ignored,
                                      QtWidgets.QSizePolicy.Fixed)
        self.mesh_button = QtWidgets.QPushButton("Open")
        self.mesh_button.clicked.connect(lambda: self.btn_open_mesh_clicked())

        self.diameter_label = QtWidgets.QLabel("Diameter:")
        self.diameter_spinbox = QtWidgets.QDoubleSpinBox()
        self.diameter_spinbox.editingFinished.connect(
            lambda: self.diameter_changed())

        self.length_label = QtWidgets.QLabel("Length:")
        self.length_spinbox = QtWidgets.QDoubleSpinBox()
        self.length_spinbox.editingFinished.connect(
            lambda: self.length_changed())

        self.width_label = QtWidgets.QLabel("Width:")
        self.width_spinbox = QtWidgets.QDoubleSpinBox()
        self.width_spinbox.editingFinished.connect(
            lambda: self.width_changed())

        self.height_label = QtWidgets.QLabel("Height:")
        self.height_spinbox = QtWidgets.QDoubleSpinBox()
        self.height_spinbox.editingFinished.connect(
            lambda: self.height_changed())

        self.color_label = QtWidgets.QLabel()
        self.color_label.setAutoFillBackground(True)
        self.update_color_label(None)
        self.color_button = QtWidgets.QPushButton("Set Color")
        self.color_button.clicked.connect(lambda: self.btn_color_clicked())

        self.layout.addWidget(self.mesh_label, 0, 0)
        self.layout.addWidget(self.mesh_button, 0, 1)
        self.layout.addWidget(self.diameter_label, 1, 0)
        self.layout.addWidget(self.diameter_spinbox, 1, 1)
        self.layout.addWidget(self.length_label, 2, 0)
        self.layout.addWidget(self.length_spinbox, 2, 1)
        self.layout.addWidget(self.width_label, 3, 0)
        self.layout.addWidget(self.width_spinbox, 3, 1)
        self.layout.addWidget(self.height_label, 4, 0)
        self.layout.addWidget(self.height_spinbox, 4, 1)
        self.layout.addWidget(self.color_label, 5, 0)
        self.layout.addWidget(self.color_button, 5, 1)

        print("init")
        self.update_widget(None)

    def get_widget(self):
        return self.widget

    def update(self, editor, level, elements):

        if level & 2:
            ## Check for change
            if self.editor.active_frame is not self.old_frame:
                self.update_widget(self.editor.active_frame)
                self.update_values(self.editor.active_frame)
            self.update_color_label(self.editor.active_frame)

        elif level & 4:
            if self.editor.active_frame is not None:
                self.update_values(self.editor.active_frame)
            self.update_color_label(self.editor.active_frame)

    def update_widget(self, frame):
        ## Clear layout
        #while self.layout.count():
        #    child = self.layout.takeAt(0)
        #    child.widget().deleteLater()

        self.mesh_label.hide()
        self.mesh_button.hide()
        self.diameter_label.hide()
        self.diameter_spinbox.hide()
        self.length_label.hide()
        self.length_spinbox.hide()
        self.width_label.hide()
        self.width_spinbox.hide()
        self.height_label.hide()
        self.height_spinbox.hide()

        if frame is None or frame.style == "none":
            self.widget.setEnabled(False)
            return

        if frame.style == "mesh":
            self.mesh_label.show()
            self.mesh_button.show()
        elif frame.style == "sphere":
            self.diameter_label.show()
            self.diameter_spinbox.show()
        else:
            self.length_label.show()
            self.length_spinbox.show()
            self.width_label.show()
            self.width_spinbox.show()
            if frame.style == "cube":
                self.height_label.show()
                self.height_spinbox.show()

        self.widget.setEnabled(True)

    def update_values(self, frame):
        if frame is None or frame.style == "none":
            return

        if frame.style == "mesh":
            self.mesh_label.setText(frame.path)
        elif frame.style == "sphere":
            self.diameter_spinbox.setValue(frame.diameter)
        else:
            self.length_spinbox.setValue(frame.length)
            self.width_spinbox.setValue(frame.width)
            if frame.style == "cube":
                self.height_spinbox.setValue(frame.height)

    def update_color_label(self, frame):
        if frame is None:
            values = "{}, {}, {}, {}".format(200, 200, 200, 255)
        else:
            values = "{}, {}, {}, {}".format(frame.color[0] * 255,
                                             frame.color[1] * 255,
                                             frame.color[2] * 255,
                                             frame.color[3] * 255)
        self.color_label.setStyleSheet("QLabel { background-color: rgba(" +
                                       values + "); }")

    @Slot(float)
    def diameter_changed(self):
        if self.editor.active_frame.diameter != self.diameter_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "diameter", self.diameter_spinbox.value()))

    @Slot(float)
    def length_changed(self):
        if self.editor.active_frame.length != self.length_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "length", self.length_spinbox.value()))

    @Slot(float)
    def width_changed(self):
        if self.editor.active_frame.width != self.width_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "width", self.width_spinbox.value()))

    @Slot(float)
    def height_changed(self):
        if self.editor.active_frame.height != self.height_spinbox.value():
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "height", self.height_spinbox.value()))

    @Slot(bool)
    def btn_open_mesh_clicked(self):
        path = QtWidgets.QFileDialog.getOpenFileName(None, 'Open Mesh',
                                                     '/home',
                                                     'Mesh Files (*.stl)')[0]
        try:
            rospackage = rospkg.get_package_name(path)
            if rospackage is None:
                QtWidgets.QMessageBox.warning(
                    self.widget, "Saving absolute path to mesh",
                    "Cannot find rospackage with selected mesh in it!\nSaving absolute path to mesh instead!"
                )
                #print("WARNING cannot find rospackage with mesh in it, saving absolute path")
                self.editor.command(
                    Command_SetGeometry(self.editor, self.editor.active_frame,
                                        "package", ""))
                self.editor.command(
                    Command_SetGeometry(self.editor, self.editor.active_frame,
                                        "path", path))
            else:
                rel_path = os.path.relpath(
                    path,
                    rospkg.RosPack().get_path(rospackage))
                print("Saving: package: {} + relative path: {}".format(
                    rospackage, rel_path))
                self.editor.command(
                    Command_SetGeometry(self.editor, self.editor.active_frame,
                                        "package", rospackage))
                self.editor.command(
                    Command_SetGeometry(self.editor, self.editor.active_frame,
                                        "path", rel_path))
        except:
            QtWidgets.QMessageBox.warning(
                self.widget, "Saving absolute path to mesh",
                "The found rospackage with selected mesh in it is not sourced in your ROS workspace!\n"
                +
                "Cannot resolve the packagepath\nSaving absolute path to mesh instead!"
            )
            #print("The package found is not sourced withing the current workspace, saving absolute path instead!")
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "package", ""))
            self.editor.command(
                Command_SetGeometry(self.editor, self.editor.active_frame,
                                    "path", path))

    @Slot(bool)
    def btn_color_clicked(self):
        frame = self.editor.active_frame
        color = QtWidgets.QColorDialog.getColor(
            QColor(frame.color[0] * 255, frame.color[1] * 255,
                   frame.color[2] * 255, frame.color[3] * 255),
            None,
            "Select Color",
            options=QtWidgets.QColorDialog.ShowAlphaChannel)
        self.editor.command(
            Command_SetStyleColor(self.editor, frame, color.getRgbF()))
Exemple #3
0
class Packml(Plugin):

    def __init__(self, context):
        super(Packml, self).__init__(context)
        self.setObjectName('Packml')

        from argparse import ArgumentParser
        parser = ArgumentParser()

        parser.add_argument("-q", "--quiet", action="store_true",
                      dest="quiet",
                      help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print 'arguments: ', args
            print 'unknowns: ', unknowns

        # Create QWidget
        self._widget = QWidget()
        ui_file = os.path.join(rospkg.RosPack().get_path('packml_gui'), 'resource', 'packml.ui')
        loadUi(ui_file, self._widget)
        self._widget.setObjectName('Packml')

        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))

        context.add_widget(self._widget)

        # Custom code begins here
        self._widget.reset_button.clicked[bool].connect(self.__handle_reset_clicked)
        self._widget.start_button.clicked[bool].connect(self.__handle_start_clicked)
        self._widget.stop_button.clicked[bool].connect(self.__handle_stop_clicked)
        self._widget.clear_button.clicked[bool].connect(self.__handle_clear_clicked)
        self._widget.hold_button.clicked[bool].connect(self.__handle_hold_clicked)
        self._widget.unhold_button.clicked[bool].connect(self.__handle_unhold_clicked)
        self._widget.suspend_button.clicked[bool].connect(self.__handle_suspend_clicked)
        self._widget.unsuspend_button.clicked[bool].connect(self.__handle_unsuspend_clicked)
        self._widget.abort_button.clicked[bool].connect(self.__handle_abort_clicked)

        self._service_thread = Thread(target=self.wait_for_services, args=())
        self._service_thread.start()

        self._status_sub = rospy.Subscriber('packml/status', Status, self.status_callback)

        self.threadpool = QThreadPool()

    def disable_all_buttons(self):
        self._widget.clear_button.setEnabled(False)
        self._widget.reset_button.setEnabled(False)
        self._widget.start_button.setEnabled(False)
        self._widget.stop_button.setEnabled(False)
        self._widget.hold_button.setEnabled(False)
        self._widget.suspend_button.setEnabled(False)
        self._widget.unhold_button.setEnabled(False)
        self._widget.unsuspend_button.setEnabled(False)
        self._widget.abort_button.setEnabled(False)

    def set_message_text(self, text):
        self._widget.message_box.setText("Message: " + text)

    def status_callback(self, msg):
        self.update_button_states(msg.state.val)
        self.update_status_fields(msg)


    def update_button_states(self, state):
        self.disable_all_buttons()
        if state == State.ABORTED:
            self._widget.clear_button.setEnabled(True)
        elif state == State.STOPPED:
            self._widget.reset_button.setEnabled(True)
        elif state == State.IDLE:
            self._widget.start_button.setEnabled(True)
        elif state == State.EXECUTE:
            self._widget.hold_button.setEnabled(True)
            self._widget.suspend_button.setEnabled(True)
        elif state == State.HELD:
            self._widget.unhold_button.setEnabled(True)
        elif state == State.SUSPENDED:
            self._widget.unsuspend_button.setEnabled(True)
        elif state == State.COMPLETE:
            self._widget.reset_button.setEnabled(True)

        if state != State.STOPPED and \
        state != State.STOPPING and \
        state != State.ABORTED and \
        state != State.ABORTING and \
        state != State.CLEARING:
            self._widget.stop_button.setEnabled(True)


        if state != State.ABORTED and \
        state != State.ABORTING:
            self._widget.abort_button.setEnabled(True)

    def update_status_fields(self, msg):
        self.update_state_field(msg.state.val)
        self._widget.substate.setText(str(msg.sub_state))
        self.update_mode_field(msg.mode.val)
        self._widget.error_code.setText(str(msg.error))
        self._widget.suberror_code.setText(str(msg.sub_error))


    def update_state_field(self, state):
        if state == State.UNDEFINED:
            self._widget.state_name.setText("UNDEFINED")
        elif state == State.OFF:
            self._widget.state_name.setText("OFF")
        elif state == State.STOPPED:
            self._widget.state_name.setText("STOPPED")
        elif state == State.STARTING:
            self._widget.state_name.setText("STARTING")
        elif state == State.IDLE:
            self._widget.state_name.setText("IDLE")
        elif state == State.SUSPENDED:
            self._widget.state_name.setText("SUSPENDED")
        elif state == State.EXECUTE:
            self._widget.state_name.setText("EXECUTE")
        elif state == State.STOPPING:
            self._widget.state_name.setText("STOPPING")
        elif state == State.ABORTING:
            self._widget.state_name.setText("ABORTING")
        elif state == State.ABORTED:
            self._widget.state_name.setText("ABORTED")
        elif state == State.HOLDING:
            self._widget.state_name.setText("HOLDING")
        elif state == State.HELD:
            self._widget.state_name.setText("HELD")
        elif state == State.RESETTING:
            self._widget.state_name.setText("RESETTING")
        elif state == State.SUSPENDING:
            self._widget.state_name.setText("SUSPENDING")
        elif state == State.UNSUSPENDING:
            self._widget.state_name.setText("UNSUSPENDING")
        elif state == State.CLEARING:
            self._widget.state_name.setText("CLEARING")
        elif state == State.UNHOLDING:
            self._widget.state_name.setText("UNHOLDING")
        elif state == State.COMPLETING:
            self._widget.state_name.setText("COMPLETING")
        elif state == State.COMPLETE:
            self._widget.state_name.setText("COMPLETE")
        else:
            self._widget.state_name.setTest("UNKNOWN")



    def update_mode_field(self, mode):
        if mode == Mode.UNDEFINED:
            self._widget.mode_name.setText("UNDEFINED")
        elif mode == Mode.AUTOMATIC:
            self._widget.mode_name.setText("AUTOMATIC")
        elif mode == Mode.SEMI_AUTOMATIC:
            self._widget.mode_name.setText("SEMI-AUTOMATIC")
        elif mode == Mode.MANUAL:
            self._widget.mode_name.setText("MANUAL")
        elif mode == Mode.IDLE:
            self._widget.mode_name.setText("IDLE")
        elif mode == Mode.SETUP:
            self._widget.mode_name.setText("SETUP")
        else:
            self._widget.mode_name.setText("UNKNOWN")



    def wait_for_services(self):
        self._widget.setEnabled(False)
        transition_service_name = 'packml/transition'
        rospy.wait_for_service(transition_service_name, 30)
        self.transition_service = rospy.ServiceProxy(transition_service_name, Transition)
        self._widget.setEnabled(True)

    def shutdown_plugin(self):
        self._status_sub.unregister()
        pass

    def save_settings(self, plugin_settings, instance_settings):
        # TODO save intrinsic configuration, usually using:
        # instance_settings.set_value(k, v)
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # TODO restore intrinsic configuration, usually using:
        # v = instance_settings.value(k)
        pass


    def handle_click_thread(self, request):
        try:
            service_thread = WorkerThread(self.transition_service, request, self.set_message_text)
            if self.threadpool.activeThreadCount() >= 1:
                return
            else:
                self.threadpool.start(service_thread)
        except rospy.ServiceException as exc:
            rospy.logerror("Service did not process request: " + str(exc))

    def __handle_start_clicked(self, checked):
        rospy.loginfo("Start button press")
        self.handle_click_thread(TransitionRequest.START)

    def __handle_stop_clicked(self, checked):
        rospy.loginfo("Stop button press")
        self.handle_click_thread(TransitionRequest.STOP)

    def __handle_reset_clicked(self, checked):
        rospy.loginfo("Reset button press")
        self.handle_click_thread(TransitionRequest.RESET)

    def __handle_clear_clicked(self, checked):
        rospy.loginfo("Clear button press")
        self.handle_click_thread(TransitionRequest.CLEAR)

    def __handle_hold_clicked(self, checked):
        rospy.loginfo("Hold button press")
        self.handle_click_thread(TransitionRequest.HOLD)

    def __handle_unhold_clicked(self, checked):
        rospy.loginfo("Unhold button press")
        self.handle_click_thread(TransitionRequest.UNHOLD)

    def __handle_suspend_clicked(self, checked):
        rospy.loginfo("Suspend button press")
        self.handle_click_thread(TransitionRequest.SUSPEND)

    def __handle_unsuspend_clicked(self, checked):
        rospy.loginfo("Unsuspend button press")
        self.handle_click_thread(TransitionRequest.UNSUSPEND)

    def __handle_abort_clicked(self, checked):
        rospy.loginfo("Abort button press")
        self.handle_click_thread(TransitionRequest.ABORT)

    @staticmethod
    def add_arguments(parser):
        rospy.loginfo("Add arguments callback")
        group = parser.add_argument_group('Options for PackML plugin')
        group.add_argument('--arg1', action='store_true', help='arg1 help')