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 "preferencemanager.h"
38 #include "strokemanager.h"
39 #include "selectionpainter.h"
40 
41 class Layer;
42 class Editor;
43 class BaseTool;
44 class PointerEvent;
45 class BitmapImage;
46 class VectorImage;
47 
48 
49 class ScribbleArea : public QWidget
50 {
51  Q_OBJECT
52 
53  friend class MoveTool;
54  friend class EditTool;
55  friend class SmudgeTool;
56  friend class BucketTool;
57 
58 public:
60  ~ScribbleArea() override;
61 
62  bool init();
63  void setEditor(Editor* e) { mEditor = e; }
64  StrokeManager* getStrokeManager() const { return mStrokeManager.get(); }
65  Editor* editor() const { return mEditor; }
66 
67  void deleteSelection();
68  void applySelectionChanges();
69  void displaySelectionProperties();
70 
71  void paintTransformedSelection();
72  void applyTransformedSelection();
73  void cancelTransformedSelection();
74 
75  bool isLayerPaintable() const;
76 
77  QVector<QPoint> calcSelectionCenterPoints();
78 
79  void setEffect(SETTING e, bool isOn);
80 
81  LayerVisibility getLayerVisibility() const { return mLayerVisibility; }
82  qreal getCurveSmoothing() const { return mCurveSmoothingLevel; }
83  bool usePressure() const { return mUsePressure; }
84  bool makeInvisible() const { return mMakeInvisible; }
85 
86  QRectF getCameraRect();
87  QPointF getCentralPoint();
88 
89  void updateCurrentFrame();
90 
94  void updateFrame(int frame);
95  void updateOnionSkinsAround(int frame);
96  void updateAllFrames();
97  void updateAllVectorLayersAtCurrentFrame();
98  void updateAllVectorLayersAt(int frameNumber);
99 
100  void setModified(int layerNumber, int frameNumber);
101  void setAllDirty();
102 
103  void flipSelection(bool flipVertical);
104 
105  BaseTool* currentTool() const;
106  BaseTool* getTool(ToolType eToolMode);
107  void setCurrentTool(ToolType eToolMode);
108  void setTemporaryTool(ToolType eToolMode);
109  void setPrevTool();
110 
111  void floodFillError(int errorType);
112 
113  bool isMouseInUse() const { return mMouseInUse; }
114  bool isTabletInUse() const { return mTabletInUse; }
115  bool isPointerInUse() const { return mMouseInUse || mTabletInUse; }
116  bool isTemporaryTool() const { return mInstantTool; }
117 
125  bool isAffectedByActiveLayer() const;
126 
127  void keyEvent(QKeyEvent* event);
128  void keyEventForSelection(QKeyEvent* event);
129 
130 signals:
131  void modification(int);
132  void multiLayerOnionSkinChanged(bool);
133  void refreshPreview();
134 
135 public slots:
136  void clearImage();
137  void setCurveSmoothing(int);
138  void toggleThinLines();
139  void toggleOutlines();
140  void increaseLayerVisibilityIndex();
141  void decreaseLayerVisibilityIndex();
142  void setLayerVisibility(LayerVisibility visibility);
143 
144  void updateToolCursor();
145  void paletteColorChanged(QColor);
146 
147  void showLayerNotVisibleWarning();
148 
149 
150 protected:
151  bool event(QEvent *event) override;
152  void tabletEvent(QTabletEvent*) override;
153  void wheelEvent(QWheelEvent*) override;
154  void mousePressEvent(QMouseEvent*) override;
155  void mouseMoveEvent(QMouseEvent*) override;
156  void mouseReleaseEvent(QMouseEvent*) override;
157  void mouseDoubleClickEvent(QMouseEvent*) override;
158  void keyPressEvent(QKeyEvent*) override;
159  void keyReleaseEvent(QKeyEvent*) override;
160  void paintEvent(QPaintEvent*) override;
161  void resizeEvent(QResizeEvent*) override;
162 
163 public:
164  void drawPolyline(QPainterPath path, QPen pen, bool useAA);
165  void drawLine(QPointF P1, QPointF P2, QPen pen, QPainter::CompositionMode cm);
166  void drawPath(QPainterPath path, QPen pen, QBrush brush, QPainter::CompositionMode cm);
167  void drawPen(QPointF thePoint, qreal brushWidth, QColor fillColor, bool useAA = true);
168  void drawPencil(QPointF thePoint, qreal brushWidth, qreal fixedBrushFeather, QColor fillColor, qreal opacity);
169  void drawBrush(QPointF thePoint, qreal brushWidth, qreal offset, QColor fillColor, qreal opacity, bool usingFeather = true, bool useAA = false);
170  void blurBrush(BitmapImage *bmiSource_, QPointF srcPoint_, QPointF thePoint_, qreal brushWidth_, qreal offset_, qreal opacity_);
171  void liquifyBrush(BitmapImage *bmiSource_, QPointF srcPoint_, QPointF thePoint_, qreal brushWidth_, qreal offset_, qreal opacity_);
172 
173  void paintBitmapBuffer();
174  void paintBitmapBufferRect(const QRect& rect);
175  void paintCanvasCursor(QPainter& painter);
176  void clearBitmapBuffer();
177  void refreshBitmap(const QRectF& rect, int rad);
178  void refreshVector(const QRectF& rect, int rad);
179  void setGaussianGradient(QGradient &gradient, QColor color, qreal opacity, qreal offset);
180 
181  void pointerPressEvent(PointerEvent*);
182  void pointerMoveEvent(PointerEvent*);
183  void pointerReleaseEvent(PointerEvent*);
184 
185  void updateCanvasCursor();
186 
190 
191  BitmapImage* mBufferImg = nullptr; // used to pre-draw vector modifications
192 
193  QPixmap mCursorImg;
194  QPixmap mTransCursImg;
195 
196 private:
197  void prepCanvas(int frame, QRect rect);
198  void drawCanvas(int frame, QRect rect);
199  void settingUpdated(SETTING setting);
200  void paintSelectionVisuals(QPainter &painter);
201 
202  BitmapImage* currentBitmapImage(Layer* layer) const;
203  VectorImage* currentVectorImage(Layer* layer) const;
204 
205  MoveMode mMoveMode = MoveMode::NONE;
206  ToolType mPrevTemporalToolType = ERASER;
207  ToolType mPrevToolType = PEN; // previous tool (except temporal)
208 
209  BitmapImage mBitmapSelection; // used to temporary store a transformed portion of a bitmap image
210 
211  std::unique_ptr<StrokeManager> mStrokeManager;
212 
213  Editor* mEditor = nullptr;
214 
215  bool mIsSimplified = false;
216  bool mShowThinLines = false;
217  bool mQuickSizing = true;
218  LayerVisibility mLayerVisibility = LayerVisibility::ALL;
219  bool mUsePressure = true;
220  bool mMakeInvisible = false;
221  bool mToolCursors = true;
222  qreal mCurveSmoothingLevel = 0.0;
223  bool mMultiLayerOnionSkin = false; // future use. If required, just add a checkbox to updated it.
224  QColor mOnionColor;
225 
226 private:
227  bool mKeyboardInUse = false;
228  bool mMouseInUse = false;
229  bool mMouseRightButtonInUse = false;
230  bool mTabletInUse = false;
231 
232  // Double click handling for tablet input
233  void handleDoubleClick();
234  bool mIsFirstClick = true;
235  int mDoubleClickMillis = 0;
236  // Microsoft suggests that a double click action should be no more than 500 ms
237  const int DOUBLE_CLICK_THRESHOLD = 500;
238  QTimer* mDoubleClickTimer = nullptr;
239 
240  QPoint mCursorCenterPos;
241  QPointF mTransformedCursorPos;
242 
243  //instant tool (temporal eg. eraser)
244  bool mInstantTool = false; //whether or not using temporal tool
245 
246  PreferenceManager* mPrefs = nullptr;
247 
248  QPixmap mCanvas;
249  CanvasPainter mCanvasPainter;
250  SelectionPainter mSelectionPainter;
251 
252  // Pixmap Cache keys
253  QMap<unsigned int, QPixmapCache::Key> mPixmapCacheKeys;
254 
255  // debug
256  QLoggingCategory mLog{ "ScribbleArea" };
257 };
258 
259 #endif
virtual bool event(QEvent *e)
void updateAllFramesIfNeeded()
Check if the cache should be invalidated for all frames since the last paint operation.
void handleDrawingOnEmptyFrame()
Call this when starting to use a paint tool.
Q_OBJECTQ_OBJECT
Definition: layer.h:39
QRect rect() const const
bool isAffectedByActiveLayer() const
Check if the content of the canvas depends on the active layer.
Definition: editor.h:51
QObject * parent() const const