Пример #1
0
class ColorGraphicsScene(QGraphicsScene):
    """
    The widget that is responsible for displaying the color gradient to the user
    """

    def __init__(self, parent=None):
        super(ColorGraphicsScene, self).__init__(parent)
        # setup default attrs
        self.CROSSHAIR_RADIUS = 10
        self._rgba_crosshair_pos = QPoint(0, 0)
        self._linear_crosshair_pos = QPoint(0, 0)
        self._linear_crosshair_size = 15

        # create scene
        self.setSceneRect(0, 0, 500, 500)
        self.gradient_type = attrs.RGBA
        self.drawRGBACrosshair()
        self.drawLinearCrosshair()
        self._drawRGBAForegroundItem()

    """ DRAW GRADIENTS """
    def drawGradient(self):
        """
        Draws the gradient that will be displayed to the user
        """

        _gradient = draw.drawColorTypeGradient(self.gradient_type, self.width(), self.height())
        direction = self.linearCrosshairDirection()
        self.rgba_foreground.hide()

        # show gradient for RGBA gradient
        if self.gradient_type == attrs.RGBA:
            """
            for some reason the darker it gets the harder of a time the picker has
            and the steps become larger and larger =/
            """
            # get value
            main_widget = getWidgetAncestor(self.views()[0], ColorGradientDelegate)
            value = main_widget.color().valueF()
            self.rgba_foreground.updateSize(QRectF(0, 0, self.width(), self.height()))
            self.rgba_foreground.updateGradient(value, self.width(), self.height())

            self.rgba_foreground.show()

        # update linear gradient
        else:
            if direction == Qt.Horizontal:
                _gradient.setFinalStop(QPoint(self.width(), 0))
            elif direction == Qt.Vertical:
                # TODO Move this to draw utils (gradient inversion)
                _gradient.setStart(QPoint(0, self.height()))
                _gradient.setFinalStop(QPoint(0, 0))

        self.setBackgroundBrush(QBrush(_gradient))

    """ PROPERTIES """
    @property
    def gradient_type(self):
        return self._gradient_type

    @gradient_type.setter
    def gradient_type(self, gradient_type):
        self._gradient_type = gradient_type

    """ CROSSHAIR"""
    def drawLinearCrosshair(self):
        """
        Creates the initial linear crosshair.  Note that this is hard coded to setup
        to be drawn horizontally.  You can update the direction with
        setLinearCrosshairDirection(Qt.Direction) on the
        ColorInputWidget.
        """
        self.linear_crosshair_item = ColorPickerItem1D()
        self.linear_crosshair_item.setWidth(self.width())
        self.linear_crosshair_item.setHeight(self.height())
        self.linear_crosshair_item.setDirection(Qt.Horizontal)

        # add group item
        self.addItem(self.linear_crosshair_item)

        # hide by default
        self.linear_crosshair_item.hide()

    def setLinearCrosshairDirection(self, direction):
        """
        Sets the direction of travel of the linear crosshair.  This will also update
        the display of the crosshair

        Args:
            direction (Qt.Vertical | Qt. Horizontal): what direction this gradient will be
                displayed as.
        """
        # set direction
        self._linear_crosshair_direction = direction
        self.linear_crosshair_item.setDirection(direction)

    def linearCrosshairDirection(self):
        return self._linear_crosshair_direction

    """ RGBA """
    def drawRGBACrosshair(self):
        """
        rgba_topline_item
        rgba_botline_item
        rgba_leftline_item
        rgba_rightline_item:
        rgba_crosshair_item_circle: center portion of crosshair

        """
        # vertical line
        self.rgba_topline_item = DualColoredLineSegment()
        self.rgba_topline_item.setLine(0, 0, 0, self.height())
        self.rgba_botline_item = DualColoredLineSegment()
        self.rgba_botline_item.setLine(0, 0, 0, self.height())

        # horizontal line
        self.rgba_leftline_item = DualColoredLineSegment()
        self.rgba_leftline_item.setLine(0, 0, self.width(), 0)
        self.rgba_rightline_item = DualColoredLineSegment()
        self.rgba_rightline_item.setLine(0, 0, self.width(), 0)

        # crosshair circle
        self.rgba_crosshair_item_circle = QGraphicsEllipseItem()

        self.rgba_crosshair_item_circle.setRect(
            -(self.CROSSHAIR_RADIUS * 0.5),
            -(self.CROSSHAIR_RADIUS * 0.5),
            self.CROSSHAIR_RADIUS,
            self.CROSSHAIR_RADIUS
        )

        # add items
        self.rgba_crosshair_item = QGraphicsItemGroup()

        self.rgba_crosshair_item.addToGroup(self.rgba_crosshair_item_circle)
        self.rgba_crosshair_item.addToGroup(self.rgba_topline_item)
        self.rgba_crosshair_item.addToGroup(self.rgba_botline_item)
        self.rgba_crosshair_item.addToGroup(self.rgba_leftline_item)
        self.rgba_crosshair_item.addToGroup(self.rgba_rightline_item)

        self.addItem(self.rgba_crosshair_item)

    def getRGBACrosshairPos(self):
        return self._rgba_crosshair_pos

    def setRGBACrosshairPos(self, pos):
        """
        Places the crosshair at a specific  location in the widget.  This is generally
        used when updating color values, and passing them back to the color widget.

        Args:
            pos (QPoint): in LOCAL space
        """


        crosshair_radius = self.CROSSHAIR_RADIUS * 0.5
        xpos = pos.x()
        ypos = pos.y()

        # update items positions
        self.rgba_crosshair_item_circle.setPos(pos)
        self.rgba_topline_item.setLine(xpos, 0, xpos, ypos - crosshair_radius)
        self.rgba_botline_item.setLine(xpos, ypos + crosshair_radius, xpos, self.height())
        self.rgba_leftline_item.setLine(0, ypos, xpos - crosshair_radius, ypos)
        self.rgba_rightline_item.setLine(xpos + crosshair_radius, ypos, self.width(), ypos)

        # set attr
        self._rgba_crosshair_pos = pos

    def updateRGBACrosshair(self):
        main_widget = getWidgetAncestor(self, ColorGradientDelegate)
        xpos = (main_widget.color().hueF() * self.width())
        ypos = math.fabs((main_widget.color().saturationF() * self.height()) - self.height())
        pos = QPoint(xpos, ypos)
        self.setRGBACrosshairPos(pos)

    def _drawRGBAForegroundItem(self):
        """
        Creates the RGBA Foreground item.  This item is just one big rectangle
        that spans the entire scene with a 1D gradient in it to compensate for the
        Saturation portion of the RGBA gradient.
        """
        self.rgba_foreground = RGBAForegroundGradient(self.width(), self.height())
        self.addItem(self.rgba_foreground)
        self.rgba_foreground.setZValue(-10)
Пример #2
0
class DataNode:
    def __init__(self, data, radius=15):

        self.data = data

        # Add circular node
        self.node = QGraphicsEllipseItem(0, 0, 1, 1)

        # Set radius
        self.radius = radius

        # Add text label
        self.label = QGraphicsTextItem(data.label)
        font = self.label.font()
        font.setPointSize(10)
        self.label.setFont(font)

        # Add line between label and node
        self.line1 = QGraphicsLineItem(0, 0, 1, 1)
        self.line2 = QGraphicsLineItem(0, 0, 1, 1)

        self.node.setZValue(20)
        self.label.setZValue(10)
        self.line1.setZValue(10)
        self.line2.setZValue(10)

        self.line1.setPen(get_pen('0.5'))
        self.line2.setPen(get_pen('0.5'))

        self.color = '0.8'

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self._radius = value
        self.node.setRect(-value, -value, 2 * value, 2 * value)

    def contains(self, point):

        # Check label
        if self.label.contains(self.label.mapFromScene(point)):
            return True

        # Check node
        if self.node.contains(self.node.mapFromScene(point)):
            return True

        return False

    def update(self):
        self.node.update()

    def add_to_scene(self, scene):
        scene.addItem(self.node)
        scene.addItem(self.label)
        scene.addItem(self.line1)
        scene.addItem(self.line2)

    def remove_from_scene(self, scene):
        scene.removeItem(self.node)
        scene.removeItem(self.label)
        scene.removeItem(self.line1)
        scene.removeItem(self.line2)

    @property
    def node_position(self):
        pos = self.node.pos()
        return pos.x(), pos.y()

    @node_position.setter
    def node_position(self, value):
        self.node.setPos(value[0], value[1])
        self.update_lines()

    @property
    def label_position(self):
        pos = self.label.pos()
        return pos.x(), pos.y()

    @label_position.setter
    def label_position(self, value):
        self.label.setPos(value[0], value[1])
        self.update_lines()

    def update_lines(self):
        x0, y0 = self.label_position
        x2, y2 = self.node_position
        x1 = 0.5 * (x0 + x2)
        y1 = y0
        self.line1.setLine(x0, y0, x1, y1)
        self.line2.setLine(x1, y1, x2, y2)

    @property
    def color(self):
        return qt_to_mpl_color(self.node.brush().color())

    @color.setter
    def color(self, value):
        self.node.setBrush(mpl_to_qt_color(value))
Пример #3
0
class DataNode:

    def __init__(self, data, radius=15):

        self.data = data

        # Add circular node
        self.node = QGraphicsEllipseItem(0, 0, 1, 1)

        # Set radius
        self.radius = radius

        # Add text label
        self.label = QGraphicsTextItem(data.label)
        font = self.label.font()
        font.setPointSize(10)
        self.label.setFont(font)

        # Add line between label and node
        self.line1 = QGraphicsLineItem(0, 0, 1, 1)
        self.line2 = QGraphicsLineItem(0, 0, 1, 1)

        self.node.setZValue(20)
        self.label.setZValue(10)
        self.line1.setZValue(10)
        self.line2.setZValue(10)

        self.line1.setPen(get_pen('0.5'))
        self.line2.setPen(get_pen('0.5'))

        self.color = '0.8'

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self._radius = value
        self.node.setRect(-value, -value, 2 * value, 2 * value)

    def contains(self, point):

        # Check label
        if self.label.contains(self.label.mapFromScene(point)):
            return True

        # Check node
        if self.node.contains(self.node.mapFromScene(point)):
            return True

        return False

    def update(self):
        self.node.update()

    def add_to_scene(self, scene):
        scene.addItem(self.node)
        scene.addItem(self.label)
        scene.addItem(self.line1)
        scene.addItem(self.line2)

    def remove_from_scene(self, scene):
        scene.removeItem(self.node)
        scene.removeItem(self.label)
        scene.removeItem(self.line1)
        scene.removeItem(self.line2)

    @property
    def node_position(self):
        pos = self.node.pos()
        return pos.x(), pos.y()

    @node_position.setter
    def node_position(self, value):
        self.node.setPos(value[0], value[1])
        self.update_lines()

    @property
    def label_position(self):
        pos = self.label.pos()
        return pos.x(), pos.y()

    @label_position.setter
    def label_position(self, value):
        self.label.setPos(value[0], value[1])
        self.update_lines()

    def update_lines(self):
        x0, y0 = self.label_position
        x2, y2 = self.node_position
        x1 = 0.5 * (x0 + x2)
        y1 = y0
        self.line1.setLine(x0, y0, x1, y1)
        self.line2.setLine(x1, y1, x2, y2)

    @property
    def color(self):
        return qt_to_mpl_color(self.node.brush().color())

    @color.setter
    def color(self, value):
        self.node.setBrush(mpl_to_qt_color(value))