示例#1
0
class ListItem(Item):

    def __init__(self, scene, x, y, w, data, item_selected_cb=None, parent=None):

        self.w = 100
        self.h = 100
        self.sp = 0

        self.item_selected_cb = item_selected_cb

        super(ListItem, self).__init__(scene, x, y, parent)

        self.w = self.m2pix(w)
        self.h = self.m2pix(0.2)
        self.sp = self.m2pix(0.005)

        self.items = []

        self.middle_item_idx = 0
        self.selected_item_idx = None

        for d in data:

            self.items.append(ButtonItem(self.scene(), 0, 0,
                                         d, self, self.item_clicked_cb, width=w, push_button=True))

        rospack = rospkg.RosPack()
        icons_path = rospack.get_path('art_projected_gui') + '/icons/'

        self.up_btn = ButtonItem(self.scene(), 0, 0, translate(
            "ProgramItem", "Up"), self, self.up_btn_cb, width=w, image_path=icons_path + "arrow-up.svg")
        self.down_btn = ButtonItem(self.scene(), 0, 0, translate(
            "ProgramItem", "Down"), self, self.down_btn_cb, width=w, image_path=icons_path + "arrow-down.svg")

        self.up_btn.setPos(0,  0)
        self.down_btn.setPos(0, self.h - self.down_btn.boundingRect().height())

        self.set_current_idx(min(1, len(self.items) - 1))

        self.update()

    def item_clicked_cb(self, btn):

        if not self.isEnabled():

            return

        if not btn.pressed:

            self.selected_item_idx = None

        else:

            self.selected_item_idx = self.items.index(btn)

            for i in range(0, len(self.items)):

                if i != self.selected_item_idx:

                    self.items[i].set_pressed(False)

            self.set_current_idx(self.selected_item_idx)

        if self.item_selected_cb is not None:

            self.item_selected_cb()

    def get_current_idx(self):

        return self.middle_item_idx

    def set_current_idx(self,  idx, select=False):

        if select:

            self.selected_item_idx = idx

        self.middle_item_idx = max(idx, min(1, len(self.items) - 1))

        if self.isEnabled():

            if self.middle_item_idx == min(1, len(self.items) - 1):
                self.up_btn.set_enabled(False)
            else:
                self.up_btn.set_enabled(True)

            if (idx < len(self.items) - 2):
                self.down_btn.set_enabled(True)
            else:
                self.down_btn.set_enabled(False)

        for it in self.items:

            it.setVisible(False)

            if select:
                it.set_pressed(False)

        # selected item is always vertically centered
        self.items[self.middle_item_idx].setPos(
            0, (self.h - self.items[self.middle_item_idx].boundingRect().height()) / 2)
        self.items[self.middle_item_idx].setVisible(True)

        if select:
            self.items[self.middle_item_idx].set_pressed(True)

        # how much vert. space is used
        vspace = self.items[self.middle_item_idx].boundingRect().height()

        # fill space above selected item
        for idx in range(self.middle_item_idx - 1, -1, -1):

            h = self.items[idx].boundingRect().height()
            y = self.items[idx + 1].y() - self.sp - h

            if y < self.up_btn.y() + self.up_btn.boundingRect().height():
                break

            self.items[idx].setPos(0, y)
            self.items[idx].setVisible(True)
            vspace += self.sp + h

        # fill space below selected item
        for idx in range(self.middle_item_idx + 1, len(self.items)):

            h = self.items[idx].boundingRect().height()
            y = self.items[idx - 1].y() + self.items[idx -
                                                     1].boundingRect().height() + self.sp

            if y + h > self.down_btn.y():
                break

            self.items[idx].setPos(0, y)
            self.items[idx].setVisible(True)
            vspace += self.sp + h

    def up_btn_cb(self, btn):

        if self.middle_item_idx > 0:
            self.set_current_idx(self.middle_item_idx - 1)

    def down_btn_cb(self, btn):

        if self.middle_item_idx < len(self.items) - 1:
            self.set_current_idx(self.middle_item_idx + 1)

    def boundingRect(self):

        return QtCore.QRectF(0, 0, self.w, self.h)

    def paint(self, painter, option, widget):

        pass
示例#2
0
class ListItem(Item):

    def __init__(self, scene, x, y, w, data, item_selected_cb=None, parent=None):

        self.w = 100
        self.h = 100
        self.sp = 0

        self.item_selected_cb = item_selected_cb

        super(ListItem, self).__init__(scene, x, y, parent=parent)

        self.w = self.m2pix(w)
        self.h = self.m2pix(0.2)
        self.sp = self.m2pix(0.005)

        self.items = []

        self.middle_item_idx = 0
        self.selected_item_idx = None

        for d in data:

            self.items.append(ButtonItem(self.scene(), 0, 0,
                                         d, self, self.item_clicked_cb, width=w, push_button=True))

        # TODO down_btn is not properly aligned
        self.up_btn = ButtonItem(self.scene(), 0, 0, "", self, self.up_btn_cb, width=w / 2 - 0.005 / 2,
                                 image_path=icons_path + "arrow-up.svg")
        self.down_btn = ButtonItem(self.scene(), 0, 0, "", self, self.down_btn_cb, width=w / 2 - 0.005 / 2,
                                   image_path=icons_path + "arrow-down.svg")

        self.up_btn.setPos(0, self.h - self.down_btn.boundingRect().height())
        self.down_btn.setPos(self.up_btn.boundingRect().width() + self.sp,
                             self.h - self.down_btn.boundingRect().height())

        self.set_current_idx(min(1, len(self.items) - 1))

        self.update()

    def item_clicked_cb(self, btn):

        if not self.isEnabled():

            return

        if not btn.pressed:

            self.selected_item_idx = None

        else:

            self.selected_item_idx = self.items.index(btn)

            for i in range(0, len(self.items)):

                if i != self.selected_item_idx:

                    self.items[i].set_pressed(False)

            self.set_current_idx(self.selected_item_idx)

        if self.item_selected_cb is not None:

            self.item_selected_cb()

    def get_current_idx(self):

        return self.middle_item_idx

    def set_current_idx(self, idx, select=False):

        if select:

            self.selected_item_idx = idx

        self.middle_item_idx = max(idx, min(1, len(self.items) - 1))

        for it in self.items:

            it.setVisible(False)

            if select:
                it.set_pressed(False)

        displayed = [self.middle_item_idx]

        # selected item is always vertically centered
        self.items[self.middle_item_idx].setPos(
            0, (self.h - self.items[self.middle_item_idx].boundingRect().height()) / 2)
        self.items[self.middle_item_idx].setVisible(True)

        if select:
            self.items[self.selected_item_idx].set_pressed(True)

        # how much vert. space is used
        vspace = self.items[self.middle_item_idx].boundingRect().height()

        # fill space above middle item
        for idx in range(self.middle_item_idx - 1, -1, -1):

            h = self.items[idx].boundingRect().height()
            y = self.items[idx + 1].y() - self.sp - h

            if y < 0:
                break

            self.items[idx].setPos(0, y)
            self.items[idx].setVisible(True)
            displayed.append(idx)
            vspace += self.sp + h
            displayed.append(idx)

        # fill space below middle item
        for idx in range(self.middle_item_idx + 1, len(self.items)):

            h = self.items[idx].boundingRect().height()
            y = self.items[idx - 1].y() + self.items[idx -
                                                     1].boundingRect().height() + self.sp

            if y + h > self.down_btn.y():
                break

            self.items[idx].setPos(0, y)
            self.items[idx].setVisible(True)
            vspace += self.sp + h
            displayed.append(idx)

        if self.isEnabled():

            self.up_btn.set_enabled(min(displayed) > 0)
            self.down_btn.set_enabled(max(displayed) < len(self.items) - 1)

    def up_btn_cb(self, btn):

        if self.middle_item_idx > 0:
            self.set_current_idx(self.middle_item_idx - 1)

    def down_btn_cb(self, btn):

        if self.middle_item_idx < len(self.items) - 1:
            self.set_current_idx(self.middle_item_idx + 1)

    def boundingRect(self):

        return QtCore.QRectF(0, 0, self.w, self.h)

    def paint(self, painter, option, widget):

        pass
示例#3
0
class ProgramItem(Item):

    def __init__(self, scene, rpm, x, y, active_item_switched=None, program_state_changed=None):

        self.states = ['LEARNING', 'RUNNING', 'PAUSED', 'STOPPED']
        self.state = 'LEARNING'

        self.w = 180  # TODO spocitat podle rpm
        self.h = 20

        super(ProgramItem, self).__init__(scene, rpm, x, y)

        self.prog = None
        self.template = None
        self.items = []
        self.active_item = None

        self.active_item_switched = active_item_switched
        self.program_state_changed = program_state_changed
        self.fixed = False

        self.setZValue(100)

    def set_running(self):

        self.state = 'RUNNING'

    def has_prog(self):

        return self.prog is None

    def set_active(self, it=None, inst_id=None):

        if it is None and inst_id is not None:

            it = self.get_item_by_id(inst_id)

        if it is None:
            return

        if self.active_item is not None:
            self.active_item.setPos(30, self.active_item.y())
            self.active_item.active_item = False

        it.active_item = True
        self.active_item = it
        self.active_item.update()

        self.active_item.setPos(10, self.active_item.y())

    def is_prog_learned(self):

        for it in self.items:

            if not it.item_learned():
                return False

        return True

    def get_prog(self):

        # TODO deal with more blocks
        del self.prog.blocks[0].items[:]

        for it in self.items:

            self.prog.blocks[0].items.append(it.item)

        return self.prog

    def set_prog(self, prog, template):

        self.prog = prog
        self.template = template
        self.items = []

        self.active_item = None

        cnt = 0
        max_w = 0

        # TODO Handle program groups - create ProgramGroupItem class and allow switching between groups. For now, let's assume that there will always be just one group
        for pitem in self.prog.blocks[0].items:

            if self.template:

                # to make sure that template is 'clear'
                pitem.object = ""
                del pitem.pick_polygon.polygon.points[:]
                pitem.place_pose.pose.position.x = 0
                pitem.place_pose.pose.position.y = 0
                pitem.place_pose.pose.position.z = 0

            # TODO how to place items easily? using some layout??
            self.items.append(ProgramItemItem(self.scene(), self.rpm, 0, 0, pitem, self, self.item_selected_cb))
            if len(self.items) < 2:
                self.items[-1].setPos(30, 20)
            else:
                self.items[-1].setPos(30, 10 + self.items[-2].y() + self.items[-2].h)

            if self.items[-1].w > max_w:
                max_w = self.items[-1].w
            cnt += 1

            # set first item as active
            if (self.active_item is None) and self.items[-1].item_req_learning():

                self.set_active(self.items[-1])
            # if pitem.type in self.items_req_learning:
            #    if self.active_item is None: self.active_item = pitem

        self.btn = ButtonItem(self.scene(), self.rpm, 0, 0, translate("ProgramItem", "Start"), self, self.btn_clicked)
        self.btn.setPos(10, 5 + cnt * 50)
        self.btn.set_enabled(False)

        # TODO najit max. sirku itemu a tomu prizpusobit sirku programu
        self.h = 20 + cnt * 50 + 30
        self.w = max_w + 40

        self.update()

    def btn_clicked(self):

        if self.state == 'LEARNING':

            self.state = 'RUNNING'
            self.btn.set_caption(translate("ProgramItem", "Pause"))

        elif self.state == 'RUNNING':

            self.state = 'PAUSED'
            self.btn.set_caption(translate("ProgramItem", "Resume"))

        # TODO second button for STOP

        if self.program_state_changed is not None:
            self.program_state_changed(self.state)

    def item_selected_cb(self, it):

        if self.state == 'RUNNING':
            print "program running - ignoring item selection"
            return

        self.set_active(it)
        if self.active_item_switched is not None:
            self.active_item_switched()

    def update_size(self):

        self.active_item.update_size()

        max_w = 0

        for it in self.items:

            if self.active_item.w + 40 > max_w:
                max_w = self.active_item.w + 40
        self.w = max_w

        self.update()

    def program_updated(self):

        # TODO consides state
        if self.is_prog_learned():
            print "enabling start button"
            self.btn.set_enabled(True)

    def set_object(self, obj):

        self.active_item.item.object = obj
        self.program_updated()
        self.update_size()

    def set_place_pose(self, x, y):

        self.active_item.item.place_pose.pose.position.x = x
        self.active_item.item.place_pose.pose.position.y = y
        self.active_item.item.place_pose.pose.orientation.w = 1.0
        self.program_updated()
        self.update_size()

    def set_polygon(self, pts):

        del self.active_item.item.pick_polygon.polygon.points[:]

        for pt in pts:

            self.active_item.item.pick_polygon.polygon.points.append(Point32(pt[0], pt[1], 0))

        self.program_updated()
        self.update_size()

    def boundingRect(self):

        return QtCore.QRectF(0, -30, self.w, self.h + 30)

    def get_item_by_id(self, id):

        for it in self.items:

            if it.item.id == id:

                return it

        return None

    def paint(self, painter, option, widget):

        if self.prog is None:
            return

        painter.setClipRect(option.exposedRect)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        font = QtGui.QFont('Arial', 14)
        painter.setFont(font)
        painter.setPen(QtCore.Qt.white)

        painter.drawText(0, -10, translate("ProgramItem", "Program") + " ID=" + str(self.prog.id))

        pen = QtGui.QPen()
        pen.setStyle(QtCore.Qt.NoPen)
        painter.setPen(pen)

        painter.setBrush(QtCore.Qt.gray)
        painter.setOpacity(0.5)
        # TODO projit itemy a zjistit skutecnou velikost (muze byt ruzna)
        painter.drawRect(0, 0, self.w, self.h)