Пример #1
0
    def updateSceneRect(self, factor: float) -> QRectF:
        """Updates the associated scene's bounding rectangle.

    To make it possible to pan the view, the scene's bounding rectangle must
    be larger than the viewport. Scaling the view means that the scene in its
    entirety is scaled, including the scene's bounding rectangle, so it must
    be scaled along with the view.

    Currently, the view can be panned such that the editing grid can be
    freely moved around, but within the bounds of the viewport regardless of
    its size or zoom level, similar to Aseprite.

    Args:
      factor: The scaling factor the scene should be sized with respect to.

    Returns the updated scene bounding rectangle.
    """

        # TODO: make configurable via Property
        margin = QSize(10, 10)  # Between edge of grid and viewport
        editAreaRect = self.editor().editArea.rect()
        editAreaSize = editAreaRect.size().toSize()

        # Make the scene 2x larger than the viewport, minus the editing grid. This
        # allows us to pan the grid up to the edges of the viewport (minus margin),
        # but no further. Also ensure the scene is at least big enough to encompass
        # the entire grid.
        sceneSize = self.maximumViewportSize() * 2 * (1 / factor)
        sceneSize = sceneSize - editAreaSize - margin
        sceneSize = sceneSize.expandedTo(editAreaSize + margin)
        newSceneRect = QRectF(QPointF(0, 0), sceneSize)
        newSceneRect.moveCenter(editAreaRect.center())
        self.setSceneRect(newSceneRect)

        return newSceneRect
Пример #2
0
    def _make_ellipse_path(self):
        """Returns an ellipse path for the link's base.

        Returns:
            QPainterPath
        """
        ellipse_path = QPainterPath()
        rect = QRectF(0, 0, 1.6 * self.magic_number, 1.6 * self.magic_number)
        rect.moveCenter(self.src_center)
        ellipse_path.addEllipse(rect)
        return ellipse_path
Пример #3
0
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(painter.Antialiasing)

        #painter.setBrush(QBrush(Qt.black, Qt.NoBrush))
        #painter.drawRect(self.winBox)  # border

        # value selector indicator
        painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
        painter.drawPie(self.vIdBox, 16 * (degrees(self.vIdAng) - 22.5), 720)

        # value selector arc
        painter.setClipPath(self.vArcPath)
        painter.setPen(Qt.NoPen)
        arc = QConicalGradient(self.cen, self.e_ang)
        color = QColor()
        color.setHsv(self.hue, self.sat, 255)
        arc.setColorAt(1 - (self.e_ang - self.s_ang) / 360.0, color)
        arc.setColorAt(1, Qt.black)
        arc.setColorAt(0, Qt.black)
        painter.setBrush(arc)
        painter.drawPath(self.vArcPath)
        painter.setClipPath(self.vArcPath, Qt.NoClip)

        # color wheel
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.cWhlBrush1)
        painter.drawEllipse(self.cWhBox)
        painter.setBrush(self.cWhlBrush2)
        painter.drawEllipse(self.cWhBox)

        # crosshairs
        painter.setClipPath(self.colWhlPath)
        painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
        chVert = QRectF(0, 0, 2, 20)
        chHort = QRectF(0, 0, 20, 2)
        chVert.moveCenter(self.chPt)
        chHort.moveCenter(self.chPt)
        painter.drawRect(chVert)
        painter.drawRect(chHort)

        # named color locations
        if self._showNames:
            painter.setClipPath(self.vArcPath, Qt.NoClip)
            painter.setPen(Qt.SolidLine)
            try:
                painter.drawPoints(*self._namedColorPts)  # PyQt
            except:
                painter.drawPoints(self._namedColorPts)  # PySide
Пример #4
0
    def __init__(self, parent, toolbox, position="left"):
        """Connector button graphics item. Used for Link drawing between project items.

        Args:
            parent (QGraphicsItem): Project item bg rectangle
            toolbox (ToolBoxUI): QMainWindow instance
            position (str): Either "top", "left", "bottom", or "right"
        """
        super().__init__(parent)
        self._parent = parent
        self._toolbox = toolbox
        self.position = position
        self.links = list()
        pen = QPen(Qt.black, 0.5, Qt.SolidLine)
        self.setPen(pen)
        self.setBrush(self.brush)
        parent_rect = parent.rect()
        extent = 0.2 * parent_rect.width()
        rect = QRectF(0, 0, extent, extent)
        if position == "top":
            rect.moveCenter(
                QPointF(parent_rect.center().x(),
                        parent_rect.top() + extent / 2))
        elif position == "left":
            rect.moveCenter(
                QPointF(parent_rect.left() + extent / 2,
                        parent_rect.center().y()))
        elif position == "bottom":
            rect.moveCenter(
                QPointF(parent_rect.center().x(),
                        parent_rect.bottom() - extent / 2))
        elif position == "right":
            rect.moveCenter(
                QPointF(parent_rect.right() - extent / 2,
                        parent_rect.center().y()))
        self.setRect(rect)
        self.setAcceptHoverEvents(True)
        self.setCursor(Qt.PointingHandCursor)
Пример #5
0
    def paint(self, painter, option, widget=None):
        if Design.flow_theme == 'dark std':
            color = QColor(
                '#2E688C'
            ) if self.parent_port_instance.type_ == 'data' else QColor(
                '#3880ad')
            if option.state & QStyle.State_MouseOver:
                color = color.lighter()

            brush = QBrush(QColor(color))
            painter.setBrush(brush)
            painter.setPen(Qt.NoPen)

            painter.drawEllipse(
                QRectF(self.padding, self.padding, self.painting_width,
                       self.painting_height))

        elif Design.flow_theme == 'dark tron':
            color = ''
            if self.parent_port_instance.type_ == 'exec':
                color = '#FFFFFF'
            elif self.parent_port_instance.type_ == 'data':
                color = self.parent_node_instance.parent_node.color
            pen = QPen(color)
            pen.setWidth(2)
            painter.setPen(pen)
            if len(self.parent_port_instance.connected_port_instances) > 0 or \
                    option.state & QStyle.State_MouseOver:  # also fill when mouse hovers
                c = self.parent_node_instance.parent_node.color
                r = c.red()
                g = c.green()
                b = c.blue()
                brush = QBrush(QColor(r, g, b, 100))
                painter.setBrush(brush)
            else:
                painter.setBrush(Qt.NoBrush)

            painter.drawEllipse(
                QRectF(self.padding, self.padding, self.painting_width,
                       self.painting_height))

        elif Design.flow_theme == 'ghostly' or Design.flow_theme == 'blender':
            color = ''
            if self.parent_port_instance.type_ == 'exec':
                color = '#FFFFFF'

                if len(self.parent_port_instance.connected_port_instances) > 0 or \
                        option.state & QStyle.State_MouseOver:  # also fill when mouse hovers
                    brush = QBrush(QColor(255, 255, 255, 100))
                    painter.setBrush(brush)
                else:
                    painter.setBrush(Qt.NoBrush)
            elif self.parent_port_instance.type_ == 'data':
                color = self.parent_node_instance.parent_node.color

                if len(self.parent_port_instance.connected_port_instances) > 0 or \
                        option.state & QStyle.State_MouseOver:  # also fill when mouse hovers
                    c = self.parent_node_instance.parent_node.color
                    r = c.red()
                    g = c.green()
                    b = c.blue()
                    brush = QBrush(QColor(r, g, b, 100))
                    painter.setBrush(brush)
                else:
                    painter.setBrush(Qt.NoBrush)

            pen = QPen(color)
            pen.setWidth(1)
            painter.setPen(pen)

            rect = QRectF()
            rect.moveCenter(QPointF(self.width / 2, self.height / 2))
            rect.setWidth(self.painting_width)
            rect.setHeight(self.painting_height)
            painter.drawEllipse(QPointF(self.width / 2, self.height / 2),
                                self.painting_width / 3,
                                self.painting_height / 3)
Пример #6
0
class wheel(QWidget):
    currentColorChanged = Signal(QColor)

    def __init__(self, parent=None):
        super(wheel, self).__init__(parent)
        self.setFixedSize(256, 256)

        # start, end angles for value arc
        self.s_ang, self.e_ang = 135, 225

        # offset angle and direction for color wheel
        self.o_ang, self.rot_d = 45, -1  # 1 for clock-wise, -1 for widdershins

        # other initializations
        self.pos = QPointF(-100, -100)
        self.vIdCen = QPointF(-100, -100)
        self.vIdAng = radians(self.s_ang)
        self.chPt = self.pos
        self.hue = self.sat = self.value = 255

        self.setup()
        self.pos = self.cWhBox.center()

        self._namedColorList = []
        self._namedColorPts = []
        self._showNames = False

        self.setMouseTracking(True)
        self.installEventFilter(self)

        self._startedTimer = False


##    def timerSpinner(self):
##        "won't this be fun"
##        self.o_ang -= 1; self.o_ang %= 360
##        stable = False
##
##        colWhl = QConicalGradient(self.cen, self.o_ang)
##        whl_cols = [Qt.red, Qt.magenta,
##                    Qt.blue, Qt.cyan, Qt.green,
##                    Qt.yellow, Qt.red]
##        for i, c in enumerate(whl_cols[::self.rot_d]):
##            colWhl.setColorAt(i / 6.0, c)
##
##        if stable:  # crosshairs stay on color
##            t = radians(self.hue + self.o_ang * -self.rot_d) * -self.rot_d
##            r = self.sat / 255.0 * self.cW_rad
##            x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y()
##            self.chPt = QPointF(x, y)
##        else:  # crosshairs stay on point
##            t = atan2(self.cen.y() - self.pos.y(), self.pos.x() - self.cen.x())
##            h = (int(degrees(t)) - self.o_ang) * -self.rot_d
##            self.hue = (h if h > 0 else h + 360) % 360
##            col = QColor(); col.setHsv(self.hue, self.sat, self.value)
##            self.currentColorChanged.emit(col)
##
##        self.cWhlBrush1 = QBrush(colWhl)
##        self.update()

    def resizeEvent(self, event):
        self.setup()  # re-construct the sizes
        self.setNamedColors(self._namedColorList)

    def getColor(self):
        col = QColor()
        col.setHsv(self.hue, self.sat, self.value)
        return col

    def setNamedColors(self, colorList):
        "sets list [(name, #html)] of named colors"
        self._namedColorList = colorList
        lst = []
        r2 = (self.vAoBox.width() + self.vAiBox.width()) / 4.0
        for i in self._namedColorList:
            h, s, v, a = QColor(i[1]).getHsv()

            t = radians(h + self.o_ang * -self.rot_d) * -self.rot_d
            r = s / 255.0 * self.cW_rad
            x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y()
            lst.append(QPointF(x, y))

            #t2 = ((v / 255.0) * self.ang_w + radians(self.e_ang) + 2 * pi) % (2 * pi)
            #x, y = r2 * cos(t2) + self.cen.x(), r2 * -sin(t2) + self.cen.y()
            #lst.append(QPointF(x, y))
        self._namedColorPts = lst

    def showNamedColors(self, flag=False):
        "show/hide location of named colors on color wheel"
        self._showNames = flag
        self.update()

    def setColor(self, color):  # saturation -> radius
        h, s, v, a = color.getHsv()  # hue -> angle
        self.hue, self.sat, self.value = h, s, v  # value -> side bar thingy

        t = radians(h + self.o_ang * -self.rot_d) * -self.rot_d
        r = s / 255.0 * self.cW_rad
        x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y()
        self.chPt = QPointF(x, y)  # hue, saturation

        self.vIdAng = t2 = (v / 255.0) * self.ang_w + radians(self.e_ang)
        self.vIdAng = t2 = t2 if t2 > 0 else t2 + 2 * pi
        r2 = self.vAoBox.width() / 2.0

        x, y = r2 * cos(t2) + self.cen.x(), r2 * -sin(t2) + self.cen.y()
        self.vIdCen, self.vIdAng = QPointF(x, y), t2  # value
        self.vIdBox.moveCenter(self.vIdCen)
        self.update()

    def eventFilter(self, source, event):
        if (event.type() == QEvent.MouseButtonPress
                or (event.type() == QEvent.MouseMove
                    and event.buttons() == Qt.LeftButton)):
            self.pos = pos = event.pos()

            t = atan2(self.cen.y() - pos.y(), pos.x() - self.cen.x())
            if self.colWhlPath.contains(pos):  # in the color wheel
                self.chPt = pos

                #if not self._startedTimer:
                #    self.timer = QTimer()
                #    self.timer.timeout.connect(self.timerSpinner)
                #    self.timer.start(30.303)
                #    self._startedTimer = True

                # hue -> mouse angle (same as t here)
                h = (int(degrees(t)) - self.o_ang) * -self.rot_d
                self.hue = (h if h > 0 else h + 360) % 360

                # saturation -> mouse radius (clipped to wheel radius)
                m_rad = sqrt((self.pos.x() - self.cen.x())**2 +
                             (self.pos.y() - self.cen.y())**2)
                self.sat = int(255 * min(m_rad / self.cW_rad, 1))

            if self.vInArcPath.contains(pos):  # in the value selection arc
                self.vIdAng = t if t > 0 else t + 2 * pi
                r2 = self.vAoBox.width() / 2.0

                x, y = r2 * cos(t) + self.cen.x(), r2 * -sin(t) + self.cen.y()
                self.vIdCen = QPointF(x, y)
                self.vIdBox.moveCenter(self.vIdCen)
                self.value = int(255 *
                                 (t - radians(self.e_ang)) / self.ang_w) % 256

            self.update()
            col = QColor()
            col.setHsv(self.hue, self.sat, self.value)
            self.currentColorChanged.emit(col)
        return QWidget.eventFilter(self, source, event)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(painter.Antialiasing)

        #painter.setBrush(QBrush(Qt.black, Qt.NoBrush))
        #painter.drawRect(self.winBox)  # border

        # value selector indicator
        painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
        painter.drawPie(self.vIdBox, 16 * (degrees(self.vIdAng) - 22.5), 720)

        # value selector arc
        painter.setClipPath(self.vArcPath)
        painter.setPen(Qt.NoPen)
        arc = QConicalGradient(self.cen, self.e_ang)
        color = QColor()
        color.setHsv(self.hue, self.sat, 255)
        arc.setColorAt(1 - (self.e_ang - self.s_ang) / 360.0, color)
        arc.setColorAt(1, Qt.black)
        arc.setColorAt(0, Qt.black)
        painter.setBrush(arc)
        painter.drawPath(self.vArcPath)
        painter.setClipPath(self.vArcPath, Qt.NoClip)

        # color wheel
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.cWhlBrush1)
        painter.drawEllipse(self.cWhBox)
        painter.setBrush(self.cWhlBrush2)
        painter.drawEllipse(self.cWhBox)

        # crosshairs
        painter.setClipPath(self.colWhlPath)
        painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
        chVert = QRectF(0, 0, 2, 20)
        chHort = QRectF(0, 0, 20, 2)
        chVert.moveCenter(self.chPt)
        chHort.moveCenter(self.chPt)
        painter.drawRect(chVert)
        painter.drawRect(chHort)

        # named color locations
        if self._showNames:
            painter.setClipPath(self.vArcPath, Qt.NoClip)
            painter.setPen(Qt.SolidLine)
            try:
                painter.drawPoints(*self._namedColorPts)  # PyQt
            except:
                painter.drawPoints(self._namedColorPts)  # PySide

    def setup(self):
        "sets bounds on value arc and color wheel"
        # bounding boxes
        self.winBox = QRectF(self.rect())
        self.vIoBox = QRectF()  # value indicator arc outer
        self.vIdBox = QRectF()  # value indicator box
        self.vAoBox = QRectF()  # value arc outer
        self.vAiBox = QRectF()  # value arc inner
        self.cWhBox = QRectF()  # color wheel

        self.vIdBox.setSize(QSizeF(15, 15))
        self.vIoBox.setSize(self.winBox.size())
        self.vAoBox.setSize(self.winBox.size() - self.vIdBox.size() / 2.0)
        self.vAiBox.setSize(self.vAoBox.size() - QSizeF(20, 20))
        self.cWhBox.setSize(self.vAiBox.size() - QSizeF(20, 20))

        # center - shifted to the right slightly
        x = self.winBox.width() - (self.vIdBox.width() +
                                   self.vAiBox.width()) / 2.0
        self.cen = QPointF(x, self.winBox.height() / 2.0)

        # positions and initial settings
        self.vAoBox.moveCenter(self.cen)
        self.vAiBox.moveCenter(self.cen)
        self.cWhBox.moveCenter(self.cen)
        self.vIdBox.moveCenter(self.vIdCen)

        self.cW_rad = self.cWhBox.width() / 2.0
        self.ang_w = radians(self.s_ang) - radians(self.e_ang)

        # gradients
        colWhl = QConicalGradient(self.cen, self.o_ang)
        whl_cols = [
            Qt.red, Qt.magenta, Qt.blue, Qt.cyan, Qt.green, Qt.yellow, Qt.red
        ]
        for i, c in enumerate(whl_cols[::self.rot_d]):
            colWhl.setColorAt(i / 6.0, c)

        rad = min(self.cWhBox.width() / 2.0, self.cWhBox.height() / 2.0)
        cWhlFade = QRadialGradient(self.cen, rad, self.cen)
        cWhlFade.setColorAt(0, Qt.white)
        cWhlFade.setColorAt(1, QColor(255, 255, 255, 0))

        self.cWhlBrush1 = QBrush(colWhl)
        self.cWhlBrush2 = QBrush(cWhlFade)

        # painter paths (arcs, wheel)
        rad = self.vAoBox.width() / 2.0
        x, y = rad * cos(radians(self.s_ang)), -rad * sin(radians(self.s_ang))
        x += self.cen.x()
        y += self.cen.y()

        self.vArcPath = QPainterPath(QPointF(x, y))  # value arc (for color)
        self.vArcPath.arcTo(self.vAoBox, self.s_ang, self.e_ang - self.s_ang)
        self.vArcPath.arcTo(self.vAiBox, self.e_ang, self.s_ang - self.e_ang)
        self.vArcPath.closeSubpath()

        self.vInArcPath = QPainterPath(QPointF(x, y))  # value arc (for mouse)
        self.vInArcPath.arcTo(self.vIoBox, self.s_ang, self.e_ang - self.s_ang)
        self.vInArcPath.arcTo(self.vAiBox, self.e_ang, self.s_ang - self.e_ang)
        self.vInArcPath.closeSubpath()

        self.colWhlPath = QPainterPath()
        self.colWhlPath.addEllipse(self.cWhBox)
Пример #7
0
    def draw(self, painter: QPainter, block_length: int):
        self.pixel_length = block_length / Block.WIDTH

        self.scroll_brush = QBrush(Qt.blue)
        self.scroll_pen = QPen(self.scroll_brush, 2 * self.pixel_length)

        self.acceleration_brush = QBrush(Qt.red)
        self.acceleration_pen = QPen(self.acceleration_brush,
                                     2 * self.pixel_length)

        painter.setPen(self.scroll_pen)
        painter.setBrush(self.scroll_brush)

        auto_scroll_type_index = self.auto_scroll_row >> 4
        auto_scroll_routine_index = self.auto_scroll_row & 0b0001_1111

        if auto_scroll_type_index in [
                SPIKE_CEILING_SCROLL,
                UP_TIL_DOOR_SCROLL,
                WATER_LEVEL_SCROLL,
                UP_RIGHT_DIAG_SCROLL,
        ]:
            # not visualized
            return
        elif auto_scroll_type_index not in [
                HORIZONTAL_SCROLL_0, HORIZONTAL_SCROLL_1
        ]:
            # illegal value, those appear in the vanilla ROM, though; so error out
            return

        first_movement_command_index = (self.rom.int(
            AScroll_HorizontalInitMove + auto_scroll_routine_index) + 1) % 256
        last_movement_command_index = (self.rom.int(
            AScroll_HorizontalInitMove + auto_scroll_routine_index + 1)) % 256

        self.horizontal_speed = 0
        self.vertical_speed = 0

        self.current_pos = self._determine_auto_scroll_start(block_length)

        for movement_command_index in range(first_movement_command_index,
                                            last_movement_command_index + 1):

            movement_command = self.rom.int(AScroll_Movement +
                                            movement_command_index)
            movement_repeat = self.rom.int(AScroll_MovementRepeat +
                                           movement_command_index)

            self._execute_movement_command(painter, movement_command,
                                           movement_repeat)

        stop_marker = QRectF(QPoint(0, 0), QSizeF(10, 10) * self.pixel_length)
        stop_marker.moveCenter(self.current_pos)

        painter.setPen(Qt.NoPen)
        painter.drawRect(stop_marker)

        painter.setPen(self.scroll_pen)
        painter.setBrush(self.scroll_brush)

        painter.setOpacity(0.2)
        painter.drawPolygon(self.screen_polygon)