Pencil2D  ff90c0872e88be3bf81c548cd60f01983012ec49
Pencil2D is an animation software for both bitmap and vector graphics. It is free, multi-platform, and open source.
 All Classes Functions
buckettool.cpp
1 /*
2 
3 Pencil - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2017 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 <QPixmap>
19 #include <QPainter>
20 #include <QMouseEvent>
21 
22 #include "layer.h"
23 #include "layervector.h"
24 #include "layerbitmap.h"
25 #include "layermanager.h"
26 #include "colormanager.h"
27 #include "strokemanager.h"
28 
29 #include "pencilsettings.h"
30 #include "editor.h"
31 #include "scribblearea.h"
32 
33 #include "buckettool.h"
34 
35 BucketTool::BucketTool( QObject *parent ) :
36 StrokeTool( parent )
37 {
38 }
39 
40 
41 ToolType BucketTool::type()
42 {
43  return BUCKET;
44 }
45 
46 void BucketTool::loadSettings()
47 {
48  properties.width = 4;
49  properties.feather = 10;
50  properties.inpolLevel = -1;
51  properties.useAA = -1;
52  properties.tolerance = 10;
53 
54  m_enabledProperties[TOLERANCE] = true;
55 }
56 
57 QCursor BucketTool::cursor()
58 {
59  if( mEditor->preference()->isOn( SETTING::TOOL_CURSOR ) ) {
60  QPixmap pixmap( ":icons/bucketTool.png" );
61  QPainter painter( &pixmap );
62  painter.end();
63 
64  return QCursor( pixmap, 4, 20 );
65  } else {
66  return Qt::CrossCursor;
67  }
68 }
69 
70 void BucketTool::setTolerance(const int tolerance)
71 {
72  // Set current property
73  properties.tolerance = tolerance;
74 
75  // Update settings
76  QSettings settings( PENCIL2D, PENCIL2D );
77  settings.setValue("tolerance", tolerance );
78  settings.sync();
79 }
80 
81 
82 void BucketTool::mousePressEvent( QMouseEvent *event )
83 {
84  if( event->button() == Qt::LeftButton ) {
85  mEditor->backup( typeName() );
86  mScribbleArea->setAllDirty();
87  }
88 
89  startStroke();
90 }
91 
92 void BucketTool::mouseReleaseEvent( QMouseEvent *event )
93 {
94  Layer* layer = mEditor->layers()->currentLayer();
95  if ( layer == NULL ) { return; }
96 
97  if ( event->button() == Qt::LeftButton ) {
98  if ( layer->type() == Layer::BITMAP ) {
99  paintBitmap(layer);
100  }
101  else if( layer->type() == Layer::VECTOR ) {
102  paintVector(event, layer);
103  }
104  }
105  endStroke();
106 }
107 
108 void BucketTool::mouseMoveEvent( QMouseEvent *event )
109 {
110  Layer* layer = mEditor->layers()->currentLayer();
111  if ( layer->type() == Layer::BITMAP) {
112  Q_UNUSED( event );
113  }
114  else if(layer->type() == Layer::VECTOR ) {
115  if( event->buttons() & Qt::LeftButton ) {
116  drawStroke();
117  qDebug() << "DrawStroke" << event->pos() ;
118  }
119  }
120 
121  Q_UNUSED( event );
122 }
123 
124 void BucketTool::paintBitmap(Layer* layer)
125 {
126  Layer *targetLayer = layer; // by default
127  int layerNumber = mEditor->layers()->currentLayerIndex(); // by default
128 
129  BitmapImage *targetImage = ( ( LayerBitmap * )targetLayer )->getLastBitmapImageAtFrame( mEditor->currentFrame(), 0 );
130 
131  QPoint point = getLastPoint().toPoint();
132 
133  QRect cameraRect = mScribbleArea->getCameraRect().toRect();
134 
135  BitmapImage::floodFill( targetImage,
136  cameraRect,
137  point,
138  Qt::transparent,
139  qPremultiply( mEditor->color()->frontColor().rgba() ),
140  properties.tolerance * 2.55 );
141 
142  mScribbleArea->setModified( layerNumber, mEditor->currentFrame() );
143  mScribbleArea->setAllDirty();
144 }
145 
146 void BucketTool::paintVector(QMouseEvent *event, Layer* layer)
147 {
148  mScribbleArea->clearBitmapBuffer();
149  VectorImage *vectorImage = ( ( LayerVector * )layer )->getLastVectorImageAtFrame( mEditor->currentFrame(), 0 );
150 
151  if( event->modifiers() == Qt::AltModifier ) {
152  vectorImage->removeArea( getLastPoint() );
153  } else {
154  QList<QPointF> path = mStrokePoints;
155  if (path.size() < 10) {
156  vectorImage->fill( getLastPoint(),
157  mEditor->color()->frontColorNumber(),
158  3.0 / mEditor->view()->scaling() );
159  } else {
160  vectorImage->fillPath( path,
161  mEditor->color()->frontColorNumber(),
162  10.0 / mEditor->view()->scaling() );
163  }
164  }
165  mScribbleArea->setModified( mEditor->layers()->currentLayerIndex(), mEditor->currentFrame() );
166  mScribbleArea->setAllDirty();
167 }
168 
169 void BucketTool::drawStroke()
170 {
171  StrokeTool::drawStroke();
172  QList<QPointF> p = m_pStrokeManager->interpolateStroke();
173 
174  Layer* layer = mEditor->layers()->currentLayer();
175 
176  if( layer->type() == Layer::BITMAP ) {
177  // No stroke in Bitmap layer
178  }
179  else if( layer->type() == Layer::VECTOR ) {
180  int rad = qRound( ( mCurrentWidth / 2 + 2 ) * mEditor->view()->scaling() );
181 
182  QColor pathColor = mEditor->color()->frontColor();
183  pathColor.setAlpha(50);
184 
185  QPen pen( pathColor,
186  mCurrentWidth * mEditor->view()->scaling(),
187  Qt::SolidLine,
188  Qt::RoundCap,
189  Qt::RoundJoin );
190 
191  if( p.size() == 4 ) {
192  QPainterPath path( p[ 0 ] );
193  path.cubicTo( p[ 1 ],
194  p[ 2 ],
195  p[ 3 ] );
196  mScribbleArea->drawPath( path, pen, Qt::NoBrush, QPainter::CompositionMode_Source );
197  mScribbleArea->refreshVector( path.boundingRect().toRect(), rad );
198  }
199  }
200 }
Definition: layer.h:32