-
Notifications
You must be signed in to change notification settings - Fork 275
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Overhaul canvas cursor and quick cursor implementation (#1806)
* Implement width cursor * Make feather cursor adjust properly * Invert feather values * Fix circle rendering becoming near invisible when width and feather are too close * Cleanup cursor logic in strokeTool * Remove tolerance quick cursor shortcut As it currently is, it does not make sense to keep it as a cursor modification as it has no relation to the cursor. * Don't show feather circle when it's fixed size * Simplify cursor paint methods * Fix CI Qt not compiling * Add missing license to CanvasCursorPainter * Review changes * Fix build failure on old MSVC versions * Review change: move quick cursor logic into stroke tool * Remove redundant neutral multiplication * Fix cursor lingers on canvas * Migrate canvas cursor setting from dotted to canvas cursor * Fix cursor would disappear if outside main window * Fix view updates would send signals to all stroke tools * Remove useFeather * Keep internal config file key for canvas cursor setting * Fix canvas cursor artifacts when leaving ScribbleArea * Apply suggestion to return either current tool event or widget event * Fix tool event handling * Bucket tool: remove quick sizing --------- Co-authored-by: Jakob Gahde <[email protected]>
- Loading branch information
Showing
35 changed files
with
674 additions
and
405 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
Pencil2D - Traditional Animation Software | ||
Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon | ||
Copyright (C) 2012-2020 Matthew Chiawen Chang | ||
This program is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU General Public License | ||
as published by the Free Software Foundation; version 2 of the License. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
*/ | ||
#include "canvascursorpainter.h" | ||
|
||
#include <QPainter> | ||
|
||
CanvasCursorPainter::CanvasCursorPainter() | ||
{ | ||
setupPen(); | ||
} | ||
|
||
void CanvasCursorPainter::setupPen() | ||
{ | ||
mCursorPen = QPen(Qt::gray); | ||
mCursorPen.setWidthF(1); | ||
mCursorPen.setCosmetic(true); | ||
} | ||
|
||
void CanvasCursorPainter::paint(QPainter& painter, const QRect& blitRect) | ||
{ | ||
if (mOptions.isAdjusting || mOptions.showCursor) { | ||
if (mOptions.useFeather) { | ||
paintFeatherCursor(painter, blitRect, mOptions.widthRect, mOptions.featherRect); | ||
} | ||
paintWidthCursor(painter, blitRect, mOptions.widthRect); | ||
mIsDirty = true; | ||
} | ||
} | ||
|
||
void CanvasCursorPainter::preparePainter(const CanvasCursorPainterOptions& painterOptions, const QTransform& viewTransform) | ||
{ | ||
mOptions = painterOptions; | ||
if (mOptions.isAdjusting || mOptions.showCursor) { | ||
mOptions.widthRect = viewTransform.mapRect(mOptions.widthRect); | ||
mOptions.featherRect = viewTransform.mapRect(mOptions.featherRect); | ||
} | ||
} | ||
|
||
void CanvasCursorPainter::paintFeatherCursor(QPainter& painter, const QRect& blitRect, const QRectF& widthCircleBounds, const QRectF& featherCircleBounds) | ||
{ | ||
// When the circles are too close to each other, the rendering will appear dotted or almost | ||
// invisible at certain zoom levels. | ||
if (widthCircleBounds.width() - featherCircleBounds.width() <= 1) { | ||
return; | ||
} | ||
|
||
painter.save(); | ||
|
||
painter.setClipRect(blitRect); | ||
painter.setPen(mCursorPen); | ||
painter.setCompositionMode(QPainter::RasterOp_SourceXorDestination); | ||
painter.drawEllipse(featherCircleBounds); | ||
|
||
painter.restore(); | ||
} | ||
|
||
void CanvasCursorPainter::paintWidthCursor(QPainter& painter, const QRect& blitRect, const QRectF& widthCircleBounds) | ||
{ | ||
painter.save(); | ||
|
||
painter.setClipRect(blitRect); | ||
painter.setPen(mCursorPen); | ||
|
||
painter.setCompositionMode(QPainter::RasterOp_SourceXorDestination); | ||
|
||
// Only draw the cross when the width is bigger than the cross itself | ||
if (widthCircleBounds.width() > 8) { | ||
const QPointF& pos = widthCircleBounds.center(); | ||
painter.drawLine(QPointF(pos.x() - 2, pos.y()), QPointF(pos.x() + 2, pos.y())); | ||
painter.drawLine(QPointF(pos.x(), pos.y() - 2), QPointF(pos.x(), pos.y() + 2)); | ||
} | ||
|
||
painter.drawEllipse(widthCircleBounds); | ||
painter.restore(); | ||
|
||
mDirtyRect = widthCircleBounds.toAlignedRect(); | ||
} | ||
|
||
void CanvasCursorPainter::clearDirty() | ||
{ | ||
mDirtyRect = QRect(); | ||
mIsDirty = false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
Pencil2D - Traditional Animation Software | ||
Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon | ||
Copyright (C) 2012-2020 Matthew Chiawen Chang | ||
This program is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU General Public License | ||
as published by the Free Software Foundation; version 2 of the License. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
*/ | ||
#ifndef CANVASCURSORPAINTER_H | ||
#define CANVASCURSORPAINTER_H | ||
|
||
#include <QPen> | ||
|
||
class QPainter; | ||
|
||
struct CanvasCursorPainterOptions | ||
{ | ||
QRectF widthRect; | ||
QRectF featherRect; | ||
bool isAdjusting; | ||
bool useFeather = false; | ||
bool showCursor = false; | ||
}; | ||
|
||
class CanvasCursorPainter | ||
{ | ||
|
||
public: | ||
CanvasCursorPainter(); | ||
void paint(QPainter& painter, const QRect& blitRect); | ||
|
||
void preparePainter(const CanvasCursorPainterOptions& painterOptions, const QTransform& viewTransform); | ||
|
||
const QRect dirtyRect() { return mDirtyRect; } | ||
bool isDirty() const { return mIsDirty; } | ||
void clearDirty(); | ||
|
||
private: | ||
|
||
void setupPen(); | ||
|
||
/// @brief precision circular cursor: used for drawing a cursor on the canvas. | ||
void paintWidthCursor(QPainter& painter, const QRect& blitRect, const QRectF& widthCircleBounds); | ||
void paintFeatherCursor(QPainter& painter, const QRect& blitRect, const QRectF& widthCircleBounds, const QRectF& featherCircleBounds); | ||
|
||
CanvasCursorPainterOptions mOptions; | ||
QRect mDirtyRect; | ||
bool mIsDirty = false; | ||
|
||
QPen mCursorPen; | ||
}; | ||
|
||
#endif // CANVASCURSORPAINTER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.