All Classes Namespaces Functions Variables Enumerations Properties Pages
eyedroppertool.cpp
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 
36 EyedropperTool::EyedropperTool(QObject* parent) : BaseTool(parent)
37 {
38 }
39 
40 void EyedropperTool::loadSettings()
41 {
42  properties.width = -1;
43  properties.feather = -1;
44  properties.useFeather = false;
45  properties.useAA = -1;
46 }
47 
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 
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 
80 void EyedropperTool::pointerPressEvent(PointerEvent*)
81 {}
82 
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 
114 void EyedropperTool::pointerReleaseEvent(PointerEvent* event)
115 {
116  if (event->button() == Qt::LeftButton)
117  {
119 
120  // reset cursor
121  mScribbleArea->setCursor(cursor());
122  }
123 }
124 
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()->setFrontColor(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 
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 
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 }
QColor getBitmapColor(LayerBitmap *layer)
Retrieves color of the pixel under the cursor for a bitmap layer.
void setCursor(const QCursor &)
SolidLine
void updateFrontColor()
Updates front color for bitmap and color index for vector.
void setRgba(QRgb rgba)
LeftButton
int getVectorColor(LayerVector *layer)
Retrieves the color index of the pixel under the cursor for a vector layer.
RoundCap
bool isEmpty() const const
Definition: layer.h:38
int alpha() const const
RoundJoin
T & last()
Qt::MouseButton button() const
Returns Qt::MouseButton()
transparent
bool isValid() const const