Snapshot/SnapshotFreehandGrabber.py

changeset 2993
4933ac9daa80
parent 2302
f29e9405c851
child 2997
7f0ef975da9e
equal deleted inserted replaced
2992:dbdf27746da5 2993:4933ac9daa80
6 """ 6 """
7 Module implementing a grabber widget for a freehand snapshot region. 7 Module implementing a grabber widget for a freehand snapshot region.
8 """ 8 """
9 9
10 from PyQt4.QtCore import pyqtSignal, Qt, QRect, QPoint, QTimer, qVersion 10 from PyQt4.QtCore import pyqtSignal, Qt, QRect, QPoint, QTimer, qVersion
11 from PyQt4.QtGui import QWidget, QPixmap, QColor, QRegion, QApplication, QPainter, \ 11 from PyQt4.QtGui import QWidget, QPixmap, QColor, QRegion, QApplication, \
12 QPalette, QToolTip, QPolygon, QPen, QBrush, QPaintEngine 12 QPainter, QPalette, QToolTip, QPolygon, QPen, QBrush, QPaintEngine
13 13
14 14
15 def drawPolygon(painter, polygon, outline, fill=QColor()): 15 def drawPolygon(painter, polygon, outline, fill=QColor()):
16 """ 16 """
17 Module function to draw a polygon with the given parameters. 17 Module function to draw a polygon with the given parameters.
61 self.__dragStartPoint = QPoint() 61 self.__dragStartPoint = QPoint()
62 self.__selectionBeforeDrag = QPolygon() 62 self.__selectionBeforeDrag = QPolygon()
63 63
64 self.__helpTextRect = QRect() 64 self.__helpTextRect = QRect()
65 self.__helpText = self.trUtf8( 65 self.__helpText = self.trUtf8(
66 "Select a region using the mouse. To take the snapshot, press the Enter key" 66 "Select a region using the mouse. To take the snapshot,"
67 " or double click. Press Esc to quit.") 67 " press the Enter key or double click. Press Esc to quit.")
68 68
69 self.__pixmap = QPixmap() 69 self.__pixmap = QPixmap()
70 self.__pBefore = QPoint() 70 self.__pBefore = QPoint()
71 71
72 self.setMouseTracking(True) 72 self.setMouseTracking(True)
117 painter.setFont(font) 117 painter.setFont(font)
118 118
119 pol = QPolygon(self.__selection) 119 pol = QPolygon(self.__selection)
120 if not self.__selection.boundingRect().isNull(): 120 if not self.__selection.boundingRect().isNull():
121 # Draw outline around selection. 121 # Draw outline around selection.
122 # Important: the 1px-wide outline is *also* part of the captured free-region 122 # Important: the 1px-wide outline is *also* part of the
123 # captured free-region
123 pen = QPen(handleColor, 1, Qt.SolidLine, Qt.SquareCap, Qt.BevelJoin) 124 pen = QPen(handleColor, 1, Qt.SolidLine, Qt.SquareCap, Qt.BevelJoin)
124 painter.setPen(pen) 125 painter.setPen(pen)
125 painter.drawPolygon(pol) 126 painter.drawPolygon(pol)
126 127
127 # Draw the grey area around the selection. 128 # Draw the grey area around the selection.
135 drawPolygon(painter, pol, handleColor) 136 drawPolygon(painter, pol, handleColor)
136 137
137 if self.__showHelp: 138 if self.__showHelp:
138 painter.setPen(textColor) 139 painter.setPen(textColor)
139 painter.setBrush(textBackgroundColor) 140 painter.setBrush(textBackgroundColor)
140 self.__helpTextRect = painter.boundingRect(self.rect().adjusted(2, 2, -2, -2), 141 self.__helpTextRect = painter.boundingRect(
142 self.rect().adjusted(2, 2, -2, -2),
141 Qt.TextWordWrap, self.__helpText).translated( 143 Qt.TextWordWrap, self.__helpText).translated(
142 -self.__desktop.x(), -self.__desktop.y()) 144 -self.__desktop.x(), -self.__desktop.y())
143 self.__helpTextRect.adjust(-2, -2, 4, 2) 145 self.__helpTextRect.adjust(-2, -2, 4, 2)
144 drawPolygon(painter, self.__helpTextRect, textColor, textBackgroundColor) 146 drawPolygon(painter, self.__helpTextRect, textColor,
147 textBackgroundColor)
145 painter.drawText(self.__helpTextRect.adjusted(3, 3, -3, -3), 148 painter.drawText(self.__helpTextRect.adjusted(3, 3, -3, -3),
146 Qt.TextWordWrap, self.__helpText) 149 Qt.TextWordWrap, self.__helpText)
147 150
148 if self.__selection.isEmpty(): 151 if self.__selection.isEmpty():
149 return 152 return
150 153
151 # The grabbed region is everything which is covered by the drawn 154 # The grabbed region is everything which is covered by the drawn
152 # rectangles (border included). This means that there is no 0px 155 # rectangles (border included). This means that there is no 0px
153 # selection, since a 0px wide rectangle will always be drawn as a line. 156 # selection, since a 0px wide rectangle will always be drawn as a line.
154 boundingRect = self.__selection.boundingRect() 157 boundingRect = self.__selection.boundingRect()
155 txt = "{0:n}, {1:n} ({2:n} x {3:n})".format(boundingRect.x(), boundingRect.y(), 158 txt = "{0:n}, {1:n} ({2:n} x {3:n})".format(
159 boundingRect.x(), boundingRect.y(),
156 boundingRect.width(), boundingRect.height()) 160 boundingRect.width(), boundingRect.height())
157 textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt) 161 textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
158 boundingRect = textRect.adjusted(-4, 0, 0, 0) 162 boundingRect = textRect.adjusted(-4, 0, 0, 0)
159 163
160 polBoundingRect = pol.boundingRect() 164 polBoundingRect = pol.boundingRect()
161 if textRect.width() < polBoundingRect.width() - 2 * self.__handleSize and \ 165 if (textRect.width() <
162 textRect.height() < polBoundingRect.height() - 2 * self.__handleSize and \ 166 polBoundingRect.width() - 2 * self.__handleSize) and \
167 (textRect.height() <
168 polBoundingRect.height() - 2 * self.__handleSize) and \
163 polBoundingRect.width() > 100 and \ 169 polBoundingRect.width() > 100 and \
164 polBoundingRect.height() > 100: 170 polBoundingRect.height() > 100:
165 # center, unsuitable for small selections 171 # center, unsuitable for small selections
166 boundingRect.moveCenter(polBoundingRect.center()) 172 boundingRect.moveCenter(polBoundingRect.center())
167 textRect.moveCenter(polBoundingRect.center()) 173 textRect.moveCenter(polBoundingRect.center())
176 # left, top aligned 182 # left, top aligned
177 boundingRect.moveTopRight( 183 boundingRect.moveTopRight(
178 QPoint(polBoundingRect.x() - 3, polBoundingRect.y())) 184 QPoint(polBoundingRect.x() - 3, polBoundingRect.y()))
179 textRect.moveTopRight( 185 textRect.moveTopRight(
180 QPoint(polBoundingRect.x() - 5, polBoundingRect.y())) 186 QPoint(polBoundingRect.x() - 5, polBoundingRect.y()))
181 elif polBoundingRect.bottom() + 3 + textRect.height() < self.rect().bottom() and \ 187 elif (polBoundingRect.bottom() + 3 + textRect.height() <
188 self.rect().bottom()) and \
182 polBoundingRect.right() > textRect.width(): 189 polBoundingRect.right() > textRect.width():
183 # at bottom, right aligned 190 # at bottom, right aligned
184 boundingRect.moveTopRight( 191 boundingRect.moveTopRight(
185 QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3)) 192 QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3))
186 textRect.moveTopRight( 193 textRect.moveTopRight(
187 QPoint(polBoundingRect.right() - 2, polBoundingRect.bottom() + 3)) 194 QPoint(polBoundingRect.right() - 2,
188 elif polBoundingRect.right() + textRect.width() + 3 < self.rect().width(): 195 polBoundingRect.bottom() + 3))
196 elif polBoundingRect.right() + textRect.width() + 3 < \
197 self.rect().width():
189 # right, bottom aligned 198 # right, bottom aligned
190 boundingRect.moveBottomLeft( 199 boundingRect.moveBottomLeft(
191 QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom())) 200 QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom()))
192 textRect.moveBottomLeft( 201 textRect.moveBottomLeft(
193 QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom())) 202 QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom()))
194 203
195 # If the above didn't catch it, you are running on a very tiny screen... 204 # If the above didn't catch it, you are running on a very
205 # tiny screen...
196 drawPolygon(painter, boundingRect, textColor, textBackgroundColor) 206 drawPolygon(painter, boundingRect, textColor, textBackgroundColor)
197 painter.drawText(textRect, Qt.AlignHCenter, txt) 207 painter.drawText(textRect, Qt.AlignHCenter, txt)
198 208
199 if (polBoundingRect.height() > self.__handleSize * 2 and \ 209 if (polBoundingRect.height() > self.__handleSize * 2 and \
200 polBoundingRect.width() > self.__handleSize * 2) or \ 210 polBoundingRect.width() > self.__handleSize * 2) or \
243 p = evt.pos() 253 p = evt.pos()
244 self.__selection.append(p) 254 self.__selection.append(p)
245 else: 255 else:
246 # moving the whole selection 256 # moving the whole selection
247 p = evt.pos() - self.__pBefore # Offset 257 p = evt.pos() - self.__pBefore # Offset
248 self.__pBefore = evt.pos() # save position for next iteration 258 self.__pBefore = evt.pos() # save position for
259 # next iteration
249 self.__selection.translate(p) 260 self.__selection.translate(p)
250 261
251 self.update() 262 self.update()
252 else: 263 else:
253 if self.__selection.boundingRect().isEmpty(): 264 if self.__selection.boundingRect().isEmpty():
307 pixmap2.fill(Qt.transparent) 318 pixmap2.fill(Qt.transparent)
308 319
309 pt = QPainter() 320 pt = QPainter()
310 pt.begin(pixmap2) 321 pt.begin(pixmap2)
311 if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff): 322 if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
312 pt.setRenderHints(QPainter.Antialiasing | \ 323 pt.setRenderHints(
313 QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform, 324 QPainter.Antialiasing | \
325 QPainter.HighQualityAntialiasing | \
326 QPainter.SmoothPixmapTransform,
314 True) 327 True)
315 pt.setBrush(Qt.black) 328 pt.setBrush(Qt.black)
316 pt.setPen(QPen(QBrush(Qt.black), 0.5)) 329 pt.setPen(QPen(QBrush(Qt.black), 0.5))
317 pt.drawPolygon(translatedPol) 330 pt.drawPolygon(translatedPol)
318 pt.setCompositionMode(QPainter.CompositionMode_SourceIn) 331 pt.setCompositionMode(QPainter.CompositionMode_SourceIn)

eric ide

mercurial