All Classes Namespaces Functions Variables Enumerations Properties Pages
scribblearea.h
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 
19 #ifndef SCRIBBLEAREA_H
20 #define SCRIBBLEAREA_H
21 
22 #include <cstdint>
23 #include <ctime>
24 #include <deque>
25 #include <memory>
26 
27 #include <QColor>
28 #include <QPoint>
29 #include <QWidget>
30 #include <QPixmapCache>
31 
32 #include "movemode.h"
33 #include "log.h"
34 #include "pencildef.h"
35 #include "bitmapimage.h"
36 #include "canvaspainter.h"
37 #include "overlaypainter.h"
38 #include "preferencemanager.h"
39 #include "strokemanager.h"
40 #include "selectionpainter.h"
41 
42 class Layer;
43 class Editor;
44 class BaseTool;
45 class PointerEvent;
46 class BitmapImage;
47 class VectorImage;
48 
49 
50 class ScribbleArea : public QWidget
51 {
52  Q_OBJECT
53 
54  friend class MoveTool;
55  friend class EditTool;
56  friend class SmudgeTool;
57  friend class BucketTool;
58 
59 public:
61  ~ScribbleArea() override;
62 
63  bool init();
64  void setEditor(Editor* e) { mEditor = e; }
65  StrokeManager* getStrokeManager() const { return mStrokeManager.get(); }
66  Editor* editor() const { return mEditor; }
67 
68  void deleteSelection();
69  void applySelectionChanges();
70  void displaySelectionProperties();
71 
72  void paintTransformedSelection();
73  void applyTransformedSelection();
74  void cancelTransformedSelection();
75 
76  bool isLayerPaintable() const;
77 
78  QVector<QPoint> calcSelectionCenterPoints();
79 
80  void setEffect(SETTING e, bool isOn);
81 
82  LayerVisibility getLayerVisibility() const { return mLayerVisibility; }
83  qreal getCurveSmoothing() const { return mCurveSmoothingLevel; }
84  bool usePressure() const { return mUsePressure; }
85  bool makeInvisible() const { return mMakeInvisible; }
86 
87  QRect getCameraRect();
88  QPointF getCentralPoint();
89 
92  void updateCurrentFrame();
95  void updateFrame(int frame);
96 
98  void onScrubbed(int frameNumber);
99 
101  void onFramesModified();
102 
104  void onPlayStateChanged();
105 
107  void onViewChanged();
108 
110  void onFrameModified(int frameNumber);
111 
114  void onCurrentFrameModified();
115 
117  void onLayerChanged();
118 
120  void onSelectionChanged();
121 
124  void onOnionSkinTypeChanged();
125 
127  void onObjectLoaded();
128 
130  void setModified(int layerNumber, int frameNumber);
131  void setModified(const Layer* layer, int frameNumber);
132 
133  void flipSelection(bool flipVertical);
134  void renderOverlays();
135  void prepOverlays();
136 
137  BaseTool* currentTool() const;
138  BaseTool* getTool(ToolType eToolMode);
139  void setCurrentTool(ToolType eToolMode);
140 
141  void floodFillError(int errorType);
142 
143  bool isMouseInUse() const { return mMouseInUse; }
144  bool isTabletInUse() const { return mTabletInUse; }
145  bool isPointerInUse() const { return mMouseInUse || mTabletInUse; }
146 
147  void keyEvent(QKeyEvent* event);
148  void keyEventForSelection(QKeyEvent* event);
149 
150 signals:
151  void modified(int, int);
152  void multiLayerOnionSkinChanged(bool);
153  void refreshPreview();
154  void selectionUpdated();
155 
156 public slots:
157  void clearImage();
158  void setCurveSmoothing(int);
159  void toggleThinLines();
160  void toggleOutlines();
161  void increaseLayerVisibilityIndex();
162  void decreaseLayerVisibilityIndex();
163  void setLayerVisibility(LayerVisibility visibility);
164 
165  void updateToolCursor();
166  void paletteColorChanged(QColor);
167 
168  void showLayerNotVisibleWarning();
169  void updateOriginalPolygonF();
170  void setOriginalPolygonF(QPolygonF polygon) { mOriginalPolygonF = polygon; }
171  QPolygonF getOriginalPolygonF() { return mOriginalPolygonF; }
172 
173 
174 protected:
175  bool event(QEvent *event) override;
176  void tabletEvent(QTabletEvent*) override;
177  void wheelEvent(QWheelEvent*) override;
178  void mousePressEvent(QMouseEvent*) override;
179  void mouseMoveEvent(QMouseEvent*) override;
180  void mouseReleaseEvent(QMouseEvent*) override;
181  void mouseDoubleClickEvent(QMouseEvent*) override;
182  void keyPressEvent(QKeyEvent*) override;
183  void keyReleaseEvent(QKeyEvent*) override;
184  void paintEvent(QPaintEvent*) override;
185  void resizeEvent(QResizeEvent*) override;
186 
187 public:
188  void drawPolyline(QPainterPath path, QPen pen, bool useAA);
189  void drawLine(QPointF P1, QPointF P2, QPen pen, QPainter::CompositionMode cm);
190  void drawPath(QPainterPath path, QPen pen, QBrush brush, QPainter::CompositionMode cm);
191  void drawPen(QPointF thePoint, qreal brushWidth, QColor fillColor, bool useAA = true);
192  void drawPencil(QPointF thePoint, qreal brushWidth, qreal fixedBrushFeather, QColor fillColor, qreal opacity);
193  void drawBrush(QPointF thePoint, qreal brushWidth, qreal offset, QColor fillColor, qreal opacity, bool usingFeather = true, bool useAA = false);
194  void blurBrush(BitmapImage *bmiSource_, QPointF srcPoint_, QPointF thePoint_, qreal brushWidth_, qreal offset_, qreal opacity_);
195  void liquifyBrush(BitmapImage *bmiSource_, QPointF srcPoint_, QPointF thePoint_, qreal brushWidth_, qreal offset_, qreal opacity_);
196 
197  void paintBitmapBuffer();
198  void paintBitmapBufferRect(const QRect& rect);
199  void paintCanvasCursor(QPainter& painter);
200  void clearBitmapBuffer();
201  void refreshBitmap(const QRectF& rect, int rad);
202  void refreshVector(const QRectF& rect, int rad);
203  void setGaussianGradient(QGradient &gradient, QColor color, qreal opacity, qreal offset);
204 
205  void pointerPressEvent(PointerEvent*);
206  void pointerMoveEvent(PointerEvent*);
207  void pointerReleaseEvent(PointerEvent*);
208 
209  void updateCanvasCursor();
210 
214 
215  BitmapImage* mBufferImg = nullptr; // used to pre-draw vector modifications
216 
217  QPixmap mCursorImg;
218  QPixmap mTransCursImg;
219 
220 private:
221 
227 
229  void invalidateCacheForFrame(int frameNumber);
230 
233  void invalidateAllCache();
234 
237 
239  void invalidateOnionSkinsCacheAround(int frame);
240 
241  void prepCanvas(int frame, QRect rect);
242  void drawCanvas(int frame, QRect rect);
243  void settingUpdated(SETTING setting);
244  void paintSelectionVisuals(QPainter &painter);
245 
246  BitmapImage* currentBitmapImage(Layer* layer) const;
247  VectorImage* currentVectorImage(Layer* layer) const;
248 
249  MoveMode mMoveMode = MoveMode::NONE;
250 
251  BitmapImage mBitmapSelection; // used to temporary store a transformed portion of a bitmap image
252 
253  std::unique_ptr<StrokeManager> mStrokeManager;
254 
255  Editor* mEditor = nullptr;
256 
257 
258  bool mIsSimplified = false;
259  bool mShowThinLines = false;
260  bool mQuickSizing = true;
261  LayerVisibility mLayerVisibility = LayerVisibility::ALL;
262  bool mUsePressure = true;
263  bool mMakeInvisible = false;
264  bool mToolCursors = true;
265  qreal mCurveSmoothingLevel = 0.0;
266  bool mMultiLayerOnionSkin = false; // future use. If required, just add a checkbox to updated it.
267  QColor mOnionColor;
268 
269 private:
270  bool mKeyboardInUse = false;
271  bool mMouseInUse = false;
272  bool mMouseRightButtonInUse = false;
273  bool mTabletInUse = false;
274  qreal mDevicePixelRatio = 1.;
275 
276  // Double click handling for tablet input
277  void handleDoubleClick();
278  bool mIsFirstClick = true;
279  int mDoubleClickMillis = 0;
280  // Microsoft suggests that a double click action should be no more than 500 ms
281  const int DOUBLE_CLICK_THRESHOLD = 500;
282  QTimer* mDoubleClickTimer = nullptr;
283 
284  QPoint mCursorCenterPos;
285  QPointF mTransformedCursorPos;
286 
287  PreferenceManager* mPrefs = nullptr;
288 
289  QPixmap mCanvas;
290  CanvasPainter mCanvasPainter;
291  OverlayPainter mOverlayPainter;
292  SelectionPainter mSelectionPainter;
293 
294  QPolygonF mOriginalPolygonF = QPolygonF();
295 
296  // Pixmap Cache keys
297  QMap<unsigned int, QPixmapCache::Key> mPixmapCacheKeys;
298 
299  // debug
300  QLoggingCategory mLog{ "ScribbleArea" };
301 };
302 
303 #endif
void onSelectionChanged()
Selection was changed, keep cache.
void invalidateOnionSkinsCacheAround(int frame)
invalidate onion skin cache around frame
void onPlayStateChanged()
Playstate changed, invalidate relevant cache.
void onFramesModified()
Multiple frames modified, invalidate cache for affected frames.
void onLayerChanged()
Layer changed, invalidate relevant cache.
void setModified(int layerNumber, int frameNumber)
Set frame on layer to modified and invalidate current frame cache.
virtual bool event(QEvent *e)
void invalidateAllCache()
Invalidate all cache.
void handleDrawingOnEmptyFrame()
Call this when starting to use a paint tool.
Q_OBJECTQ_OBJECT
Definition: layer.h:38
void updateFrame(int frame)
Update frame.
void onScrubbed(int frameNumber)
Frame scrubbed, invalidate relevant cache.
QRect rect() const const
void invalidateCacheForDirtyFrames()
invalidate cache for dirty keyframes.
void onFrameModified(int frameNumber)
Frame modified, invalidate cache for frame if any.
void invalidateCacheForFrame(int frameNumber)
Invalidate cache for the given frame.
void onViewChanged()
View updated, invalidate relevant cache.
void invalidateLayerPixmapCache()
Invalidate the layer pixmap cache.
void onObjectLoaded()
Object updated, invalidate all cache.
void updateCurrentFrame()
Update current frame.
void onOnionSkinTypeChanged()
Onion skin type changed, all frames will be affected.
Definition: editor.h:55
QObject * parent() const const
void onCurrentFrameModified()
Current frame modified, invalidate current frame cache if any.