1 /*
2
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 */
17
18 #include "eyedroppertool.h"
19
20 #include <QPainter>
21 #include <QPixmap>
22 #include <QBitmap>
23 #include <QtMath>
24 #include "pointerevent.h"
25
26 #include "vectorimage.h"
27 #include "layervector.h"
28 #include "layerbitmap.h"
29 #include "colormanager.h"
30 #include "object.h"
31 #include "editor.h"
32 #include "layermanager.h"
33 #include "scribblearea.h"
34 #include "util.h"
35
EyedropperTool(QObject * parent)36 EyedropperTool::EyedropperTool(QObject* parent) : BaseTool(parent)
37 {
38 }
39
loadSettings()40 void EyedropperTool::loadSettings()
41 {
42 properties.width = -1;
43 properties.feather = -1;
44 properties.useFeather = false;
45 properties.useAA = -1;
46 }
47
cursor()48 QCursor EyedropperTool::cursor()
49 {
50 if (mEditor->preference()->isOn(SETTING::TOOL_CURSOR))
51 {
52 return QCursor(QPixmap(":icons/eyedropper.png"), 0, 15);
53 }
54 else
55 {
56 return QCursor(QPixmap(":icons/cross.png"), 10, 10);
57 }
58 }
59
cursor(const QColor color)60 QCursor EyedropperTool::cursor(const QColor color)
61 {
62 QPixmap icon(":icons/eyedropper.png");
63
64 QPixmap pixmap(32, 32);
65 pixmap.fill(Qt::transparent);
66
67 QPainter painter(&pixmap);
68 painter.drawPixmap(0, 0, icon);
69
70 painter.setBrush(Qt::white);
71 painter.drawRect(17, 17, 13, 13);
72 painter.setPen(QPen(Qt::white, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
73 painter.setBrush(color);
74 painter.drawRect(16, 16, 15, 15);
75 painter.end();
76
77 return QCursor(pixmap, 0, 15);
78 }
79
pointerPressEvent(PointerEvent *)80 void EyedropperTool::pointerPressEvent(PointerEvent*)
81 {}
82
pointerMoveEvent(PointerEvent *)83 void EyedropperTool::pointerMoveEvent(PointerEvent*)
84 {
85 Layer* layer = mEditor->layers()->currentLayer();
86 if (layer == nullptr) { return; }
87
88 if (layer->type() == Layer::BITMAP)
89 {
90 QColor pickedColor = getBitmapColor(static_cast<LayerBitmap*>(layer));
91 if (pickedColor.isValid())
92 {
93 mScribbleArea->setCursor(cursor(pickedColor));
94 }
95 else
96 {
97 mScribbleArea->setCursor(cursor());
98 }
99 }
100 if (layer->type() == Layer::VECTOR)
101 {
102 int pickedColor = getVectorColor(static_cast<LayerVector*>(layer));
103 if (pickedColor >= 0)
104 {
105 mScribbleArea->setCursor(cursor(mEditor->object()->getColor(pickedColor).color));
106 }
107 else
108 {
109 mScribbleArea->setCursor(cursor());
110 }
111 }
112 }
113
pointerReleaseEvent(PointerEvent * event)114 void EyedropperTool::pointerReleaseEvent(PointerEvent* event)
115 {
116 if (event->button() == Qt::LeftButton)
117 {
118 updateFrontColor();
119
120 // reset cursor
121 mScribbleArea->setCursor(cursor());
122 }
123 }
124
updateFrontColor()125 void EyedropperTool::updateFrontColor()
126 {
127 Layer* layer = mEditor->layers()->currentLayer();
128 if (layer == nullptr) { return; }
129 if (layer->type() == Layer::BITMAP)
130 {
131 QColor pickedColor = getBitmapColor(static_cast<LayerBitmap*>(layer));
132 if (pickedColor.isValid())
133 {
134 mEditor->color()->setColor(pickedColor);
135 }
136 }
137 else if (layer->type() == Layer::VECTOR)
138 {
139 int pickedColor = getVectorColor(static_cast<LayerVector*>(layer));
140 if (pickedColor >= 0)
141 {
142 mEditor->color()->setColorNumber(pickedColor);
143 }
144 }
145 }
146
getBitmapColor(LayerBitmap * layer)147 QColor EyedropperTool::getBitmapColor(LayerBitmap* layer)
148 {
149 BitmapImage* targetImage = layer->getLastBitmapImageAtFrame(mEditor->currentFrame(), 0);
150 if (targetImage == nullptr || !targetImage->contains(getCurrentPoint())) return QColor();
151
152 QColor pickedColour;
153 const QRgb pixelColor = targetImage->constScanLine(qFloor(getCurrentPoint().x()),
154 qFloor(getCurrentPoint().y()));
155 pickedColour.setRgba(pixelColor);
156
157 if (pickedColour.alpha() <= 0) pickedColour = QColor();
158 return pickedColour;
159 }
160
getVectorColor(LayerVector * layer)161 int EyedropperTool::getVectorColor(LayerVector* layer)
162 {
163 auto vectorImage = static_cast<VectorImage*>(layer->getLastKeyFrameAtPosition(mEditor->currentFrame()));
164 if (vectorImage == nullptr) return -1;
165
166 // Check curves
167 const qreal toleranceDistance = 10.0;
168 const QList<int> closestCurves = vectorImage->getCurvesCloseTo(getCurrentPoint(), toleranceDistance);
169 const QList<int> visibleClosestCurves = filter(closestCurves, [vectorImage](int i) { return vectorImage->isCurveVisible(i); });
170
171 if (!visibleClosestCurves.isEmpty())
172 {
173 return vectorImage->getCurvesColor(visibleClosestCurves.last());
174 }
175
176 // Check fills
177 int colorNumber = vectorImage->getColorNumber(getCurrentPoint());
178 return colorNumber;
179 }
180