Ejemplo n.º 1
0
    def __init__(
        self,
        image: ScaledImageItem,
        data: np.ndarray,
        pen: QtGui.QPen = None,
        font: QtGui.QFont = None,
        parent: QtWidgets.QGraphicsItem = None,
    ):
        super().__init__(image, parent)

        if pen is None:
            pen = QtGui.QPen(QtCore.Qt.white, 2.0, QtCore.Qt.DotLine)
            pen.setCosmetic(True)
            pen.setCapStyle(QtCore.Qt.RoundCap)

        if font is None:
            font = QtGui.QFont()

        self.image_data = data
        self.sliced: Optional[np.ndarray] = None

        self.pen = pen
        self.font = font

        self.line = QtCore.QLineF()
        self.poly = QtGui.QPolygonF()

        self.action_copy_to_clipboard = qAction(
            "insert-text",
            "Copy To Clipboard",
            "Copy slice values to the clipboard.",
            self.actionCopyToClipboard,
        )
Ejemplo n.º 2
0
    def update_chart(self, task_list, current_date=None):
        self.chart.removeSeries(self.series)
        self.task_list = task_list

        result = TaskAnalyser.getPointFromTasks(self.task_list, self.max_bound,
                                                self.interval)
        self.axisX.setMin(self.max_bound -
                          datetime.timedelta(days=self.interval - 1))
        self.axisY.setRange(min(result), max(result))

        self.qdate = DatetimeParser.fromDateToQDate(str(self.max_bound.date()))
        self.axisX.setMax(self.max_bound)

        self.series = QtCharts.QLineSeries()
        self.series.setName("Karma points")
        self.axisX.setTickCount(self.interval)
        result.reverse()

        for i in range(len(result)):
            self.series.append(
                self.qdate.addDays(-self.interval - 1 - i).toMSecsSinceEpoch(),
                result[i])

        pen = QPen()
        pen.setWidth(3)
        pen.setColor(QColor(242, 183, 54))
        pen.setCapStyle(Qt.RoundCap)
        self.series.setPen(pen)
        self.chart.addSeries(self.series)
        self.update()
Ejemplo n.º 3
0
        def paintEvent(self, paintEvent: QPaintEvent):
            painter = QPainter(self)
            painter.setBackgroundMode(Qt.TransparentMode)
            painter.setRenderHint(QPainter.Antialiasing)
            brush = QBrush()
            brush.setStyle(Qt.SolidPattern)
            pen = QPen()
            pen.setJoinStyle(Qt.RoundJoin)
            pen.setCapStyle(Qt.RoundCap)

            center = QPoint(self.width() // 2, self.height() // 2)
            radius = 0.45 * min(self.width(), self.height())

            pen.setColor(self.palette().color(self.color[0]))
            brush.setColor(self.palette().color(self.color[1]))
            if self.highlight is True:
                pen.setColor(self.palette().color(QPalette.Highlight))
            pen.setWidth(round(0.15 * radius))
            painter.setBrush(brush)
            painter.setPen(pen)
            painter.drawEllipse(center, radius, radius)

            if self.checked is True:
                brush.setColor(self.palette().color(QPalette.Background))
                pen.setColor(self.palette().color(QPalette.Background))
                painter.setPen(pen)
                painter.setBrush(brush)
                painter.drawEllipse(center, 0.40 * radius, 0.40 * radius)
            del painter, brush, pen
Ejemplo n.º 4
0
        def paintEvent(self, paintEvent: QPaintEvent):
            painter = QPainter(self)
            painter.setBackgroundMode(Qt.TransparentMode)
            painter.setRenderHint(QPainter.Antialiasing)
            brush = QBrush()
            brush.setStyle(Qt.SolidPattern)
            pen = QPen()
            pen.setJoinStyle(Qt.RoundJoin)
            pen.setCapStyle(Qt.RoundCap)

            center = QPoint(self.width() // 2, self.height() // 2)
            radius = 0.45 * min(self.width(), self.height())

            pen.setColor(self.palette().color(self.color[0]))
            brush.setColor(self.palette().color(self.color[1]))
            if self.highlight is True:
                pen.setColor(self.palette().color(QPalette.Highlight))
            pen.setWidth(round(0.15 * radius))
            painter.setBrush(brush)
            painter.setPen(pen)
            painter.drawEllipse(center, radius, radius)

            if self.checked is True:
                brush.setColor(self.palette().color(QPalette.Background))
                pen.setColor(self.palette().color(QPalette.Background))
                painter.setPen(pen)
                painter.setBrush(brush)
                painter.drawEllipse(center, 0.40 * radius, 0.40 * radius)
            del painter, brush, pen
Ejemplo n.º 5
0
    def paintEvent(self, event):
        s = self.size()
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing, True)
        qp.setPen(self.penColor)
        qp.setBrush(self.fillColor)
        qp.drawRect(0, 0, s.width(), s.height())

        if self.drawDrag:
            pen = QPen(Qt.white, 5)
            pen.setCapStyle(Qt.RoundCap)
            qp.setPen(pen)
            qp.setBrush(self.fillColor)

            outerWidth = s.width() - 60
            outerHeight = s.height() - 60

            ow = int(s.width() / 2 - outerWidth / 2)
            oh = int(s.height() / 2 - outerHeight / 2)
            qp.drawRoundedRect(ow, oh, outerWidth, outerHeight, 5, 5)

            qp.setBrush(Qt.white)
            thickness = 12
            length = 50
            roundness = thickness / 2

            vS = int(s.width() / 2 - thickness / 2)
            vE = int(s.height() / 2 - length / 2)
            qp.drawRoundedRect(vS, vE, thickness, length, roundness, roundness)
            hS = int(s.width() / 2 - length / 2)
            hE = int(s.height() / 2 - thickness / 2)
            qp.drawRoundedRect(hS, hE, length, thickness, roundness, roundness)

        qp.end()
Ejemplo n.º 6
0
    def __init__(
        self,
        image: ScaledImageItem,
        pen: QtGui.QPen = None,
        font: QtGui.QFont = None,
        unit: str = "μm",
        parent: QtWidgets.QGraphicsItem = None,
    ):
        super().__init__(image, None, parent)

        if pen is None:
            pen = QtGui.QPen(QtCore.Qt.white, 2.0)
            pen.setCosmetic(True)
            pen.setStyle(QtCore.Qt.DashLine)
            pen.setCapStyle(QtCore.Qt.RoundCap)

        if font is None:
            font = QtGui.QFont()

        self.pen = pen
        self.font = font
        self.text = ""
        self.unit = unit

        self.line = QtCore.QLineF()
Ejemplo n.º 7
0
 def paint(self, painter, options, widget):
     pen = QPen()
     pen.setColor(self.color)
     pen.setStyle(Qt.DashLine)
     pen.setCapStyle(Qt.RoundCap)
     pen.setWidth(ConnectionIndicator.PEN_WIDTH)
     painter.setPen(pen)
     painter.drawLine(self._srcPoint, self._destPoint)
Ejemplo n.º 8
0
 def _make_pen(self):
     pen = QPen()
     pen.setWidth(self._width)
     color = QGuiApplication.palette().color(QPalette.Normal,
                                             QPalette.WindowText)
     color.setAlphaF(0.8)
     pen.setColor(color)
     pen.setStyle(Qt.SolidLine)
     pen.setCapStyle(Qt.RoundCap)
     return pen
Ejemplo n.º 9
0
    def paintEvent(self, paintEvent: QPaintEvent):
        pen = QPen()
        pen.setJoinStyle(Qt.RoundJoin)
        pen.setCapStyle(Qt.RoundCap)
        painter = QPainter(self)
        painter.translate(self.paintOffset)
        painter.setBackgroundMode(Qt.TransparentMode)
        painter.setRenderHint(QPainter.Antialiasing)

        if self.nodes is not None:
            painted = set()

            def paintNode(node):
                nonlocal painter, painted
                if node in painted:
                    return
                painted.add(node)
                for link in node.links:
                    if link not in painted:
                        painter.drawLine(node.point, link.point)
                        paintNode(link)

            color = self.palette().color(QPalette.Dark)
            pen.setColor(color)
            pen.setWidth(0.50 * self.paintStep)
            painter.setPen(pen)
            for node in self.nodes.values():
                if paintEvent.region().contains(node.point):
                    paintNode(node)

        if self.startNode is not None:
            color = self.palette().color(QPalette.Dark)
            pen.setColor(color)
            pen.setWidth(0.75 * self.paintStep)
            painter.setPen(pen)
            if paintEvent.region().contains(self.startNode.point):
                painter.drawPoint(self.startNode.point)

        if self.finishNode is not None and paintEvent.region().contains(self.finishNode.point):
            color = self.palette().color(QPalette.Dark).darker(120)
            pen.setColor(color)
            pen.setWidth(0.75 * self.paintStep)
            painter.setPen(pen)
            painter.drawPoint(self.finishNode.point)

        if self.player is not None:
            color = self.palette().color(QPalette.Highlight)
            color.setAlpha(196)
            pen.setColor(color)
            pen.setWidth(0.90 * self.paintStep)
            painter.setPen(pen)
            painter.drawPoint(self.player)

        del painter, pen
Ejemplo n.º 10
0
 def paint(self, painter, option, widget=None):
     for i in range(1, len(self.points)):
         pen = QPen()
         pen.setColor(self.color)
         pen_width = (self.stroke_weights[i] +
                      0.2) * self.base_stroke_weight
         pen.setWidthF(pen_width)
         if i == 1 or i == len(self.points) - 1:
             pen.setCapStyle(Qt.RoundCap)
         painter.setPen(pen)
         painter.setRenderHint(QPainter.Antialiasing)
         painter.setRenderHint(QPainter.HighQualityAntialiasing)
         painter.drawLine(self.points[i - 1], self.points[i])
Ejemplo n.º 11
0
def initialize_qpen(qt_color, width=2):
    """
    Initializes a Qt QPen with color qt_clor
    :param width:
    :param qt_color: A color from Qt: Qt.Color
    :return: returns the created QPen
    """
    mpen = QPen()
    mpen.setCapStyle(Qt.FlatCap)
    mpen.setWidth(width)
    mpen.setColor(qt_color)

    return mpen
Ejemplo n.º 12
0
    def reset(self, parameters: Parameters):
        self._parameters = parameters

        self._total_label.setText("Éponges détectées : 0")

        for i in reversed(range(self._legend_layout.count())):
            self._legend_layout.itemAt(i).widget().setParent(None)

        self._chart.removeAllSeries()
        self._legend_items = {}
        self._series = {}
        for i, m in parameters.selectedMorphotypes().items():
            self._series[i] = QtCharts.QLineSeries(self)
            self._series[i].setName(m.name())
            self._series[i].setColor(m.color())

            pen = QPen(m.color(), 3)
            pen.setCapStyle(Qt.RoundCap)
            self._series[i].setPen(pen)

            self._series[i].append(0, 0)
            self._chart.addSeries(self._series[i])

            self._legend_items[i] = ChartLegendItem(m.name(), m.color(), self)
            self._legend_items[i].toggled.connect(self._legendItemToggled)

        for i, k in enumerate(self._legend_items.keys()):
            row = i % 2 + 1
            col = i // 2 + 1

            self._legend_layout.addWidget(self._legend_items[k], row, col)

        axis_pen = QPen(Loader.QSSColor("@dark"))
        axis_pen.setWidth(2)

        grid_line_pen = QPen(Loader.QSSColor("@light-gray"))

        labels_font = QFont(Loader.QSSVariable("@font"))
        labels_font.setPointSize(10)

        self._chart.createDefaultAxes()

        for axis in (self._chart.axisX(), self._chart.axisY()):
            axis.setRange(0, 4)
            axis.setLinePen(axis_pen)
            axis.setGridLinePen(grid_line_pen)
            axis.setLabelFormat("%d")
            axis.setLabelsFont(labels_font)
Ejemplo n.º 13
0
 def pathComponent(self):
     pathPainter = QPainter(self)
     pathPainter.setRenderHint(QPainter.Antialiasing)
     penPath = QPen()
     penPath.setStyle(Qt.SolidLine)
     penPath.setWidth(self.pathWidth)
     penPath.setBrush(
         QColor(self.pathColor[0], self.pathColor[1], self.pathColor[2]))
     penPath.setCapStyle(Qt.RoundCap)
     penPath.setJoinStyle(Qt.RoundJoin)
     pathPainter.setPen(penPath)
     pathPainter.drawArc(self.positionX + self.posFactor,
                         self.positionY + self.posFactor,
                         self.rpb_Size - self.sizeFactor,
                         self.rpb_Size - self.sizeFactor, 0, 360 * 16)
     pathPainter.end()
Ejemplo n.º 14
0
 def lineComponent(self):
     linePainter = QPainter(self)
     linePainter.setRenderHint(QPainter.Antialiasing)
     penLine = QPen()
     penLine.setStyle(self.rpb_lineStyle)
     penLine.setWidth(self.lineWidth)
     penLine.setBrush(
         QColor(self.lineColor[0], self.lineColor[1], self.lineColor[2]))
     penLine.setCapStyle(self.rpb_lineCap)
     penLine.setJoinStyle(Qt.RoundJoin)
     linePainter.setPen(penLine)
     linePainter.drawArc(self.positionX + self.posFactor,
                         self.positionY + self.posFactor,
                         self.rpb_Size - self.sizeFactor,
                         self.rpb_Size - self.sizeFactor,
                         self.startPosition, self.rpb_value)
     linePainter.end()
Ejemplo n.º 15
0
class FlowTheme:
    """A FlowTheme holds all design information for the flow. And it defines what
    themes exist. Notice, that all drawing of NodeInstances and PortInstances
    is done by NIPainter classes, while for each FlowTheme there exists exactly
    one NIPainter class.

    HOW TO CREATE NEW THEMES
    - Create a new subclass of NIPainter in NodeInstancePainter.py, and implement
    all methods that are passed in NIPainter (take a look at the other already
    existing NIPainter subclasses there for reference)
    - Add a new theme entry to the flow_themes array of DesignContainer and
    reference the new NIPainter subclass for your new theme you just made"""
    def __init__(self,
                 name,
                 flow_conn_exec_color,
                 flow_conn_exec_width,
                 flow_conn_exec_pen_style,
                 flow_conn_data_color,
                 flow_conn_data_width,
                 flow_conn_data_pen_style,
                 node_instance_painter,
                 flow_background_color=QColor('#333333')):
        self.name = name
        self.node_inst_painter = node_instance_painter

        self.flow_conn_exec_pen = QPen(flow_conn_exec_color,
                                       flow_conn_exec_width)
        self.flow_conn_exec_pen.setStyle(flow_conn_exec_pen_style)
        self.flow_conn_exec_pen.setCapStyle(Qt.RoundCap)

        self.flow_conn_data_pen = QPen(flow_conn_data_color,
                                       flow_conn_data_width)
        self.flow_conn_data_pen.setStyle(flow_conn_data_pen_style)
        self.flow_conn_data_pen.setCapStyle(Qt.RoundCap)

        self.flow_background_color = flow_background_color

    def get_flow_conn_pen_inst(self, connection_type):
        if connection_type == 'data':
            return self.flow_conn_data_pen.__copy__()
        else:
            return self.flow_conn_exec_pen.__copy__()
Ejemplo n.º 16
0
class BoltPainter(BasePainter):
    def __init__(self, parent):
        BasePainter.__init__(self, parent)
        self._pen_z_1 = None
        self._pen_z_2 = None
        self._pen_z_0 = None
        self._length = None

    def setup(self):
        if self.is_set:
            return

        self._pen_z_2 = QPen(QColor(255, 0, 0), 5, Qt.SolidLine)
        self._pen_z_2.setCapStyle(Qt.RoundCap)
        self._pen_z_1 = QPen(QColor(255, 100, 100), 5, Qt.SolidLine)
        self._pen_z_1.setCapStyle(Qt.RoundCap)
        self._pen_z_0 = QPen(QColor(255, 255, 255), 5, Qt.SolidLine)
        self._pen_z_0.setCapStyle(Qt.RoundCap)
        self._length = 25
        self.is_set = True

    def paint(self, painter: QPainter, model: BaseModel):
        if model.is_alive:
            assert self.is_set, 'Painter is not set.'
            _origin = self.transform(model.x, model.y, is_point=True)
            for _i, _pen in enumerate(
                [self._pen_z_2, self._pen_z_1, self._pen_z_0]):
                _factor = (3 - _i) / 3
                _tail_x = _origin.x() - model.dir_y * self._length * _factor
                _tail_y = _origin.y() + model.dir_x * self._length * _factor
                _tail = QPoint(_tail_x, _tail_y)
                painter.setPen(_pen)
                painter.drawLine(_origin, _tail)
Ejemplo n.º 17
0
class ArcItem(QGraphicsLineItem):
    """Arc item to use with GraphViewForm. Connects a RelationshipItem to an ObjectItem."""
    def __init__(self, rel_item, obj_item, width, is_wip=False):
        """Initializes item.

        Args:
            rel_item (spinetoolbox.widgets.graph_view_graphics_items.RelationshipItem): relationship item
            obj_item (spinetoolbox.widgets.graph_view_graphics_items.ObjectItem): object item
            width (float): Preferred line width
        """
        super().__init__()
        self.rel_item = rel_item
        self.obj_item = obj_item
        self._width = float(width)
        self.is_wip = is_wip
        src_x = rel_item.x()
        src_y = rel_item.y()
        dst_x = obj_item.x()
        dst_y = obj_item.y()
        self.setLine(src_x, src_y, dst_x, dst_y)
        self._pen = QPen()
        self._pen.setWidth(self._width)
        color = QGuiApplication.palette().color(QPalette.Normal,
                                                QPalette.WindowText)
        color.setAlphaF(0.8)
        self._pen.setColor(color)
        self._pen.setStyle(Qt.SolidLine)
        self._pen.setCapStyle(Qt.RoundCap)
        self.setPen(self._pen)
        self.setZValue(-2)
        rel_item.add_arc_item(self)
        obj_item.add_arc_item(self)
        if self.is_wip:
            self.become_wip()
        self.setCursor(Qt.ArrowCursor)

    def mousePressEvent(self, event):
        """Accepts the event so it's not propagated."""
        event.accept()

    def other_item(self, item):
        return {
            self.rel_item: self.obj_item,
            self.obj_item: self.rel_item
        }.get(item)

    def become_wip(self):
        """Turns this arc into a work-in-progress."""
        self.is_wip = True
        self._pen.setStyle(Qt.DotLine)
        self.setPen(self._pen)

    def become_whole(self):
        """Removes the wip status from this arc."""
        self.is_wip = False
        self._pen.setStyle(Qt.SolidLine)
        self.setPen(self._pen)

    def move_rel_item_by(self, pos_diff):
        """Moves source point.

        Args:
            pos_diff (QPoint)
        """
        line = self.line()
        line.setP1(line.p1() + pos_diff)
        self.setLine(line)

    def move_obj_item_by(self, pos_diff):
        """Moves destination point.

        Args:
            pos_diff (QPoint)
        """
        line = self.line()
        line.setP2(line.p2() + pos_diff)
        self.setLine(line)

    def adjust_to_zoom(self, transform):
        """Adjusts the item's geometry so it stays the same size after performing a zoom.

        Args:
            transform (QTransform): The view's transformation matrix after the zoom.
        """
        factor = transform.m11()
        if factor < 1:
            return
        scaled_width = self._width / factor
        self._pen.setWidthF(scaled_width)
        self.setPen(self._pen)

    def wipe_out(self):
        self.obj_item.arc_items.remove(self)
        self.rel_item.arc_items.remove(self)
Ejemplo n.º 18
0
class spiralProgressBar(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(spiralProgressBar, self).__init__(parent)

        self.positionX = 0
        self.positionY = 0
        self.spb_Size = 0
        self.posFactor = 0
        self.sizeFactor = 0

        self.spb_maximSize = (0, 0)
        self.spb_minimSize = (0, 0)

        self.spb_dynamicMin = True
        self.spb_dynamicMax = True

        self.noProgBar = 3

        self.spb_value = [-48 * 16, -24 * 16, -12 * 16]
        self.spb_minimValue = [0, 0, 0]
        self.spb_maximValue = [100, 100, 100]
        self.spb_startPos = [
            self.startPosFlags.North, self.startPosFlags.North,
            self.startPosFlags.North
        ]
        self.spb_direction = [
            self.rotationFlags.Clockwise, self.rotationFlags.Clockwise,
            self.rotationFlags.Clockwise
        ]

        self.lineWidth = 5
        self.lineColor = [[0, 159, 227], [0, 159, 227], [0, 159, 227]]
        self.lineStyle = [
            self.lineStyleFlags.SolidLine, self.lineStyleFlags.SolidLine,
            self.lineStyleFlags.SolidLine
        ]
        self.lineCap = [
            self.lineCapFlags.RoundCap, self.lineCapFlags.RoundCap,
            self.lineCapFlags.RoundCap
        ]
        self.varWidth = False
        self.widthIncr = 1

        self.pathWidth = 5
        self.pathColor = [[179, 241, 215], [179, 241, 215], [179, 241, 215]]
        self.pathPresent = True
        self.pathStyle = [
            self.lineStyleFlags.SolidLine, self.lineStyleFlags.SolidLine,
            self.lineStyleFlags.SolidLine
        ]
        self.pathIndepend = False

        self.spb_gap = self.lineWidth * 2  #GAP BETWEEN THE ROUNDPROGRESS BAR MAKING A SPIRAL PROGRESS BAR.
        self.gapCngd = False
        self.spb_cngSize = 1

#------------------------------------------------------CLASS ENUMERATORS

    class lineStyleFlags:
        SolidLine = Qt.SolidLine
        DotLine = Qt.DotLine
        DashLine = Qt.DashLine

    class lineCapFlags:
        SquareCap = Qt.SquareCap
        RoundCap = Qt.RoundCap

    class rotationFlags:
        Clockwise = -1
        AntiClockwise = 1

    class startPosFlags:
        North = 90 * 16
        South = -90 * 16
        East = 0 * 16
        West = 180 * 16

#------------------------------------------------------METHODS FOR CHANGING THE PROPERTY OF THE SPIRALPROGRESSBAR :SOLTS

    def spb_setMinimumSize(self, width, height):
        """
        Minimum Size of the Widget
        ...

        Parameters
        --------------

        width : int
            width of the Widget

        height : int
            height of the Widget

        Raises
        --------------
        none
        """
        self.spb_dynamicMin = False
        self.setMinimumSize(width, height)
        self.spb_minimSize = (width, height)
        self.update()

    def spb_setMaximumSize(self, width, height):
        """
        Maximum Size of the Widget
        ...

        Parameters
        --------------

        width : int
            width of the Widget

        height : int
            height of the Widget

        Raises
        --------------
        none
        """
        self.spb_dynamicMax = False
        self.setMaximumSize(width, height)
        self.spb_maximSize = (width, height)
        self.update()

    def spb_setNoProgressBar(self, num):
        """
        By default the Number of progress bar in spiralProgressBar is: 3,
        Users can increase the number of progress bar upto 6.(min: 2), this function
        is used to do exactly that.
        ...

        Parameters
        --------------
        num : int
            Number of progress bar.

        Raises
        --------------
        Exception : "Supported Format: int and not: " + type(num)
            raised when the user passes a non-int 'num' to the method.
        """
        if type(num) != type(
                5
        ):  #MAKING SURE THAT THE ENTERED IS A NUMBER AND NOT A STRING OR OTHERS
            raise Exception("Supported Format: int and not: " + str(type(num)))
        if num <= 6 and num >= 2:
            self.noProgBar = num
            self.spb_value = []
            self.spb_maximValue = []
            self.spb_minimValue = []
            self.spb_startPos = []
            self.spb_direction = []
            self.lineColor = []
            self.lineStyle = []
            self.lineCap = []
            for each in range(0, self.noProgBar, 1):
                self.spb_value.append(-12 * self.noProgBar * 16 / (each + 1))
                self.spb_maximValue.append(100)
                self.spb_minimValue.append(0)
                self.spb_startPos.append(self.startPosFlags.North)
                self.spb_direction.append(self.rotationFlags.Clockwise)
                self.lineColor.append([0, 159, 227])
                self.lineStyle.append(self.lineStyleFlags.SolidLine)
                self.lineCap.append(self.lineCapFlags.RoundCap)
                self.pathColor.append([179, 241, 215])
                self.pathStyle.append(self.lineStyleFlags.SolidLine)
            self.update()

    def spb_setValue(self, value):  #value: TUPLE OF (value1, value2, value3)
        """
        Set the current value of the Progress Bar. maximum value >= Value >= minimum Value
        The user can set the value of each progress bar within the spiralprogressbar independely.
        The 'value' tuple element order corresponds to the outer to inner most progressbar.
        ...

        Parameters
        --------------
        value : tuple
            Ex: value = (0, 50, 22), this means value of outermost progress bar has the value of 0, 
            midden one to 50, and innermost to 22.

        Raises
        --------------
        Exception : "Value should be a tuple and not " + type(value)
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(value) != type(()):  #IF INPUT IS NOT A TUPLE
            raise Exception("Value should be a Tuple and not " +
                            str(type(value)))
        elif len(
                value
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                value
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        elif self.spb_value != value:  #IF EVERY THING GOES RIGHT
            for each in range(0, self.noProgBar, 1):
                if value[each] != 'nc':  #nc: NOC CHANGE STRING FOR ELEIMINATING THE NO CHANGE PROGRESS VALUES
                    if value[each] < self.spb_minimValue[each]:
                        spiralProgressBar.convValue(self,
                                                    self.spb_minimValue[each],
                                                    each)
                    elif value[each] > self.spb_maximValue[each]:
                        spiralProgressBar.convValue(self,
                                                    self.spb_maximValue[each],
                                                    each)
                    else:
                        spiralProgressBar.convValue(self, value[each], each)
            self.update()

    def spb_setMaximum(self, maxVal):
        """
        Maximum Value of the progressbar, default is 100.
        ...

        Parameters
        --------------
        maxVal : tuple
            Maximum value of each progressbar, in tuple, with elements in order 
            Ex: maxVal = (100, 200, 300) : corresponding to 100 for the outermost, 200
            for middle progress bar, 300 for innermost progressbar. 

        Raises
        --------------
        Exception : "The Max. for should be in form of a Tuple and not: " + type(maxVal)
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(maxVal) != type(()):  #IF INPUT IS NOT A TUPLE
            raise Exception(
                "The Max. for should be in form of a Tuple and not: " +
                str(type(maxVal)))
        elif len(
                maxVal
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                maxVal
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        elif self.spb_maximValue != maxVal:
            for each in range(0, self.noProgBar,
                              1):  #TO AVOID FUTURE DIVISION BY ZERO ERROR
                if maxVal[each] == self.spb_minimValue[each]:
                    raise ValueError(
                        "Maximum and Minimum Value Cannot be the Same")
            self.spb_maximValue = list(maxVal)
            self.update()

    def spb_setMinimum(self, minVal):
        """
        Minimum Value of the progressbar, default is 0.
        ...

        Parameters
        --------------
        minVal : tuple
            Minimum value of each progressbar, in tuple, with elements in order 
            Ex: minVal = (0, 10, 20) : corresponding to 0 for the outermost, 10
            for middle progress bar, 20 for innermost progressbar. 

        Raises
        --------------
        Exception : "The Min. for should be in form of a Tuple and not: " + type(minVal)
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(minVal) != type(()):  #IF INPUT IS NOT A TUPLE
            raise Exception(
                "The Min. for should be in form of a Tuple and not: " +
                str(type(minVal)))
        elif len(
                minVal
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                minVal
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        elif self.spb_minimValue != minVal:
            for each in range(0, self.noProgBar,
                              1):  #TO AVOID FUTURE DIVISION BY ZERO ERROR
                if minVal[each] == self.spb_maximValue[each]:
                    raise ValueError(
                        "Maximum and Minimum Value Cannot be the Same")
            self.spb_minimValue = list(minVal)
            self.update()

    def spb_setRange(self, minTuple, maxTuple):
        """
        This function does the job of setting the Maximum value and Minimum value in one go.
        ...

        Parameters
        --------------
        maxTuple : tuple
            Maximum value of each progressbar, in tuple, with elements in order 
            Ex: maxVal = (100, 200, 300) : corresponding to 100 for the outermost, 200
            for middle progress bar, 300 for innermost progressbar. 

        minVal : tuple
            Minimum value of each progressbar, in tuple, with elements in order 
            Ex: minVal = (0, 10, 20) : corresponding to 0 for the outermost, 10
            for middle progress bar, 20 for innermost progressbar. 

        Raises
        --------------
        Exception : "The Minimum and Maximum should be a Tuple"
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(minTuple) != type(()) or type(maxTuple) != type(()):
            raise Exception("The Minimum and Maximum should be a Tuple")
        elif len(minTuple) > self.noProgBar or len(maxTuple) > self.noProgBar:
            raise ValueError(
                "Minimum/Maximum Tuple length exceeds the number of Progress Bar"
            )
        elif len(minTuple) < self.noProgBar or len(maxTuple) < self.noProgBar:
            raise ValueError(
                "Minimum/Maximum Tuple length is less than the number of Progress Bar"
            )
        for each in range(0, self.noProgBar, 1):
            if minTuple[each] == maxTuple[each]:
                raise ValueError("Minimum and Maximum cannot be the Same")
        self.spb_minimValue = minTuple
        self.spb_maximValue = maxTuple
        self.update()

    def spb_setGap(self, gap):
        """
        Set the Gap between each concentric circle in the spiralProgressBar.
        Default is : gap = 2*line width
        ...

        Parameters
        --------------
        gap : int
        Try different settings by passing an int to the function: 'int' corresponds to the "px" seperation
        between the concentric circles.  

        Raises
        --------------
        Exception : "Gap should be an integer and not: " + type(gap)
            Rasied when the user passes a non-tuple data type to the module.
        """

        if type(gap) != type(5):
            raise ValueError("Gap should be an integer and not: " +
                             str(type(gap)))
        else:
            self.spb_gap = gap
            self.gapCngd = True
            self.update()

    def spb_setInitialPos(self, position):
        """
        Sets the statring point of the progress bar or the 0% position.
        Default is 'North'
        ...

        Parameters
        --------------
        position : tuple
            The tuple elements accepts only string of : 'North', 'South', 'East' and 'West'.
            The order of arrangment matters i.e. the first element corresponds to the outer most concentric 
            progress bar and the last element correspinds to the innermost circle. 
            Ex : position = ('North', 'South', 'East')

        Raises
        --------------
        Exception : "Position should be a Tuple and not " + type(position)
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(position) != type(()):  #IF INPUT IS NOT A TUPLE
            raise Exception("Position should be a Tuple and not " +
                            str(type(position)))
        elif len(
                position
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                position
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        else:
            for each in range(0, self.noProgBar, 1):
                if type(position[each]) != type("string"):
                    raise Exception(
                        "Position Tuple elements should be String and not: " +
                        str(type(position[each])))
                elif position[each] == 'North':
                    self.spb_startPos[each] = self.startPosFlags.North
                elif position[each] == 'South':
                    self.spb_startPos[each] = self.startPosFlags.South
                elif position[each] == 'East':
                    self.spb_startPos[each] = self.startPosFlags.East
                elif position[each] == 'West':
                    self.spb_startPos[each] = self.startPosFlags.West
                else:
                    raise Exception(
                        "Position can hold Property: 'North', 'South', 'East' and 'West' and not: "
                        + position[each])
            self.update()

    def spb_reset(self):
        """
        Resets the progress bar to the 0%.
        ...

        Parameters
        --------------
        none

        Raises
        --------------
        none
        """

        for each in range(0, self.noProgBar, 1):
            spiralProgressBar.convValue(self, self.spb_minimValue[each], each)
        self.update()

    def spb_setGeometry(self, posX, posY):
        """
        This module changes the position of the widget. Default it is : (0, 0).
        ...

        Parameters
        --------------
        posX : int
            The vertical position of the widget from the top of the window inside which the widget lies.
            By default it is 0. The user can change the position to better suite his style and positioning of the
            widget.

        posY : int

        Raises
        --------------
        Exception : Position should be an int
            If the user passes a non-int data type.
        """

        if type(posX) != type(5) or type(posY) != type(5):
            raise Exception("Position should be a int and not: X" +
                            str(type(posX))) + ", Y: " + str(type(posY))
            return
        if self.positionX != posX:
            self.positionX = posX
        if self.positionY != posY:
            self.positionY = posY
        self.update()

    def spb_setDirection(self, direction):
        """
        Direction of rotation of the spiral progress bar.
        ...

        Parameters
        --------------
        direction : tuple
            Direction that the round progress bar can hold are : 'Clockwise' and 'AntiClockwise'
            Default is 'Clockwise'. The tuple take string as elements corresponding to the direction of
            each of the concentric circles.

        Raises
        --------------
        Exception : "Direction should be a Tuple"
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.

        Exception : "Direction Tuple elements should be String"
            Rasies when the elements of the tuple is not a string.
        """

        if type(direction) != type(()):  #IF INPUT IS NOT A TUPLE
            raise Exception("Direction should be a Tuple and not " +
                            str(type(direction)))
        elif len(
                direction
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                direction
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        else:
            for each in range(0, self.noProgBar, 1):
                if type(direction[each]) != type("String"):
                    raise Exception(
                        "Direction Tuple elements should be String and not: " +
                        str(type(direction[each])))
                elif direction[each] == 'Clockwise':
                    self.spb_direction[each] = self.rotationFlags.Clockwise
                elif direction[each] == 'AntiClockwise':
                    self.spb_direction[each] = self.rotationFlags.AntiClockwise
                else:
                    raise Exception(
                        "Direction can hold Property: 'Clockwise'/'AntiClockwise' and not: "
                        + str(type(direction[each])))
            self.update()

    def variableWidth(self, inp):
        """
        A flag for varing the progress bar size.
        ...

        Parameters
        --------------
        inp : bool
            True : Changes the size of the width of line progressely.

        Raises
        --------------
        Exception : Variable width should be a bool : True/False
            Rasied when the user passes a non-bool data type to the module.
        """

        if type(inp) != type(True):
            raise Exception("Variable Width should be a Bool and not " +
                            str(type(inp)))
        else:
            self.varWidth = inp
            self.update()

    def spb_widthIncrement(self, increm):
        """
        Width increment for incrment in the line width. Default is 1px. User can sepcify the
        amount of px to increment form the outer to inner circle progressbar.
        ...

        Parameters
        --------------
        incrment : int
            Increment passed to the module as int px.

        Raises
        --------------
        Exception : Increment should be an integer
            Rasied when the user passes a non-int data type to the module.
        """

        if type(increm) != type(5):
            raise Exception("Increment should be an integer and not " +
                            str(type(increm)))
        else:
            self.widthIncr = increm
            self.update()

    def spb_lineWidth(self, width):
        """
        Line width of the circles in the spiral progress bar.
        ...

        Parameters
        --------------
        width : int

        Raises
        --------------
        Exception : Width should be an Integer
            Rasied when the user passes a non-int data type to the module.
        """

        if type(width) != type(5):
            raise Exception("Width should be an Integer and not " +
                            str(type(width)))
        else:
            self.lineWidth = width
            if self.gapCngd != True:
                self.spb_gap = self.lineWidth * 2
            self.update()

    def spb_lineColor(self, color):
        """
        Color of line in the spiral progress bar. Each concentric progress bar has its own color settings. 
        ...

        Parameters
        --------------
        color : tuple
            Color tuple corresponds to the color of each line which is a tuple of (R, G, B).
            Ex : color = ((R, G, B), (R, G, B), (R, G, B))
            Elements of the color tuple is in correspondance with the order : outer to innermost circles in progress bar.

        Raises
        --------------
        Exception : Color should be a Tuple
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(color) != type(()):
            raise Exception("Color should be a Tuple and not " +
                            str(type(Color)))
        elif type(color[0]) != type(()):
            raise Exception(
                "Color should be in Format: ((R, G, B), (R, G, B), (R, G, B)) and not any other"
            )
        elif len(color) > self.noProgBar:
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                color
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        else:
            for each in range(0, self.noProgBar, 1):
                if len(color[each]) != 3:
                    raise Exception('Color should be in format (R, G, B)')
                elif self.lineColor[each] != color[each]:
                    self.lineColor[each] = color[each]
            self.update()

    def spb_lineStyle(self, style):
        """
        line style of the spiral progress bar.
        ...

        Parameters
        --------------
        style : tuple
            Style types : 'SolidLine', 'DotLine' and 'DashLine'.
            Users can pass the style for each progress bar in the order : first element corresponds 
            to the styleof outermost progressbar and viceversa.

        Raises
        --------------
        Exception : Style should be a tuple
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(style) != type(()):
            raise Exception("Style should be a tuple and not: " +
                            str(type(style)))
        elif len(
                style
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                style
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        else:
            for each in range(0, self.noProgBar, 1):
                if type(style[each]) != type("String"):
                    raise Exception(
                        "Style Tuple element should be a String and not: " +
                        str(type(style[each])))
                elif style[each] == 'SolidLine':
                    self.lineStyle[each] = self.lineStyleFlags.SolidLine
                elif style[each] == 'DotLine':
                    self.lineStyle[each] = self.lineStyleFlags.DotLine
                elif style[each] == 'DashLine':
                    self.lineStyle[each] = self.lineStyleFlags.DashLine
                else:
                    raise Exception(
                        "Style can hold 'SolidLine', DotLine' and 'DashLine' only."
                    )
            self.update()

    def spb_lineCap(self, cap):
        """
        Cap i.e. the end of the line : to be Round or Square.
        ...

        Parameters
        --------------
        cap : tuple
            Cap : 'RoundCap' and 'SquareCap'.
            Users can pass the desired cap of the line as a string passed in the following order of : 
            Outer progress bar : first element in the tuple and viceversa.

        Raises
        --------------
        Exception : Cap should be a tuple
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(cap) != type(()):
            raise Exception("Cap should be a tuple and not: " + str(type(cap)))
        elif len(
                cap
        ) > self.noProgBar:  #IF TUPLE LENGTH IS MORE THAN THE NUMBER OF PROGRESS BAR
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                cap
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        else:
            for each in range(0, self.noProgBar, 1):
                if type(cap[each]) != type("String"):
                    raise Exception(
                        'Cap Tuple element should be a String and not a: ' +
                        str(type(cap[each])))
                elif cap[each] == 'SquareCap':
                    self.lineCap[each] = self.lineCapFlags.SquareCap
                elif cap[each] == 'RoundCap':
                    self.lineCap[each] = self.lineCapFlags.RoundCap
                else:
                    raise Exception(
                        "Cap can hold 'SquareCap' and 'RoundCap' only")
            self.update()

    def spb_setPathHidden(self, hide):
        """
        Hides the path in the spiral progress bar.
        ...

        Parameters
        --------------
        hide : bool

        Raises
        --------------
        Exception : Hidden accept a bool
            Rasied when the user passes a non-bool data type to the module.
        """

        if type(hide) != type(True):
            raise Exception("Hidden accept a bool and not: " + str(type(hide)))
        elif hide == True:
            self.pathPresent = False
        else:
            self.pathPresent = True

    def spb_pathColor(self, color):
        """
        Color of path in the spiral progress bar. Each concentric progress bar has its own color settings. 
        ...

        Parameters
        --------------
        color : tuple
            Color tuple corresponds to the color of each path which is a tuple of (R, G, B).
            Ex : color = ((R, G, B), (R, G, B), (R, G, B))
            Elements of the color tuple is in correspondance with the order : outer to innermost circles in progress bar.

        Raises
        --------------
        Exception : Color should be a Tuple
            Rasied when the user passes a non-tuple data type to the module.

        ValueError : "Tuple length more than number of Progress Bars"
            Raised when the tuple contains more element than the number of concentric progress bar in the spiralProgressBar widget.

        ValueError : "Tuple length less than the number of Progress Bars"
            Raised when the tuple contains less element than the number of concentric progress bar in the spiralProgressBar widget.
        """

        if type(color) != type(()):
            raise Exception("Color should be a Tuple and not " +
                            str(type(Color)))
        elif type(color[0]) != type(()):
            raise Exception(
                "Color should be in Format: ((R, G, B), (R, G, B), (R, G, B)) and not any other"
            )
        elif len(color) > self.noProgBar:
            raise ValueError("Tuple length more than number of Progress Bars")
        elif len(
                color
        ) < self.noProgBar:  #IF INPUT TUPLE LENGTH IS LESS THAN THE NUMBER OF PROGRESS BAR
            raise ValueError(
                "Tuple length less than the number of Progress Bars")
        else:
            for each in range(0, self.noProgBar, 1):
                if len(color[each]) != 3:
                    raise Exception('Color should be in format (R, G, B)')
                elif self.pathColor[each] != color[each]:
                    self.pathColor[each] = color[each]
            self.update()

#------------------------------------------------------METHODS FOR GETTING THE PROPERTY OF SPIRALPROGRESSBAR SLOTS

#------------------------------------------------------ENGINE: WHERE ALL THE REAL STUFF TAKE PLACE: WORKING OF THE SPIRALPROGRESSBAR

    def spb_MinimumSize(self, dynMax, minim, maxim):
        """
        Realtime automatic minimum size determiner for the spiral progress bar.
        For this to achieve the function first checks the size of the layout, where the spiralprogressbar lies.
        From that info the, it calculate the minimum size for the spiral progressbar so that all the circles in the spiral
        progress bar is clearly visible.
        
        ...
        Parameters
        --------------
        none.

        Return
        --------------
        none.
        """

        spb_Height = self.height()
        spb_Width = self.width()

        if dynMax:
            if spb_Width >= spb_Height and spb_Height >= minim[1]:
                self.spb_Size = spb_Height
            elif spb_Width < spb_Height and spb_Width >= minim[0]:
                self.spb_Size = spb_Width
        else:
            if spb_Width >= spb_Height and spb_Height <= maxim[1]:
                self.spb_Size = spb_Height
            elif spb_Width < spb_Height and spb_Width <= maxim[0]:
                self.spb_Size = spb_Width

    def geometricFactor(self):
        """
        Width of the line should be subrtracted from the size of the progrress bar, inorder to properly 
        fit inot the layout properly without any cut in the widget margins.
        
        ...
        Parameters
        --------------
        none.

        Return
        --------------
        none.
        """
        self.posFactor = self.lineWidth / 2 + 1
        self.sizeFactor = self.lineWidth + 1

    def convValue(self, value, pos):
        """
        Convert the value from the user entered to the percentage depending on the maximum and minimum value.
        Calculagted by the relation : (value - minimum)/(maximum - minimum)
        
        ...
        Parameters
        --------------
        none.

        Return
        --------------
        none.
        """

        self.spb_value[pos] = (
            (value - self.spb_minimValue[pos]) /
            (self.spb_maximValue[pos] - self.spb_minimValue[pos])) * 360 * 16
        self.spb_value[pos] = self.spb_direction[pos] * self.spb_value[pos]

    def paintEvent(self, event: QPaintEvent):
        """
        The place where the drawing takes palce.
        
        ...
        Parameters
        --------------
        none.

        Return
        --------------
        none.
        """

        if self.spb_dynamicMin:
            self.setMinimumSize(
                QSize(self.lineWidth * 6 + self.pathWidth * 6,
                      self.lineWidth * 6 + self.pathWidth * 6))

        spiralProgressBar.spb_MinimumSize(self, self.spb_dynamicMax,
                                          self.spb_minimSize,
                                          self.spb_maximSize)
        spiralProgressBar.geometricFactor(self)
        spiralIncrem = 0
        spiralIncrem2 = 0

        if self.pathIndepend != True:
            self.pathWidth = self.lineWidth
        self.tempWidth = self.pathWidth
        if self.pathPresent:
            for path in range(0, self.noProgBar, 1):
                if self.varWidth == True:  #CREAETS A INCREASING OR DECREASING TYPE OF WITH
                    self.tempWidth = self.tempWidth + self.widthIncr
                    if self.gapCngd != True:
                        self.spb_gap = self.tempWidth * 2
                self.pathPainter = QPainter(self)
                self.pathPainter.setRenderHint(QPainter.Antialiasing)
                self.penPath = QPen()
                self.penPath.setStyle(self.pathStyle[path])
                self.penPath.setWidth(self.tempWidth)
                self.penPath.setBrush(
                    QColor(self.pathColor[path][0], self.pathColor[path][1],
                           self.pathColor[path][2]))
                self.pathPainter.setPen(self.penPath)
                self.pathPainter.drawArc(
                    self.positionX + self.posFactor +
                    self.spb_cngSize * spiralIncrem2, self.positionY +
                    self.posFactor + self.spb_cngSize * spiralIncrem2,
                    self.spb_Size - self.sizeFactor -
                    2 * self.spb_cngSize * spiralIncrem2, self.spb_Size -
                    self.sizeFactor - 2 * self.spb_cngSize * spiralIncrem2,
                    self.spb_startPos[path], 360 * 16)
                self.pathPainter.end()
                spiralIncrem2 = spiralIncrem2 + self.spb_gap

        self.tempWidth = self.lineWidth  #TEMPWIDTH TEMPORARLY STORES THE LINEWIDTH, USEFUL IN VARIABLE WIDTH OPTION.
        for bar in range(0, self.noProgBar, 1):
            if self.varWidth == True:  #CREAETS A INCREASING OR DECREASING TYPE OF WITH
                self.tempWidth = self.tempWidth + self.widthIncr
                if self.gapCngd != True:
                    self.spb_gap = self.tempWidth * 2
            self.linePainter = QPainter(self)
            self.linePainter.setRenderHint(QPainter.Antialiasing)
            self.penLine = QPen()
            self.penLine.setStyle(self.lineStyle[bar])
            self.penLine.setWidth(self.tempWidth)
            self.penLine.setCapStyle(self.lineCap[bar])
            self.penLine.setBrush(
                QColor(self.lineColor[bar][0], self.lineColor[bar][1],
                       self.lineColor[bar][2]))
            self.linePainter.setPen(self.penLine)
            self.linePainter.drawArc(
                self.positionX + self.posFactor +
                self.spb_cngSize * spiralIncrem, self.positionY +
                self.posFactor + self.spb_cngSize * spiralIncrem,
                self.spb_Size - self.sizeFactor -
                2 * self.spb_cngSize * spiralIncrem, self.spb_Size -
                self.sizeFactor - 2 * self.spb_cngSize * spiralIncrem,
                self.spb_startPos[bar], self.spb_value[bar])
            self.linePainter.end()
            spiralIncrem = spiralIncrem + self.spb_gap
Ejemplo n.º 19
0
    def drawForeground(self, painter, rect):
        """Draws all connections and borders around selected items."""

        pen = QPen()
        if Design.flow_theme == 'dark std':
            # pen.setColor('#BCBBF2')
            pen.setWidth(5)
            pen.setCapStyle(Qt.RoundCap)
        elif Design.flow_theme == 'dark tron':
            # pen.setColor('#452666')
            pen.setWidth(4)
            pen.setCapStyle(Qt.RoundCap)
        elif Design.flow_theme == 'ghostly' or Design.flow_theme == 'blender':
            pen.setWidth(2)
            pen.setCapStyle(Qt.RoundCap)

        # DRAW CONNECTIONS
        for ni in self.all_node_instances:
            for o in ni.outputs:
                for cpi in o.connected_port_instances:
                    if o.type_ == 'data':
                        pen.setStyle(Qt.DashLine)
                    elif o.type_ == 'exec':
                        pen.setStyle(Qt.SolidLine)
                    path = self.connection_path(
                        o.gate.get_scene_center_pos(),
                        cpi.gate.get_scene_center_pos())
                    w = path.boundingRect().width()
                    h = path.boundingRect().height()
                    gradient = QRadialGradient(path.boundingRect().center(),
                                               pythagoras(w, h) / 2)
                    r = 0
                    g = 0
                    b = 0
                    if Design.flow_theme == 'dark std':
                        r = 188
                        g = 187
                        b = 242
                    elif Design.flow_theme == 'dark tron':
                        r = 0
                        g = 120
                        b = 180
                    elif Design.flow_theme == 'ghostly' or Design.flow_theme == 'blender':
                        r = 0
                        g = 17
                        b = 25

                    gradient.setColorAt(0.0, QColor(r, g, b, 255))
                    gradient.setColorAt(0.75, QColor(r, g, b, 200))
                    gradient.setColorAt(0.95, QColor(r, g, b, 0))
                    gradient.setColorAt(1.0, QColor(r, g, b, 0))
                    pen.setBrush(gradient)
                    painter.setPen(pen)
                    painter.drawPath(path)

        # DRAW CURRENTLY DRAGGED CONNECTION
        if self.dragging_connection:
            pen = QPen('#101520')
            pen.setWidth(3)
            pen.setStyle(Qt.DotLine)
            painter.setPen(pen)
            gate_pos = self.gate_selected.get_scene_center_pos()
            if self.gate_selected.parent_port_instance.direction == 'output':
                painter.drawPath(
                    self.connection_path(gate_pos, self.last_mouse_move_pos))
            else:
                painter.drawPath(
                    self.connection_path(self.last_mouse_move_pos, gate_pos))

        # DRAW SELECTED NIs BORDER
        for ni in self.selected_node_instances():
            pen = QPen(QColor('#245d75'))
            pen.setWidth(3)
            painter.setPen(pen)
            painter.setBrush(Qt.NoBrush)

            size_factor = 1.2
            x = ni.pos().x() - ni.boundingRect().width() / 2 * size_factor
            y = ni.pos().y() - ni.boundingRect().height() / 2 * size_factor
            w = ni.boundingRect().width() * size_factor
            h = ni.boundingRect().height() * size_factor
            painter.drawRoundedRect(x, y, w, h, 10, 10)

        # DRAW SELECTED DRAWINGS BORDER
        for p_o in self.selected_drawings():
            pen = QPen(QColor('#a3cc3b'))
            pen.setWidth(2)
            painter.setPen(pen)
            painter.setBrush(Qt.NoBrush)

            size_factor = 1.05
            x = p_o.pos().x() - p_o.width / 2 * size_factor
            y = p_o.pos().y() - p_o.height / 2 * size_factor
            w = p_o.width * size_factor
            h = p_o.height * size_factor
            painter.drawRoundedRect(x, y, w, h, 6, 6)
            painter.drawEllipse(p_o.pos().x(), p_o.pos().y(), 2, 2)
Ejemplo n.º 20
0
    def getPenFromCmnd(self, peninfo):
        '''
        Returns a QPen based on the information in the dictionary
        peninfo.  A ValueError is raised if the value for the
        "style", "capstyle", or "joinstyle" key, if given, is not
        recognized.

        Recognized keys in the outline dictionary are:
            "color": color name or 24-bit RGB integer value
                         (eg, 0xFF0088)
            "alpha": alpha value from 0 (transparent) to 255 (opaque)
            "width": pen width in points (1/72 inches); possibly 
                     further scaled by the width scaling factor 
            "style": pen style name ("solid", "dash", "dot", "dashdot",
                         "dashdotdot")
            "capstyle": pen cap style name ("square", "flat", "round")
            "joinstyle": pen join style name ("bevel", "miter", "round")
        '''
        try:
            mycolor = self.getColorFromCmnd(peninfo)
            mypen = QPen(mycolor)
        except KeyError:
            mypen = QPen()
        try:
            penwidth  = float(peninfo["width"])
            penwidth *= self.__viewer.widthScalingFactor()
            mypen.setWidthF(penwidth)
        except KeyError:
            pass
        try:
            mystyle = peninfo["style"]
            if mystyle == "solid":
                mystyle = Qt.SolidLine
            elif mystyle == "dash":
                mystyle = Qt.DashLine
            elif mystyle == "dot":
                mystyle = Qt.DotLine
            elif mystyle == "dashdot":
                mystyle = Qt.DashDotLine
            elif mystyle == "dashdotdot":
                mystyle = Qt.DashDotDotLine
            else:
                raise ValueError("Unknown pen style '%s'" % str(mystyle))
            mypen.setStyle(mystyle)
        except KeyError:
            pass
        try:
            mystyle = peninfo["capstyle"]
            if mystyle == "square":
                mystyle = Qt.SquareCap
            elif mystyle == "flat":
                mystyle = Qt.FlatCap
            elif mystyle == "round":
                mystyle = Qt.RoundCap
            else:
                raise ValueError("Unknown pen cap style '%s'" % str(mystyle))
            mypen.setCapStyle(mystyle)
        except KeyError:
            pass
        try:
            mystyle = peninfo["joinstyle"]
            if mystyle == "bevel":
                mystyle = Qt.BevelJoin
            elif mystyle == "miter":
                mystyle = Qt.MiterJoin
            elif mystyle == "round":
                mystyle = Qt.RoundJoin
            else:
                raise ValueError("Unknown pen join style '%s'" % str(mystyle))
            mypen.setJoinStyle(mystyle)
        except KeyError:
            pass
        return mypen
Ejemplo n.º 21
0
    def draw_mini_map(self, painter, is_full=False):
        _pixmap_minimap = QPixmap(
            QSize(min([self.width(), self.height()]),
                  min([self.width(), self.height()]))) if is_full else QPixmap(
                      QSize(350, 350))
        if is_full:
            _p_origin = QPoint((self.width() - _pixmap_minimap.width()) // 2,
                               (self.height() - _pixmap_minimap.height()) // 2)
        else:
            _p_origin = QPoint(self.width() - _pixmap_minimap.width(),
                               self.height() - _pixmap_minimap.height())
        _pixmap_minimap.fill(QColor('#00284d'))

        # DRAW DEAD ZONE
        _dz_radius = self.controller.get_dead_zone_radius()
        _xy = QPoint(*self.controller.get_dead_zone_center().tolist())

        # GET MOBILE OBJECTS
        _model_ships = self.controller.get_data_from_players(enemy_only=False)
        _model_bolts = self.controller.get_data_from_bolts()
        _model_asteroids = self.controller.get_data_from_asteroids()

        # SET MINI MAP
        _w_ratio = _pixmap_minimap.width() / (PartyConst.WIDTH * 1.25)
        _h_ratio = _pixmap_minimap.height() / (PartyConst.HEIGHT * 1.25)

        _minimap_painter = QPainter(_pixmap_minimap)
        _minimap_painter.setOpacity(1)
        for _ship in _model_ships:
            _w = _ship.radius * _w_ratio
            if _w < 3:
                _w = 3
            _x, _y = int(
                _ship.x * _w_ratio) + _pixmap_minimap.width() // 2, int(
                    _ship.y * _h_ratio) + _pixmap_minimap.height() // 2

            if _ship.is_alive:
                _factor_1 = (time.time() * 2) % 2
                _factor_2 = (time.time() * 2 + .5) % 2

                _minimap_painter.setPen(
                    QPen(QColor('#ffffff'), 1, Qt.SolidLine))
                _minimap_painter.setOpacity(1 - _factor_1)
                _minimap_painter.drawEllipse(QPoint(_x, _y),
                                             int(20 * _factor_1),
                                             int(20 * _factor_1))
                _minimap_painter.setOpacity(1 - _factor_2)
                _minimap_painter.drawEllipse(QPoint(_x, _y),
                                             int(20 * _factor_2),
                                             int(20 * _factor_2))

            _minimap_painter.setPen(
                QPen(QColor(*_ship.color), _w, Qt.SolidLine))
            _minimap_painter.setOpacity(1)
            _minimap_painter.drawPoint(_x, _y)

        for _astroid in _model_asteroids:
            _w = _astroid.radius * _w_ratio
            if _w < 5:
                _w = 5
            _pen = QPen(QColor('#ffb86c'), _w, Qt.SolidLine)
            _pen.setCapStyle(Qt.RoundCap)
            _minimap_painter.setPen(_pen)
            _x, _y = int(
                _astroid.x * _w_ratio) + _pixmap_minimap.width() // 2, int(
                    _astroid.y * _h_ratio) + _pixmap_minimap.height() // 2
            _minimap_painter.drawPoint(_x, _y)
        for _bolt in _model_bolts:
            _w = _bolt.radius * _w_ratio
            if _w < 1:
                _w = 1
            _minimap_painter.setPen(QPen(QColor('#ff5555'), _w, Qt.SolidLine))
            _x, _y = int(
                _bolt.x * _w_ratio) + _pixmap_minimap.width() // 2, int(
                    _bolt.y * _h_ratio) + _pixmap_minimap.height() // 2
            _minimap_painter.drawPoint(_x, _y)

        _xy.setX(_xy.x() * _w_ratio + _pixmap_minimap.width() // 2)
        _xy.setY(_xy.y() * _h_ratio + _pixmap_minimap.height() // 2)

        _minimap_painter.setPen(QPen(QColor('#8be9fd'), 3, Qt.SolidLine))
        _minimap_painter.drawEllipse(_xy, _dz_radius * _w_ratio,
                                     _dz_radius * _h_ratio)

        if not is_full:
            _minimap_painter.setPen(QPen(QColor('#ffffff'), 1, Qt.SolidLine))
            _x = -self.camera_pst.x() * _w_ratio + _pixmap_minimap.width() // 2
            _y = self.camera_pst.y() * _h_ratio + _pixmap_minimap.height() // 2
            _w = self.width() * _w_ratio
            _h = self.height() * _h_ratio
            _minimap_painter.drawRect(_x, _y - _h, _w, _h)
        _minimap_painter.end()

        _pixmap_minimap = _pixmap_minimap.transformed(QTransform().scale(
            1, -1))

        painter.setOpacity(1 if is_full else .75)
        painter.drawPixmap(_p_origin, _pixmap_minimap)
Ejemplo n.º 22
0
 def draw(self, painter: QPainter):
     render_display(self.display, painter)
     pen = QPen()
     pen.setWidth(self.width // 50)
     pen.setCapStyle(Qt.PenCapStyle.RoundCap)
     painter.setPen(pen)
Ejemplo n.º 23
0
class Canvas(QWidget):
    content_changed = Signal()

    _background_color = QColor.fromRgb(0, 0, 0)
    _foreground_color = QColor.fromRgb(255, 255, 255)

    def __init__(self, parent, w, h, pen_width, scale):
        super().__init__(parent)
        self.w = w
        self.h = h
        self.scaled_w = scale * w
        self.scaled_h = scale * h
        self.scale = scale

        # Set size
        self.setFixedSize(self.scaled_w, self.scaled_h)

        # Create image
        self.small_image = QImage(self.w, self.h, QImage.Format_RGB32)
        self.small_image.fill(self._background_color)
        self.large_image = QImage(self.scaled_w, self.scaled_h,
                                  QImage.Format_RGB32)
        self.large_image.fill(self._background_color)

        # Create pen
        self.pen = QPen()
        self.pen.setColor(self._foreground_color)
        self.pen.setJoinStyle(Qt.RoundJoin)
        self.pen.setCapStyle(Qt.RoundCap)
        self.pen.setWidthF(scale * pen_width)

        # There is currently no path
        self.currentPath = None

        self.content_changed.connect(self.repaint)

    def _get_painter(self, paintee):
        painter = QPainter(paintee)
        painter.setPen(self.pen)
        painter.setRenderHint(QPainter.Antialiasing, True)
        return painter

    def _derive_small_image(self, large_image=None):
        if large_image is None:
            large_image = self.large_image
        # Downsample image
        self.small_image = large_image.scaled(self.w,
                                              self.h,
                                              mode=Qt.SmoothTransformation)
        self.content_changed.emit()

    def _current_path_updated(self, terminate_path=False):
        # Determine whether to draw on the large image directly or whether to make a temporary copy
        paintee = self.large_image if terminate_path else self.large_image.copy(
        )

        # Draw path on the large image of choice
        painter = self._get_painter(paintee)
        if self.currentPath.elementCount() != 1:
            painter.drawPath(self.currentPath)
        else:
            painter.drawPoint(self.currentPath.elementAt(0))
        painter.end()

        # Optionally terminate the path
        if terminate_path:
            self.currentPath = None

        # Downsample image
        self._derive_small_image(paintee)

    def _clear_image(self):
        self.large_image.fill(self._background_color)
        self._derive_small_image()

    def get_content(self):
        return np.asarray(self.small_image.constBits()).reshape(
            (self.h, self.w, -1))

    def set_content(self, image_rgb):
        for row in range(image_rgb.shape[0]):
            for col in range(image_rgb.shape[1]):
                self.small_image.setPixel(col, row, image_rgb[row, col])
        self.large_image = self.small_image.scaled(
            self.scaled_w, self.scaled_h, mode=Qt.SmoothTransformation)
        self._derive_small_image()
        self.content_changed.emit()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # Create new path
            self.currentPath = QPainterPath()
            self.currentPath.moveTo(event.pos())
            self._current_path_updated()

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) and self.currentPath is not None:
            # Add point to current path
            self.currentPath.lineTo(event.pos())
            self._current_path_updated()

    def mouseReleaseEvent(self, event):
        if (event.button() == Qt.LeftButton) and self.currentPath is not None:
            # Add terminal point to current path
            self.currentPath.lineTo(event.pos())
            self._current_path_updated(terminate_path=True)
        elif event.button() == Qt.RightButton:
            self._clear_image()

    def paintEvent(self, event):
        paint_rect = event.rect()  # Only paint the surface that needs painting
        painter = self._get_painter(self)

        # Draw image
        painter.scale(self.scale, self.scale)
        painter.drawImage(paint_rect, self.small_image, paint_rect)

        painter.end()

        painter = self._get_painter(self)

        #if self.currentPath is not None:
        #    painter.drawPath(self.currentPath)

    @Slot()
    def repaint(self):
        super().repaint()
Ejemplo n.º 24
0
class ImageSegmenterView(QGraphicsView):
    photoClicked = Signal(QPoint)

    def __init__(self, parent):
        super(ImageSegmenterView, self).__init__(parent)
        self._zoom = 0
        self.empty = True
        self._scene = QGraphicsScene(self)
        self._photo = QGraphicsPixmapItem()
        self.image_hidden = False
        self._seglayer = QGraphicsPixmapItem()
        self._seglayer.setOpacity(0.5)
        self._scene.addItem(self._photo)
        self._scene.addItem(self._seglayer)
        self.setScene(self._scene)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        # self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        # self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QBrush(QtCore.Qt.darkGray))
        self.setFrameShape(QFrame.NoFrame)

        self.seg_image = None
        self.start = False
        self.prev_point = None
        self.painter = None
        self.segmenter_pen = QPen(QtCore.Qt.green, 30, QtCore.Qt.SolidLine)
        self.segmenter_pen.setCapStyle(QtCore.Qt.RoundCap)
        self.segmenter_pen.setJoinStyle(QtCore.Qt.RoundJoin)
        self.erase = False
        self.changed = False

        self.history = collections.deque(maxlen=10)
        self.future = collections.deque(maxlen=10)

    def hasPhoto(self):
        return not self.empty

    def fitInView(self, scale=True):
        rect = QtCore.QRectF(self._photo.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
            if self.hasPhoto():
                unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
                self.scale(1 / unity.width(), 1 / unity.height())
                viewrect = self.viewport().rect()
                scenerect = self.transform().mapRect(rect)
                factor = min(viewrect.width() / scenerect.width(),
                             viewrect.height() / scenerect.height())
                self.scale(factor, factor)
            self._zoom = 0

    def setPhoto(self, pixmap=None):
        self._zoom = 0
        if pixmap and not pixmap.isNull():
            self.empty = False
            self.changed = False
            self._photo.setPixmap(pixmap)
            self.seg_image = QImage(pixmap.width(), pixmap.height(),
                                    QImage.Format_ARGB32_Premultiplied)
            self.seg_image.fill(QtCore.Qt.transparent)
            self._seglayer.setPixmap(QPixmap.fromImage(self.seg_image))
        else:
            self._empty = True
            self._photo.setPixmap(QPixmap())
        self.fitInView()

    def save_state(self):
        if self.future is not None:
            while len(self.future) > 0:
                present = self.future.pop()
                del present
        if self.seg_image is not None:
            self.history.append(self.seg_image.copy())

    def clear_history(self):
        while len(self.history) > 0:
            present = self.history.pop()
            del present

    def undo(self):
        if len(self.history) > 0:
            self.future.append(self.seg_image)
            present = self.history.pop()
            self.seg_image = present
            self._seglayer.setPixmap(QPixmap.fromImage(self.seg_image))

    def redo(self):
        if len(self.future) > 0:
            self.history.append(self.seg_image)
            present = self.future.pop()
            self.seg_image = present
            self._seglayer.setPixmap(QPixmap.fromImage(self.seg_image))

    def setSegLayer(self, pixmap=None):
        if not self._photo.pixmap().isNull():
            self.save_state()
            self.seg_image = QImage(pixmap.toImage())
            self._seglayer.setPixmap(QPixmap.fromImage(self.seg_image))

    def resetSegLayer(self):
        if not self._photo.pixmap().isNull():
            self.changed = True
            self.save_state()
            del self.seg_image
            self.seg_image = QImage(self._photo.pixmap().width(),
                                    self._photo.pixmap().height(),
                                    QImage.Format_ARGB32_Premultiplied)
            self.seg_image.fill(QtCore.Qt.transparent)
            self._seglayer.setPixmap(QPixmap.fromImage(self.seg_image))

    def wheelEvent(self, event):
        if self.hasPhoto() and not self.start:
            if event.angleDelta().y() > 0:
                factor = 1.25
                self._zoom += 1
            else:
                factor = 0.8
                self._zoom -= 1
            if self._zoom > 0:
                self.scale(factor, factor)
            elif self._zoom == 0:
                self.fitInView()
            else:
                self._zoom = 0

    def mousePressEvent(self, event):
        if not self._photo.pixmap().isNull():
            if event.button() == QtCore.Qt.LeftButton:
                self.save_state()
                self.start = True
                self.painter = QPainter(self.seg_image)
                if self.erase:
                    self.painter.setCompositionMode(
                        QPainter.CompositionMode_Clear)
                self.painter.setPen(self.segmenter_pen)
                self.paint_point(event.pos())
            elif event.button() == QtCore.Qt.RightButton:
                if not self._photo.pixmap().isNull():
                    self.setDragMode(QGraphicsView.ScrollHandDrag)
                    self.scroll_origin = self.mapToScene(event.pos())
                # if self._photo.isUnderMouse():
                #     self.photoClicked.emit(self.mapToScene(event.pos()).toPoint())
        super(ImageSegmenterView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if not self._photo.pixmap().isNull():
            if self.start:
                self.paint_point(event.pos())
            if event.buttons() & QtCore.Qt.RightButton:
                newpoint = self.mapToScene(event.pos())
                translation = newpoint - self.scroll_origin
                self.translate(translation.x(), translation.y())
                self.scroll_origin = self.mapToScene(event.pos())
        super(ImageSegmenterView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if not self._photo.pixmap().isNull():
            if self.start:
                self.start = False
                self.prev_point = None
                self.painter.end()
            if self.dragMode() == QGraphicsView.ScrollHandDrag:
                self.setDragMode(QGraphicsView.NoDrag)

    def paint_point(self, pos):
        self.changed = True
        pos = self.mapToScene(pos).toPoint()
        if self.prev_point is not None:
            self.painter.drawLine(self.prev_point, pos)
        else:
            self.painter.drawPoint(pos)
        self.prev_point = pos
        self._seglayer.setPixmap(QPixmap.fromImage(self.seg_image))

    def set_foreground(self):
        self.erase = False
        self.segmenter_pen.setColor(QtCore.Qt.green)

    def set_possible_foreground(self):
        self.erase = False
        self.segmenter_pen.setColor(QtCore.Qt.blue)

    def set_possible_background(self):
        self.erase = True
        self.segmenter_pen.setColor(QtCore.Qt.transparent)

    def set_background(self):
        self.erase = False
        self.segmenter_pen.setColor(QtCore.Qt.red)

    def set_pen_size(self, size):
        self.segmenter_pen.setWidth(size)

    def set_opacity(self, value):
        self._seglayer.setOpacity(value / 100)

    def hide_image(self):
        if self.image_hidden:
            self._photo.setOpacity(1)
            self.image_hidden = False
        else:
            self._photo.setOpacity(0)
            self.image_hidden = True
Ejemplo n.º 25
0
class Style:
    """A collection of sizes and fonts, as well as a default palette that is used to draw the items in the scheme."""

    class SizeMetric(Enum):
        """Various available size metrics.
        
        A size metric is a style dependent size represented by a single value. This enum contains a set of "keys", that
        can be used as arguments in `Style.inchMetric()` or `Style.pixelMetric()` to get the corresponding 
        values.
        """

        NodeFrameCornerRadius = 0
        """Rounded rectangle corner radius."""
        NodeFrameTextPadding = auto()
        """Padding for text inside the node body."""
        NodeDividerTextMargin = auto()
        """Margin between text and the title/description divider."""
        NodeMessagePadding = auto()
        """Padding between messages below the node."""
        NodeConnectionPadding = auto()
        """Padding between connections."""
        NodeFrameWidth = auto()
        """Width of the rounded rectangle frame."""
        NodeWidth = auto()
        """Body width."""
        
        EdgeWidth = 20
        """Width of the curved line. Also width of the connection stem."""
        EdgeBezierPointOffset = auto()
        """Max horizontal offset of control points on a bezier curve compared to its endpoints."""
        EdgeBezierCloseDistance = auto()
        """Distance that's considered "too close" by the bezier curve calculation algorithm. If distance between source 
        and target is less that this variable, control points are moved closer together.
        """
        EdgeDragPrecisionRadius = auto()
        """When starting drawing an edge, mouse pointer should be inside a circle, centered on the tip of a connection,
        and this radius."""

        ConnectionStemLength = 40
        """Length of the line going out of the node body."""
        ConnectionTextLength = auto()
        """Horizontal length of the box in which the text is drawn."""
        ConnectionStemTextMargin = auto()
        """Margin between the end of the stem and the node's description."""

        MessageIconSize = 60
        """Size of the icon (width and height). The icon is expected to be square."""
        MessageTextLength = auto()
        """Horizontal length of the box in which the text is drawn."""
        MessageIconTextMargin = auto()
        """Margin between the icon and the message's text."""

        PasteOffset = 80
        """Amount by which the selection should be shifted when pasted from clipboard."""

    class Font(Enum):
        """Various fonts used in the scheme items.
        
        This enum contains a set of "keys", that can be used as arguments in `Style.font()` to get 
        the corresponding values.
        """
        Default = 0
        """Default font for non-specific purposes."""

        NodeTitle = auto()
        """Font used in the node's title."""
        NodeDescription = auto()
        """Font used in the node's description."""
        ConnectionText = auto()
        """Font used in the connection's description."""
        MessageText = auto()
        """Font used in the message's text."""

    def __init__(self):
        """Constructs a Style."""
        SM = self.SizeMetric
        FT = self.Font

        self._inch_metric = {
            SM.NodeFrameCornerRadius: 0.1,
            SM.NodeFrameTextPadding: 0.1,
            SM.NodeDividerTextMargin: 0.05,
            SM.NodeMessagePadding: 0.05,
            SM.NodeConnectionPadding: 0.15,
            SM.NodeFrameWidth: 0.02,
            SM.NodeWidth: 2,
            
            SM.EdgeWidth: 0.02,
            SM.EdgeBezierPointOffset: 0.8,
            SM.EdgeBezierCloseDistance: 1.5,
            SM.EdgeDragPrecisionRadius: 0.1,

            SM.ConnectionStemLength: 0.2,
            SM.ConnectionTextLength: 1.5,
            SM.ConnectionStemTextMargin: 0.05,

            SM.MessageIconSize: 0.16,
            SM.MessageTextLength: 2.5,
            SM.MessageIconTextMargin: 0.05,

            SM.PasteOffset: 0.5
        }

        default_font = QFont("Segoe UI")
        default_font.setPointSizeF(10.5)

        title_font = QFont("Segoe UI Semibold")
        title_font.setPointSizeF(10.5)

        self._font = {
            FT.Default: default_font,
            FT.NodeTitle: title_font,
            FT.NodeDescription: QFont(default_font),
            FT.ConnectionText: QFont(default_font),
            FT.MessageText: QFont(default_font)
        }

        self._frame_pen = QPen()
        self._frame_pen.setCapStyle(Qt.PenCapStyle.FlatCap)
        self._frame_pen.setWidthF(self.pixelMetric(SM.NodeFrameWidth))
        
        self._edge_pen = QPen()
        self._edge_pen.setCapStyle(Qt.PenCapStyle.FlatCap)
        self._edge_pen.setWidthF(self.pixelMetric(SM.EdgeWidth))
    
    def framePen(self, palette: Palette) -> QPen:
        result = QPen(self._frame_pen)
        result.setColor(palette.color(Palette.Frame))

        return result
    
    def edgePen(self, palette: Palette) -> QPen:
        result = QPen(self._edge_pen)
        result.setColor(palette.color(Palette.Edge))

        return result

    def inchMetric(self, metric: SizeMetric, /):
        return self._inch_metric[metric]
    
    def pixelMetric(self, metric: SizeMetric, /):
        return px(self._inch_metric[metric])
    
    def font(self, which: Font, /):
        return self._font[which]