207 """ |
210 """ |
208 Private method to initialize texts to be associated with undo commands |
211 Private method to initialize texts to be associated with undo commands |
209 for the various drawing tools. |
212 for the various drawing tools. |
210 """ |
213 """ |
211 self.__undoTexts = { |
214 self.__undoTexts = { |
212 self.Pencil: self.tr("Set Pixel"), |
215 IconEditorTool.PENCIL: self.tr("Set Pixel"), |
213 self.Rubber: self.tr("Erase Pixel"), |
216 IconEditorTool.RUBBER: self.tr("Erase Pixel"), |
214 self.Line: self.tr("Draw Line"), |
217 IconEditorTool.LINE: self.tr("Draw Line"), |
215 self.Rectangle: self.tr("Draw Rectangle"), |
218 IconEditorTool.RECTANGLE: self.tr("Draw Rectangle"), |
216 self.FilledRectangle: self.tr("Draw Filled Rectangle"), |
219 IconEditorTool.FILLED_RECTANGLE: self.tr("Draw Filled Rectangle"), |
217 self.Circle: self.tr("Draw Circle"), |
220 IconEditorTool.CIRCLE: self.tr("Draw Circle"), |
218 self.FilledCircle: self.tr("Draw Filled Circle"), |
221 IconEditorTool.FILLED_CIRCLE: self.tr("Draw Filled Circle"), |
219 self.Ellipse: self.tr("Draw Ellipse"), |
222 IconEditorTool.ELLIPSE: self.tr("Draw Ellipse"), |
220 self.FilledEllipse: self.tr("Draw Filled Ellipse"), |
223 IconEditorTool.FILLED_ELLIPSE: self.tr("Draw Filled Ellipse"), |
221 self.Fill: self.tr("Fill Region"), |
224 IconEditorTool.FILL: self.tr("Fill Region"), |
222 } |
225 } |
223 |
226 |
224 def isDirty(self): |
227 def isDirty(self): |
225 """ |
228 """ |
226 Public method to check the dirty status. |
229 Public method to check the dirty status. |
290 def setTool(self, tool): |
293 def setTool(self, tool): |
291 """ |
294 """ |
292 Public method to set the current drawing tool. |
295 Public method to set the current drawing tool. |
293 |
296 |
294 @param tool drawing tool to be used |
297 @param tool drawing tool to be used |
295 (IconEditorGrid.Pencil ... IconEditorGrid.CircleSelection) |
298 @type IconEditorTool |
296 """ |
299 """ |
297 self.__curTool = tool |
300 self.__curTool = tool |
298 self.__lastPos = (-1, -1) |
301 self.__lastPos = (-1, -1) |
299 |
302 |
300 if self.__curTool in [self.RectangleSelection, self.CircleSelection]: |
303 if self.__curTool in [ |
|
304 IconEditorTool.SELECT_RECTANGLE, IconEditorTool.SELECT_CIRCLE |
|
305 ]: |
301 self.__selecting = True |
306 self.__selecting = True |
302 else: |
307 else: |
303 self.__selecting = False |
308 self.__selecting = False |
304 |
309 |
305 if self.__curTool in [self.RectangleSelection, self.CircleSelection, |
310 if self.__curTool in [ |
306 self.Line, self.Rectangle, self.FilledRectangle, |
311 IconEditorTool.SELECT_RECTANGLE, IconEditorTool.SELECT_CIRCLE, |
307 self.Circle, self.FilledCircle, |
312 IconEditorTool.LINE, |
308 self.Ellipse, self.FilledEllipse]: |
313 IconEditorTool.RECTANGLE, IconEditorTool.FILLED_RECTANGLE, |
|
314 IconEditorTool.CIRCLE, IconEditorTool.FILLED_CIRCLE, |
|
315 IconEditorTool.ELLIPSE, IconEditorTool.FILLED_ELLIPSE |
|
316 ]: |
309 self.setCursor(self.__aimCursor) |
317 self.setCursor(self.__aimCursor) |
310 elif self.__curTool == self.Fill: |
318 elif self.__curTool == IconEditorTool.FILL: |
311 self.setCursor(self.__fillCursor) |
319 self.setCursor(self.__fillCursor) |
312 elif self.__curTool == self.ColorPicker: |
320 elif self.__curTool == IconEditorTool.COLOR_PICKER: |
313 self.setCursor(self.__colorPickerCursor) |
321 self.setCursor(self.__colorPickerCursor) |
314 elif self.__curTool == self.Pencil: |
322 elif self.__curTool == IconEditorTool.PENCIL: |
315 self.setCursor(self.__paintCursor) |
323 self.setCursor(self.__paintCursor) |
316 elif self.__curTool == self.Rubber: |
324 elif self.__curTool == IconEditorTool.RUBBER: |
317 self.setCursor(self.__rubberCursor) |
325 self.setCursor(self.__rubberCursor) |
318 else: |
326 else: |
319 self.setCursor(self.__normalCursor) |
327 self.setCursor(self.__normalCursor) |
320 |
328 |
321 def tool(self): |
329 def tool(self): |
322 """ |
330 """ |
323 Public method to get the current drawing tool. |
331 Public method to get the current drawing tool. |
324 |
332 |
325 @return current drawing tool |
333 @return current drawing tool |
326 (IconEditorGrid.Pencil ... IconEditorGrid.CircleSelection) |
334 @rtype IconEditorTool |
327 """ |
335 """ |
328 return self.__curTool |
336 return self.__curTool |
329 |
337 |
330 def setIconImage(self, newImage, undoRedo=False, clearUndo=False): |
338 def setIconImage(self, newImage, undoRedo=False, clearUndo=False): |
331 """ |
339 """ |
480 self.__markImage.fill(self.NoMarkColor.rgba()) |
488 self.__markImage.fill(self.NoMarkColor.rgba()) |
481 self.update(self.__pasteRect) |
489 self.update(self.__pasteRect) |
482 self.__pasteRect = QRect() |
490 self.__pasteRect = QRect() |
483 return |
491 return |
484 |
492 |
485 if self.__curTool == self.Pencil: |
493 if self.__curTool == IconEditorTool.PENCIL: |
486 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
494 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
487 self.__image) |
495 self.__image) |
488 self.__setImagePixel(evt.position().toPoint(), True) |
496 self.__setImagePixel(evt.position().toPoint(), True) |
489 self.setDirty(True) |
497 self.setDirty(True) |
490 self.__undoStack.push(cmd) |
498 self.__undoStack.push(cmd) |
491 self.__currentUndoCmd = cmd |
499 self.__currentUndoCmd = cmd |
492 elif self.__curTool == self.Rubber: |
500 elif self.__curTool == IconEditorTool.RUBBER: |
493 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
501 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
494 self.__image) |
502 self.__image) |
495 self.__setImagePixel(evt.position().toPoint(), False) |
503 self.__setImagePixel(evt.position().toPoint(), False) |
496 self.setDirty(True) |
504 self.setDirty(True) |
497 self.__undoStack.push(cmd) |
505 self.__undoStack.push(cmd) |
498 self.__currentUndoCmd = cmd |
506 self.__currentUndoCmd = cmd |
499 elif self.__curTool == self.Fill: |
507 elif self.__curTool == IconEditorTool.FILL: |
500 i, j = self.__imageCoordinates(evt.position().toPoint()) |
508 i, j = self.__imageCoordinates(evt.position().toPoint()) |
501 col = QColor() |
509 col = QColor() |
502 col.setRgba(self.__image.pixel(i, j)) |
510 col.setRgba(self.__image.pixel(i, j)) |
503 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
511 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
504 self.__image) |
512 self.__image) |
505 self.__drawFlood(i, j, col) |
513 self.__drawFlood(i, j, col) |
506 self.setDirty(True) |
514 self.setDirty(True) |
507 self.__undoStack.push(cmd) |
515 self.__undoStack.push(cmd) |
508 cmd.setAfterImage(self.__image) |
516 cmd.setAfterImage(self.__image) |
509 elif self.__curTool == self.ColorPicker: |
517 elif self.__curTool == IconEditorTool.COLOR_PICKER: |
510 i, j = self.__imageCoordinates(evt.position().toPoint()) |
518 i, j = self.__imageCoordinates(evt.position().toPoint()) |
511 col = QColor() |
519 col = QColor() |
512 col.setRgba(self.__image.pixel(i, j)) |
520 col.setRgba(self.__image.pixel(i, j)) |
513 self.setPenColor(col) |
521 self.setPenColor(col) |
514 else: |
522 else: |
520 """ |
528 """ |
521 Protected method to handle mouse move events. |
529 Protected method to handle mouse move events. |
522 |
530 |
523 @param evt reference to the mouse event object (QMouseEvent) |
531 @param evt reference to the mouse event object (QMouseEvent) |
524 """ |
532 """ |
525 self.positionChanged.emit(*self.__imageCoordinates(evt.position().toPoint())) |
533 self.positionChanged.emit( |
|
534 *self.__imageCoordinates(evt.position().toPoint())) |
526 |
535 |
527 if ( |
536 if ( |
528 self.__isPasting and |
537 self.__isPasting and |
529 not (evt.buttons() & Qt.MouseButton.LeftButton) |
538 not (evt.buttons() & Qt.MouseButton.LeftButton) |
530 ): |
539 ): |
531 self.__drawPasteRect(evt.position().toPoint()) |
540 self.__drawPasteRect(evt.position().toPoint()) |
532 return |
541 return |
533 |
542 |
534 if evt.buttons() & Qt.MouseButton.LeftButton: |
543 if evt.buttons() & Qt.MouseButton.LeftButton: |
535 if self.__curTool == self.Pencil: |
544 if self.__curTool == IconEditorTool.PENCIL: |
536 self.__setImagePixel(evt.position().toPoint(), True) |
545 self.__setImagePixel(evt.position().toPoint(), True) |
537 self.setDirty(True) |
546 self.setDirty(True) |
538 elif self.__curTool == self.Rubber: |
547 elif self.__curTool == IconEditorTool.RUBBER: |
539 self.__setImagePixel(evt.position().toPoint(), False) |
548 self.__setImagePixel(evt.position().toPoint(), False) |
540 self.setDirty(True) |
549 self.setDirty(True) |
541 elif self.__curTool in [self.Fill, self.ColorPicker]: |
550 elif self.__curTool in [IconEditorTool.FILL, |
|
551 IconEditorTool.COLOR_PICKER]: |
542 pass # do nothing |
552 pass # do nothing |
543 else: |
553 else: |
544 self.__drawTool(evt.position().toPoint(), True) |
554 self.__drawTool(evt.position().toPoint(), True) |
545 |
555 |
546 def mouseReleaseEvent(self, evt): |
556 def mouseReleaseEvent(self, evt): |
549 |
559 |
550 @param evt reference to the mouse event object (QMouseEvent) |
560 @param evt reference to the mouse event object (QMouseEvent) |
551 """ |
561 """ |
552 if evt.button() == Qt.MouseButton.LeftButton: |
562 if evt.button() == Qt.MouseButton.LeftButton: |
553 if ( |
563 if ( |
554 self.__curTool in [self.Pencil, self.Rubber] and |
564 self.__curTool in [IconEditorTool.PENCIL, |
|
565 IconEditorTool.RUBBER] and |
555 self.__currentUndoCmd |
566 self.__currentUndoCmd |
556 ): |
567 ): |
557 self.__currentUndoCmd.setAfterImage(self.__image) |
568 self.__currentUndoCmd.setAfterImage(self.__image) |
558 self.__currentUndoCmd = None |
569 self.__currentUndoCmd = None |
559 |
570 |
560 if self.__curTool not in [self.Pencil, self.Rubber, |
571 if self.__curTool not in [ |
561 self.Fill, self.ColorPicker, |
572 IconEditorTool.PENCIL, IconEditorTool.RUBBER, |
562 self.RectangleSelection, |
573 IconEditorTool.FILL, IconEditorTool.COLOR_PICKER, |
563 self.CircleSelection]: |
574 IconEditorTool.SELECT_RECTANGLE, IconEditorTool.SELECT_CIRCLE |
|
575 ]: |
564 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
576 cmd = IconEditCommand(self, self.__undoTexts[self.__curTool], |
565 self.__image) |
577 self.__image) |
566 if self.__drawTool(evt.position().toPoint(), False): |
578 if self.__drawTool(evt.position().toPoint(), False): |
567 self.__undoStack.push(cmd) |
579 self.__undoStack.push(cmd) |
568 cmd.setAfterImage(self.__image) |
580 cmd.setAfterImage(self.__image) |
659 |
671 |
660 painter = QPainter(img) |
672 painter = QPainter(img) |
661 painter.setPen(drawColor) |
673 painter.setPen(drawColor) |
662 painter.setCompositionMode(self.__compositingMode) |
674 painter.setCompositionMode(self.__compositingMode) |
663 |
675 |
664 if self.__curTool == self.Line: |
676 if self.__curTool == IconEditorTool.LINE: |
665 painter.drawLine(start, end) |
677 painter.drawLine(start, end) |
666 |
678 |
667 elif self.__curTool in [self.Rectangle, self.FilledRectangle, |
679 elif self.__curTool in [ |
668 self.RectangleSelection]: |
680 IconEditorTool.RECTANGLE, IconEditorTool.FILLED_RECTANGLE, |
|
681 IconEditorTool.SELECT_RECTANGLE |
|
682 ]: |
669 left = min(start.x(), end.x()) |
683 left = min(start.x(), end.x()) |
670 top = min(start.y(), end.y()) |
684 top = min(start.y(), end.y()) |
671 right = max(start.x(), end.x()) |
685 right = max(start.x(), end.x()) |
672 bottom = max(start.y(), end.y()) |
686 bottom = max(start.y(), end.y()) |
673 if self.__curTool == self.RectangleSelection: |
687 if self.__curTool == IconEditorTool.SELECT_RECTANGLE: |
674 painter.setBrush(QBrush(drawColor)) |
688 painter.setBrush(QBrush(drawColor)) |
675 if self.__curTool == self.FilledRectangle: |
689 if self.__curTool == IconEditorTool.FILLED_RECTANGLE: |
676 for y in range(top, bottom + 1): |
690 for y in range(top, bottom + 1): |
677 painter.drawLine(left, y, right, y) |
691 painter.drawLine(left, y, right, y) |
678 else: |
692 else: |
679 painter.drawRect(left, top, right - left, bottom - top) |
693 painter.drawRect(left, top, right - left, bottom - top) |
680 if self.__selecting: |
694 if self.__selecting: |
681 self.__selRect = QRect( |
695 self.__selRect = QRect( |
682 left, top, right - left + 1, bottom - top + 1) |
696 left, top, right - left + 1, bottom - top + 1) |
683 self.__selectionAvailable = True |
697 self.__selectionAvailable = True |
684 self.selectionAvailable.emit(True) |
698 self.selectionAvailable.emit(True) |
685 |
699 |
686 elif self.__curTool in [self.Circle, self.FilledCircle, |
700 elif self.__curTool in [ |
687 self.CircleSelection]: |
701 IconEditorTool.CIRCLE, IconEditorTool.FILLED_CIRCLE, |
|
702 IconEditorTool.SELECT_CIRCLE |
|
703 ]: |
688 deltaX = abs(start.x() - end.x()) |
704 deltaX = abs(start.x() - end.x()) |
689 deltaY = abs(start.y() - end.y()) |
705 deltaY = abs(start.y() - end.y()) |
690 r = max(deltaX, deltaY) |
706 r = max(deltaX, deltaY) |
691 if self.__curTool in [self.FilledCircle, self.CircleSelection]: |
707 if self.__curTool in [ |
|
708 IconEditorTool.FILLED_CIRCLE, IconEditorTool.SELECT_CIRCLE |
|
709 ]: |
692 painter.setBrush(QBrush(drawColor)) |
710 painter.setBrush(QBrush(drawColor)) |
693 painter.drawEllipse(start, r, r) |
711 painter.drawEllipse(start, r, r) |
694 if self.__selecting: |
712 if self.__selecting: |
695 self.__selRect = QRect(start.x() - r, start.y() - r, |
713 self.__selRect = QRect(start.x() - r, start.y() - r, |
696 2 * r + 1, 2 * r + 1) |
714 2 * r + 1, 2 * r + 1) |
697 self.__selectionAvailable = True |
715 self.__selectionAvailable = True |
698 self.selectionAvailable.emit(True) |
716 self.selectionAvailable.emit(True) |
699 |
717 |
700 elif self.__curTool in [self.Ellipse, self.FilledEllipse]: |
718 elif self.__curTool in [ |
|
719 IconEditorTool.ELLIPSE, IconEditorTool.FILLED_ELLIPSE |
|
720 ]: |
701 r1 = abs(start.x() - end.x()) |
721 r1 = abs(start.x() - end.x()) |
702 r2 = abs(start.y() - end.y()) |
722 r2 = abs(start.y() - end.y()) |
703 if r1 == 0 or r2 == 0: |
723 if r1 == 0 or r2 == 0: |
704 return False |
724 return False |
705 if self.__curTool == self.FilledEllipse: |
725 if self.__curTool == IconEditorTool.FILLED_ELLIPSE: |
706 painter.setBrush(QBrush(drawColor)) |
726 painter.setBrush(QBrush(drawColor)) |
707 painter.drawEllipse(start, r1, r2) |
727 painter.drawEllipse(start, r1, r2) |
708 |
728 |
709 painter.end() |
729 painter.end() |
710 |
730 |
711 if self.__curTool in [self.Circle, self.FilledCircle, |
731 if self.__curTool in [ |
712 self.Ellipse, self.FilledEllipse]: |
732 IconEditorTool.CIRCLE, IconEditorTool.FILLED_CIRCLE, |
|
733 IconEditorTool.ELLIPSE, IconEditorTool.FILLED_ELLIPSE |
|
734 ]: |
713 self.update() |
735 self.update() |
714 else: |
736 else: |
715 self.__updateRect(self.__startPos, pos) |
737 self.__updateRect(self.__startPos, pos) |
716 |
738 |
717 return True |
739 return True |