1from PyQt5.QtCore import Qt, QPointF
2from PyQt5.QtGui import QColor, QPen, QTransform
3from PyQt5.QtWidgets import QGraphicsRectItem
4
5
6class Selection(QGraphicsRectItem):
7    def __init__(self, *args, fillcolor, opacity, parent=None):
8        if len(args) == 0:
9            super().__init__(parent)
10        elif len(args) == 1:
11            super().__init__(args[0], parent)
12        elif len(args) == 4:
13            x0, y0, w, h = args
14            super().__init__(x0, y0, w, h, parent)
15
16        self.finished = False
17        self.selected_edge = None  # type: int
18        self.resizing = False
19
20        self.setBrush(fillcolor)
21        self.setPen(QPen(QColor(Qt.transparent), 0))
22        self.setOpacity(opacity)
23
24    @property
25    def is_empty(self) -> bool:
26        raise NotImplementedError("Overwrite in subclass")
27
28    @property
29    def width(self):
30        return self.rect().width()
31
32    @width.setter
33    def width(self, value):
34        if value == self.width:
35            return
36
37        r = self.rect()
38        r.setWidth(value)
39        self.setRect(r)
40
41    @property
42    def height(self):
43        return self.rect().height()
44
45    @height.setter
46    def height(self, value):
47        if value == self.height:
48            return
49
50        r = self.rect()
51        r.setHeight(value)
52        self.setRect(r)
53
54    @property
55    def x(self):
56        return self.rect().x()
57
58    def setX(self, p_float):
59        if p_float == self.x:
60            return
61
62        r = self.rect()
63        r.setX(p_float)
64        self.setRect(r)
65
66    @property
67    def y(self):
68        return self.rect().y()
69
70    def setY(self, p_float):
71        if p_float == self.y:
72            return
73
74        r = self.rect()
75        r.setY(p_float)
76        self.setRect(r)
77
78    @property
79    def start(self):
80        raise NotImplementedError("Overwrite in subclass")
81
82    @start.setter
83    def start(self, value):
84        raise NotImplementedError("Overwrite in subclass")
85
86    @property
87    def end(self):
88        raise NotImplementedError("Overwrite in subclass")
89
90    @end.setter
91    def end(self, value):
92        raise NotImplementedError("Overwrite in subclass")
93
94    def _get_selected_edge(self, pos: QPointF, transform: QTransform, horizontal_selection: bool):
95        x1, x2 = self.x, self.x + self.width
96        y1, y2 = self.y, self.y + self.height
97        x, y = pos.x(), pos.y()
98
99        spacing = 5
100        spacing /= transform.m11() if horizontal_selection else transform.m22()
101
102        if horizontal_selection:
103            x1a, x1b = x1 - spacing, x1 + spacing
104            y1a, y1b = y1, y2
105            x2a, x2b = x2 - spacing, x2 + spacing
106            y2a, y2b = y1, y2
107        else:
108            x1a, x1b, x2a, x2b = x1, x2, x1, x2
109            y1a, y1b = min(y1 - spacing, y1 + spacing), max(y1 - spacing, y1 + spacing)
110            y2a, y2b = min(y2 - spacing, y2 + spacing), max(y2 - spacing, y2 + spacing)
111
112        if x1a < x < x1b and y1a < y < y1b:
113            self.selected_edge = 0
114            return 0
115
116        if x2a < x < x2b and y2a < y < y2b:
117            self.selected_edge = 1
118            return 1
119
120        self.selected_edge = None
121        return None
122
123    def clear(self):
124        self.resizing = False
125        self.selected_edge = None
126        self.finished = False
127