eric7/EricWidgets/EricIconBar.py

branch
eric7
changeset 8583
aac629a05f8b
child 8584
90391fda03d5
equal deleted inserted replaced
8582:ae6032e4b4ef 8583:aac629a05f8b
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a bar widget showing just icons.
8 """
9
10 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt
11 from PyQt6.QtGui import QColor
12 from PyQt6.QtWidgets import QWidget, QBoxLayout, QWIDGETSIZE_MAX
13
14 from .EricClickableLabel import EricClickableLabel
15
16
17 class EricIconBar(QWidget):
18 """
19 Class implementing a bar widget showing just icons.
20
21 @signal currentChanged(index) emitted to indicate a change of the current
22 index
23 @signal currentClicked(index) emitted to indicate, that the current icon
24 was clicked
25 """
26 IconSize = 48
27 BorderSize = 2
28
29 WidgetStyleSheetTemplate = "QWidget {{ background-color: {0}; }}"
30 LabelStyleSheetTemplate = "QLabel {{ background-color: {0}; }}"
31
32 currentChanged = pyqtSignal(int)
33 currentClicked = pyqtSignal(int)
34
35 def __init__(self, orientation=Qt.Orientation.Horizontal, parent=None):
36 """
37 Constructor
38
39 @param orientation orientation for the widget
40 @type Qt.Orientation
41 @param parent reference to the parent widget (defaults to None)
42 @type QWidget (optional)
43 """
44 super().__init__(parent)
45
46 self.__fixedHeightWidth = (
47 EricIconBar.IconSize + 2 * EricIconBar.BorderSize
48 )
49
50 # set initial values
51 self.__color = QColor("#008800")
52 self.__orientation = Qt.Orientation.Horizontal
53 self.__currentIndex = -1
54
55 # initialize with horizontal layout and change later if needed
56 self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
57 self.setFixedHeight(self.__fixedHeightWidth)
58
59 self.__layout = QBoxLayout(QBoxLayout.Direction.LeftToRight)
60 self.__layout.setContentsMargins(
61 EricIconBar.BorderSize, EricIconBar.BorderSize,
62 EricIconBar.BorderSize, EricIconBar.BorderSize)
63 self.__layout.setSpacing(EricIconBar.BorderSize)
64
65 self.__layout.addStretch()
66
67 self.setLayout(self.__layout)
68
69 if orientation != self.__orientation:
70 self.setOrientation(orientation)
71
72 self.setColor(self.__color)
73
74 def setOrientation(self, orientation):
75 """
76 Public method to set the widget orientation.
77
78 @param orientation orientation to be set
79 @type Qt.Orientation
80 """
81 # reset list widget size constraints
82 self.setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
83
84 if orientation == Qt.Orientation.Horizontal:
85 self.setFixedHeight(self.__fixedHeightWidth)
86 self.__layout.setDirection(QBoxLayout.Direction.LeftToRight)
87 elif orientation == Qt.Orientation.Vertical:
88 self.setFixedWidth(self.__fixedHeightWidth)
89 self.__layout.setDirection(QBoxLayout.Direction.TopToBottom)
90
91 self.__orientation = orientation
92
93 def orientation(self):
94 """
95 Public method to get the orientation of the widget.
96
97 @return orientation of the widget
98 @rtype Qt.Orientation
99 """
100 return self.__orientation
101
102 def setColor(self, color):
103 """
104 Public method to set the color of the widget.
105
106 @param color color of the widget
107 @type QColor
108 """
109 self.__color = color
110 self.__highlightColor = color.darker()
111
112 self.setStyleSheet(
113 EricIconBar.WidgetStyleSheetTemplate.format(color.name()))
114
115 label = self.__layout.itemAt(self.__currentIndex)
116 if label:
117 label.widget().setStyleSheet(
118 EricIconBar.LabelStyleSheetTemplate
119 .format(self.__highlightColor.name())
120 )
121
122 def color(self):
123 """
124 Public method to return the current color.
125
126 @return current color
127 @rtype QColor
128 """
129 return self.__color
130
131 def __createIcon(self, iconPixmap, label=""):
132 """
133 Private method to creat an icon label.
134
135 @param iconPixmap reference to the icon
136 @type QPixmap
137 @param label label text to be shown as a tooltip (defaults to "")
138 @type str (optional)
139 @return created and connected label
140 @rtype EricClickableLabel
141 """
142 iconLabel = EricClickableLabel(self)
143 iconLabel.setFixedSize(EricIconBar.IconSize, EricIconBar.IconSize)
144 iconLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
145 iconLabel.setPixmap(iconPixmap)
146 if label:
147 iconLabel.setToolTip(label)
148
149 iconLabel.clicked.connect(lambda: self.__iconClicked(iconLabel))
150
151 return iconLabel
152
153 def addIcon(self, iconPixmap, label=""):
154 """
155 Public method to add an icon to the bar.
156
157 @param iconPixmap reference to the icon
158 @type QPixmap
159 @param label label text to be shown as a tooltip (defaults to "")
160 @type str (optional)
161 """
162 # the stretch item is always the last one
163 self.insertIcon(self.count(), iconPixmap, label=label)
164
165 def insertIcon(self, index, iconPixmap, label=""):
166 """
167 Public method to insert an icon into the bar.
168
169 @param index position to insert the icon at
170 @type int
171 @param iconPixmap reference to the icon
172 @type QPixmap
173 @param label label text to be shown as a tooltip (defaults to "")
174 @type str (optional)
175 """
176 iconLabel = self.__createIcon(iconPixmap, label=label)
177 self.__layout.insertWidget(index, iconLabel)
178
179 if self.__currentIndex < 0:
180 self.setCurrentIndex(index)
181 elif index <= self.__currentIndex:
182 self.setCurrentIndex(self.__currentIndex + 1)
183
184 def removeIcon(self, index):
185 """
186 Public method to remove an icon from the bar.
187
188 @param index index of the icon to be removed
189 @type int
190 """
191 label = self.__layout.itemAt(index)
192 self.__layout.removeWidget(label)
193
194 if index == self.__currentIndex:
195 self.setCurrentIndex(index)
196 elif index < self.__currentIndex:
197 self.setCurrentIndex(self.__currentIndex - 1)
198
199 @pyqtSlot()
200 def __iconClicked(self, label):
201 """
202 Private slot to handle an icon been clicked.
203
204 @param label reference to the clicked label
205 @type EricClickableLabel
206 """
207 index = self.__layout.indexOf(label)
208 if index == self.__currentIndex:
209 self.currentClicked.emit(self.__currentIndex)
210 else:
211 self.setCurrentIndex(index)
212
213 def setCurrentIndex(self, index):
214 """
215 Public method to set the current index.
216
217 @param index current index to be set
218 @type int
219 """
220 if index >= self.count():
221 index = -1
222
223 if index != self.__currentIndex:
224 # reset style of previous current icon
225 oldLabel = self.__layout.itemAt(self.__currentIndex)
226 if oldLabel:
227 oldLabel.widget().setStyleSheet("")
228
229 # set style of new current icon
230 newLabel = self.__layout.itemAt(index)
231 if newLabel:
232 newLabel.widget().setStyleSheet(
233 EricIconBar.LabelStyleSheetTemplate
234 .format(self.__highlightColor.name())
235 )
236
237 self.__currentIndex = index
238 self.currentChanged.emit(self.__currentIndex)
239
240 def currentIndex(self):
241 """
242 Public method to get the current index.
243
244 @return current index
245 @rtype int
246 """
247 return self.__currentIndex
248
249 def count(self):
250 """
251 Public method to get the number of icon labels.
252
253 @return number of icon labels
254 @rtype int
255 """
256 return self.__layout.count() - 1
257
258 def wheelEvent(self, evt):
259 """
260 Protected method to handle a wheel event.
261
262 @param evt reference to the wheel event
263 @type QWheelEvent
264 """
265 delta = evt.angleDelta().y()
266 if delta > 0:
267 self.previousIcon()
268 else:
269 self.nextIcon()
270
271 @pyqtSlot()
272 def previousIcon(self):
273 """
274 Public slot to set the icon before the current one.
275 """
276 index = self.__currentIndex - 1
277 if index < 0:
278 # wrap around
279 index = self.count() - 1
280
281 self.setCurrentIndex(index)
282
283 @pyqtSlot()
284 def nextIcon(self):
285 """
286 Public slot to set the icon after the current one.
287 """
288 index = self.__currentIndex + 1
289 if index == self.count():
290 # wrap around
291 index = 0
292
293 self.setCurrentIndex(index)

eric ide

mercurial