Beispiel #1
0
 def contains(self, p: QPoint):
     cx = self.pos.x() + self.size / 2.0
     cy = self.pos.y() + self.size / 2.0
     dx = p.x() - cx
     dy = p.y() - cy
     if math.sqrt(dx * dx + dy * dy) <= self.size + 1:
         return True
     return False
Beispiel #2
0
    def paintEvent(self, ev):
        offset = QPoint(0, 0)
        p = QPainter(self)
        p.setClipRect(ev.rect())
        bottom = self.rect().bottom()

        if self.results:
            for i, (prefix, full, text) in enumerate(self.results):
                size = prefix.size()
                if offset.y() + size.height() > bottom:
                    break
                self.max_result = i
                offset.setX(0)
                if i in (self.current_result, self.mouse_hover_result):
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
                offset.setY(offset.y() + self.MARGIN // 2)
                p.drawStaticText(offset, prefix)
                offset.setX(self.maxwidth + 5)
                p.drawStaticText(offset, self.divider)
                offset.setX(offset.x() + self.divider.size().width())
                p.drawStaticText(offset, full)
                offset.setY(offset.y() + size.height() + self.MARGIN // 2)
                if i in (self.current_result, self.mouse_hover_result):
                    offset.setX(0)
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
        else:
            p.drawText(self.rect(), Qt.AlignCenter, _('No results found'))

        p.end()
Beispiel #3
0
    def paintEvent(self, ev):
        offset = QPoint(0, 0)
        p = QPainter(self)
        p.setClipRect(ev.rect())
        bottom = self.rect().bottom()

        if self.results:
            for i, (prefix, full, text) in enumerate(self.results):
                size = prefix.size()
                if offset.y() + size.height() > bottom:
                    break
                self.max_result = i
                offset.setX(0)
                if i in (self.current_result, self.mouse_hover_result):
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
                offset.setY(offset.y() + self.MARGIN // 2)
                p.drawStaticText(offset, prefix)
                offset.setX(self.maxwidth + 5)
                p.drawStaticText(offset, self.divider)
                offset.setX(offset.x() + self.divider.size().width())
                p.drawStaticText(offset, full)
                offset.setY(offset.y() + size.height() + self.MARGIN // 2)
                if i in (self.current_result, self.mouse_hover_result):
                    offset.setX(0)
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
        else:
            p.drawText(self.rect(), Qt.AlignCenter, _('No results found'))

        p.end()
Beispiel #4
0
class Block(QWidget):
    border_color = QColor(137, 117, 89)
    border_pen = QPen(border_color, 2)
    selected_pen = QPen(border_color.lighter().lighter(), 2)
    padding = 5

    def __init__(self, type_name: str, name: str, parent: QWidget=None):
        QWidget.__init__(self, parent)
        self.settings = {"Name": Setting("Name", StringValue(name), parent=self)}
        self.outputs = {}
        self.inputs = {}
        self.__type_name = type_name
        self._bg_color = QColor(159, 160, 144, 255)
        self._fg_color = QColor(255, 255, 255)
        self._resizable = True
        self.setMinimumSize(90, 120)
        self.__origin = QPoint(0, 0)
        self.__action = Action.NONE
        self.__status = Mode.EDIT_LOGIC
        self.__selected = False
        self.__line = None
        self.__label = None
        self.setMouseTracking(True)
        if self._resizable:
            self.__init_corner()

    def remove_connections(self):
        for k in self.inputs:
            self.inputs[k].delete()
        for k in self.outputs:
            self.outputs[k].delete()

    def delete(self):
        self.remove_connections()

    def name(self):
        return self.settings["Name"].data()

    def type_name(self):
        return self.__type_name

    def mode(self):
        return self.__status

    def action(self):
        return self.__action

    def setVisible(self, val):
        QWidget.setVisible(self, val)
        self.update_nodes()

    def set_mode(self, mode):
        self.__status = mode
        if (mode == Mode.EDIT_LOGIC or mode == Mode.DEBUG) and not self.isVisible():
            self.setVisible(True)
        elif (mode == Mode.RUN or mode == Mode.EDIT_GUI) and self.isVisible():
            self.setVisible(False)

    def __init_corner(self):
        path = QPainterPath()
        path.moveTo(-Block.padding, -15 - Block.padding)
        path.lineTo(-15 - Block.padding, -Block.padding)
        path.lineTo(-Block.padding, -Block.padding)
        path.closeSubpath()
        self.__corner_path = path

    def _add_input(self, name: str, t: Type):
        if not name in self.inputs:
            x = 1
            y = 40 + Block.padding + len(self.inputs) * 13
            self.inputs[name] = Input(t, QPoint(x, y), self)

    def _add_output(self, name: str, t: Type):
        if not name in self.outputs:
            x = self.width() - 10
            y = 40 + Block.padding + len(self.outputs) * 13
            self.outputs[name] = Output(t, QPoint(x, y), self)

    def _add_setting(self, name, value, constant=False):
        self.settings[name] = Setting(name, value, constant, self)

    def bg(self):
        return self._bg_color

    def title_bg(self):
        return self._bg_color.light(80)

    def selected(self):
        return self.__selected

    def set_selected(self, selected):
        self.__selected = selected

    def deselect(self):
        if self.__selected:
            self.set_selected(False)
            eff = self.graphicsEffect()
            del eff
            self.setGraphicsEffect(None)

    def select(self):
        if not self.__selected:
            self.set_selected(True)
            effect = QGraphicsDropShadowEffect()
            effect.setBlurRadius(20)
            effect.setXOffset(0)
            effect.setYOffset(0)
            effect.setColor(QColor(0, 0, 0, 180))
            self.setGraphicsEffect(effect)
            self.raise_()

    def pen(self):
        return Block.selected_pen if self.__selected else Block.border_pen

    def _paint(self, p: QPainter):
        self._paint_bg(p)
        self._paint_title(p)
        p.setPen(QPen(self.pen().brush(), 1))
        self._paint_ins(p)
        self._paint_outs(p)
        self._paint_content(p)

    def _paint_bg(self, p: QPainter):
        pen = Block.selected_pen if self.__selected else Block.border_pen
        p.setRenderHint(QPainter.Antialiasing, True)
        p.setPen(pen)
        p.setBrush(self.bg())
        p.drawRoundedRect(Block.padding, Block.padding, self.width() - 2 * Block.padding,
                          self.height() - 2 * Block.padding, 8, 8)
        p.setBrush(self.title_bg())
        p.drawRoundedRect(Block.padding, Block.padding, self.width() - 2 * Block.padding, 35 + Block.padding, 8, 8)
        p.setBrush(self.bg())
        p.setPen(QColor(0, 0, 0, 0))
        p.drawRect(1 + Block.padding, 35 + Block.padding, self.width() - 2 - 2 * Block.padding, 10)
        p.setPen(pen)
        if self._resizable:
            p.setBrush(pen.brush())
            p.drawPath(self.__corner_path.translated(self.width(), self.height()))

    def _paint_title(self, p: QPainter):
        p.drawLine(Block.padding, 35 + Block.padding, self.width() - Block.padding, 35 + Block.padding)
        p.setPen(self._fg_color)
        f = p.font()
        f.setPointSize(10)
        f.setBold(True)
        p.setFont(f)
        p.drawText(QRectF(4 + Block.padding, Block.padding + 2, self.width() - 12, 25),
                   str(self.settings["Name"].value()))
        f.setBold(False)
        f.setPointSize(8)
        p.setPen(QColor(self._fg_color.red(), self._fg_color.green(), self._fg_color.blue(), 100))
        p.setFont(f)
        p.drawText(QRectF(4 + Block.padding, 18 + Block.padding, self.width() - 12, 15), str(self.__type_name))

    def _paint_ins(self, p: QPainter):
        for i in self.inputs:
            self.inputs[i].paint(p)

    def _paint_outs(self, p: QPainter):
        for i in self.outputs:
            self.outputs[i].paint(p)

    def _paint_content(self, p: QPainter):
        # nothing to do
        return

    def paintEvent(self, e: QPaintEvent):
        if e.isAccepted():
            p = QPainter(self)
            self._paint(p)

    def _check_action(self, action):
        if self.__action != Action.NONE and action != Action.NONE:
            return False
        return True

    def node(self, p):
        for k in self.inputs:
            i = self.inputs[k]
            if i.contains(p):
                return i
        for k in self.outputs:
            o = self.outputs[k]
            if o.contains(p):
                return o
        return None

    def node_name(self, n):
        for k in self.inputs:
            i = self.inputs[k]
            if n == i:
                return k
        for k in self.outputs:
            o = self.outputs[k]
            if o == n:
                return k
        return ''

    def __create_line(self, n):
        l = n.get_line()
        self.parent().add_line(l)
        return l

    def mousePressEvent(self, e: QMouseEvent):
        self.parent().select(self)
        n = self.node(e.pos())

        if n is not None:
            self.__line = self.__create_line(n)
            self.__action = Action.CONNECTING
            if self.__label is not None and self.__label.node() is not n:
                self.parent().delete_label(self.__label)
                self.__label = None
            return

        if self.__label is not None:
            self.parent().delete_label(self.__label)
            self.__label = None

        if self._resizable:
            if abs(e.x() - self.width()) < 8 + Block.padding \
                    and abs(e.y() - self.height()) < 8 + Block.padding \
                    and self._check_action(Action.RESIZE):
                self.__origin = e.pos()
                self.__action = Action.RESIZE
                return
        if self._check_action(Action.DRAG):
            self.__origin = e.pos()
            self.__action = Action.DRAG

    def mouseMoveEvent(self, e: QMouseEvent):
        if self.__action == Action.DRAG:
            dx = e.x() - self.__origin.x()
            dy = e.y() - self.__origin.y()
            self.set_pos(self.x() + dx, self.y() + dy)
        elif self.__action == Action.RESIZE:
            self.set_size(e.x(), e.y())
        elif self.__action == Action.CONNECTING and self.__line is not None:
            p = QPoint(e.x() + self.x(), e.y() + self.y())

            n = self.parent().get_node(p)
            if n is not None and n.compatible(self.__line.n1):
                self.__line.status(True)
            else:
                self.__line.status(False)

            self.__line.update(p)

        else:
            n = self.node(e.pos())
            if self.__label is None and n is not None:
                self.__label = self.parent().create_label(self.node_name(n), n)
            elif self.__label is not None and self.__label.node() is not n and n is not None:
                self.parent().delete_label(self.__label)
                self.__label = self.parent().create_label(self.node_name(n), n)
            elif n is None:
                self.parent().delete_label(self.__label)
                self.__label = None

    def mouseReleaseEvent(self, e: QMouseEvent):
        if self.__action == Action.CONNECTING and self.__line is not None:
            self.parent().check_line(self.__line)
            self.__line = None
        self.__action = Action.NONE
        if self.__label is not None:
            self.parent().delete_label(self.__label)
            self.__label = None

    def leaveEvent(self, e):
        QWidget.leaveEvent(self, e)
        if self.__label is not None:
            self.parent().delete_label(self.__label)
            self.__label = None

    def mouseDoubleClickEvent(self, e: QMouseEvent):
        self._double_click()

    def _double_click(self):
        # to be defined in the sub blocks
        return

    def set_pos(self, x: int, y: int):
        xx = x if x >= 0 else 0
        yy = y if y >= 0 else 0
        if xx + self.width() > self.parent().width():
            xx = self.parent().width() - self.width()
        if yy + self.height() > self.parent().height():
            yy = self.parent().height() - self.height()
        self.setGeometry(xx, yy, self.width(), self.height())

    def set_size(self, w: int, h: int):
        if self._resizable:
            width = w if w >= self.minimumWidth() else self.minimumWidth()
            height = h if h >= self.minimumHeight() else self.minimumHeight()
            self.setGeometry(self.x(), self.y(), width, height)

    def setGeometry(self, *__args):
        QWidget.setGeometry(self, *__args)
        self.update_nodes()

    def update_nodes(self):
        x = self.width() - 5 - Block.padding
        for k in self.outputs:
            o = self.outputs[k]
            o.pos.setX(x)
            o.set_visible(self.isVisible())
            o.update()
        for k in self.inputs:
            i = self.inputs[k]
            i.set_visible(self.isVisible())
            i.update()

    def _corner_path(self):
        return self.__corner_path
Beispiel #5
0
class PaintBoard(QWidget):

    # Define virtual panel coordinates for different shapes/regions
    VPCoord_Start = [316, 332]  #LeftTopX, Y
    VPCoord_Circle = [316, 332, 336, 363]  #LeftTopX, Y, RightBotX, Y
    VPCoord_Rect = [336, 332, 356, 363]  #LeftTopX, Y, RightBotX, Y
    VPCoord_Tri = [316, 363, 336, 395]  #LeftTopX, Y, RightBotX, Y
    VPCoord_Line = [336, 363, 356, 395]  #LeftTopX, Y, RightBotX, Y

    # A flag to check if the user is currently using the virtual panel
    usingVP = False

    def __init__(self, sizeX, sizeY, Parent=None):
        '''
        Constructor
        '''
        super(PaintBoard, self).__init__(Parent)

        self.__InitData(sizeX,
                        sizeY)  #Initialize Data first, then interface/view
        self.__InitView()
        print("Init PaintBoard")

    def __InitView(self):

        self.setFixedSize(self.__size)

    def __InitData(self, sizeX, sizeY):
        self.__size = QSize(sizeX, sizeY)

        self.__board = QPixmap(
            self.__size)  # Make a new QPixmap as paint board,350px * 250px
        self.__board.fill(Qt.white)  #Fill the paint board with white

        self.__IsEmpty = True  #board is empty by default
        self.EraserMode = False  #eraser mode is disabled by default

        self.__lastPos = None
        self.__currentPos = QPoint(0, 0)

        self.__painter = QPainter()

        self.__thickness = 1  #default pen thickness is 1
        self.__penColor = QColor("black")  #default color is black
        self.__colorList = QColor.colorNames()  #get the list of colors

    def Clear(self):
        #Clear the board
        self.__board.fill(Qt.white)
        self.update()
        self.__IsEmpty = True

    def ChangePenColor(self, color="black"):
        self.__penColor = QColor(color)

    def ChangePenThickness(self, thickness=1):
        self.__thickness = thickness

    def IsEmpty(self):
        #Is the board empty
        return self.__IsEmpty

    def GetContentAsQImage(self):
        #return the content of the board (return QImage)
        image = self.__board.toImage()
        return image

    def paintEvent(self, paintEvent):

        self.__painter.begin(self)
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

        # print("inside paintEvent")

    def penPressEvent(self, pos):

        self.__currentPos = QPoint(pos[0], pos[1])
        self.__lastPos = self.__currentPos

    def penMoveEvent(self, pos, pressure):
        pen_x = pos[0]
        pen_y = pos[1]
        pen_pressure = pressure

        if self.__lastPos is None:
            self.__lastPos = QPoint(pen_x, pen_y)
        elif (abs(pen_x - self.__lastPos.x()) > 21
              or abs(pen_y - self.__lastPos.y()) > 21):
            self.__lastPos = QPoint(pen_x, pen_y)

        self.__currentPos = QPoint(pen_x, pen_y)
        self.__painter.begin(self.__board)

        if self.EraserMode == False:
            #Non-Eraser mode
            self.__painter.setPen(QPen(
                self.__penColor, self.__thickness))  #Set pen color, thickness
        else:
            #Eraser mode: pen color is white, thickness is 6
            self.__painter.setPen(QPen(Qt.white, 6))

        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos

        self.update()  #Show updates

    # Virtual Panel event
    def penVPEvent(self, pos, pressure):
        pass

    '''    
        # Check if the pressure is over 500
        if(pen_pressure > 400):
            # Check which region the pen is in and prepare to draw shape accordingly
            if(pen_x < self.VPCoord_Circle[2] and pen_y < self.VPCoord_Circle[3]):
                print("A")        
            elif(pen_x < self.VPCoord_Rect[2] and pen_y < self.VPCoord_Rect[3]):
                print("B")
            elif(pen_x < self.VPCoord_Tri[2] and pen_y < self.VPCoord_Tri[3]):
                print("C")
            elif(pen_x < self.VPCoord_Line[2] and pen_y < self.VPCoord_Line[3]):
                print("D")
    '''

    def penReleaseEvent(self, pos):
        self.__IsEmpty = False  #board is not empty

    def paintEllipse(self, center_x, center_y, radias1, radias2):
        self.__painter.begin(self.__board)

        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawEllipse(QPoint(center_x, center_y), radias1,
                                   radias2)

        self.__painter.end()

        self.update()  #Show updates

    def paintRect(self, center_x, center_y, upper_left_x, upper_left_y):
        width = abs(2 * (center_x - upper_left_x))
        height = abs(2 * (center_y - upper_left_y))

        self.__painter.begin(self.__board)

        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawRect(upper_left_x, upper_left_y, width, height)

        self.__painter.end()

        self.update()  #Show updates

    def paintTriangle(self, points):
        self.__painter.begin(self.__board)

        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawPolygon(points)

        self.__painter.end()

        self.update()  #Show updates

    def paintLine(self, P1_x, P1_y, P2_x, P2_y):
        P1 = QPoint(P1_x, P1_y)
        P2 = QPoint(P2_x, P2_y)

        self.__painter.begin(self.__board)
        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawLine(P1, P2)
        self.__painter.end()

        self.update()  #Show updates

    def paintArc(self, center_x, center_y, start_x, start_y, end_x, end_y):
        radius = math.sqrt(
            math.pow(center_x - start_x, 2) + math.pow(center_y - start_y, 2))
        rect = QRectF(center_x - radius, center_y - radius, radius * 2,
                      radius * 2)
        startAngle = 16 * math.atan2(start_x - center_y,
                                     start_x - center_x) * 180.0 / math.pi
        endAngle = 16 * math.atan2(end_y - center_y,
                                   end_x - center_x) * 180.0 / math.pi
        spanAngle = endAngle - startAngle

        self.__painter.begin(self.__board)
        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawArc(rect, startAngle, spanAngle)
        self.__painter.end()

        self.update()  #Show updates

    def paintBezierSpline(self, pointListX, pointListY):
        P1 = QPoint(int(pointListX[0]), int(pointListY[0]))
        path = QtGui.QPainterPath()
        path.moveTo(P1)

        self.__painter.begin(self.__board)
        self.__painter.setPen(QPen(self.__penColor, self.__thickness))

        i = 0
        while i < len(pointListX) - 3:
            P2 = QPoint(int(pointListX[i + 1]), int(pointListY[i + 1]))
            P3 = QPoint(int(pointListX[i + 2]), int(pointListY[i + 2]))
            P4 = QPoint(int(pointListX[i + 3]), int(pointListY[i + 3]))
            path.cubicTo(P2, P3, P4)
            self.__painter.drawPath(path)
            i += 3

        self.__painter.end()

        self.update()  #Show updates