Pencil2D  ff90c0872e88be3bf81c548cd60f01983012ec49
Pencil2D is an animation software for both bitmap and vector graphics. It is free, multi-platform, and open source.
 All Classes Functions
polylinetool.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 "polylinetool.h"
19 
20 #include "editor.h"
21 #include "scribblearea.h"
22 
23 #include "strokemanager.h"
24 #include "layermanager.h"
25 
26 #include "layervector.h"
27 #include "layerbitmap.h"
28 
29 
30 PolylineTool::PolylineTool( QObject *parent ) :
31 BaseTool( parent )
32 {
33 }
34 
35 ToolType PolylineTool::type()
36 {
37  return POLYLINE;
38 }
39 
40 void PolylineTool::loadSettings()
41 {
42  m_enabledProperties[WIDTH] = true;
43  m_enabledProperties[BEZIER] = true;
44  m_enabledProperties[ANTI_ALIASING] = true;
45 
46  QSettings settings( PENCIL2D, PENCIL2D );
47 
48  properties.width = settings.value( "polyLineWidth" ).toDouble();
49  properties.feather = -1;
50  properties.pressure = 0;
51  properties.invisibility = OFF;
52  properties.preserveAlpha = OFF;
53  properties.useAA = settings.value( "brushAA").toBool();
54  properties.inpolLevel = -1;
55 
56  // First run
57  if ( properties.width <= 0 )
58  {
59  setWidth(1.5);
60  }
61 }
62 
63 void PolylineTool::setWidth(const qreal width)
64 {
65  // Set current property
66  properties.width = width;
67 
68  // Update settings
69  QSettings settings( PENCIL2D, PENCIL2D );
70  settings.setValue("polyLineWidth", width);
71  settings.sync();
72 }
73 
74 void PolylineTool::setFeather( const qreal feather )
75 {
76  Q_UNUSED( feather );
77  properties.feather = -1;
78 }
79 
80 void PolylineTool::setAA( const int AA )
81 {
82  // Set current property
83  properties.useAA = AA;
84 
85  // Update settings
86  QSettings settings( PENCIL2D, PENCIL2D );
87  settings.setValue("brushAA", AA);
88  settings.sync();
89 }
90 
91 QCursor PolylineTool::cursor()
92 {
93  return Qt::CrossCursor;
94 }
95 
96 void PolylineTool::clear()
97 {
98  mPoints.clear();
99 }
100 
101 void PolylineTool::mousePressEvent( QMouseEvent *event )
102 {
103  Layer* layer = mEditor->layers()->currentLayer();
104 
105  if ( event->button() == Qt::LeftButton )
106  {
107  if ( layer->type() == Layer::BITMAP || layer->type() == Layer::VECTOR )
108  {
109  if ( mPoints.size() == 0 )
110  {
111  mEditor->backup( tr( "Polyline" ) );
112  }
113 
114  if ( layer->type() == Layer::VECTOR )
115  {
116  ( ( LayerVector * )layer )->getLastVectorImageAtFrame( mEditor->currentFrame(), 0 )->deselectAll();
117  if ( mScribbleArea->makeInvisible() && !mEditor->preference()->isOn(SETTING::INVISIBLE_LINES) )
118  {
119  mScribbleArea->toggleThinLines();
120  }
121  }
122  mPoints << getCurrentPoint();
123  mScribbleArea->setAllDirty();
124  }
125  }
126 }
127 
128 void PolylineTool::mouseReleaseEvent( QMouseEvent *event )
129 {
130  Q_UNUSED( event );
131 }
132 
133 void PolylineTool::mouseMoveEvent( QMouseEvent *event )
134 {
135  Q_UNUSED( event );
136  Layer* layer = mEditor->layers()->currentLayer();
137 
138  if ( layer->type() == Layer::BITMAP || layer->type() == Layer::VECTOR )
139  {
140  drawPolyline( mPoints, getCurrentPoint() );
141  }
142 }
143 
144 void PolylineTool::mouseDoubleClickEvent( QMouseEvent *event )
145 {
146  // XXX highres position ??
147  if ( BezierCurve::eLength( m_pStrokeManager->getLastPressPixel() - event->pos() ) < 2.0 )
148  {
149  endPolyline( mPoints );
150  clear();
151  }
152 }
153 
154 bool PolylineTool::keyPressEvent( QKeyEvent *event )
155 {
156  switch ( event->key() ) {
157  case Qt::Key_Return:
158  if ( mPoints.size() > 0 )
159  {
160  endPolyline( mPoints );
161  clear();
162  return true;
163  }
164  break;
165 
166  case Qt::Key_Escape:
167  if ( mPoints.size() > 0 ) {
168  cancelPolyline( );
169  clear();
170  return true;
171  }
172  break;
173 
174  default:
175  return false;
176  }
177 
178  return false;
179 }
180 
181 void PolylineTool::drawPolyline(QList<QPointF> points, QPointF endPoint)
182 {
183  if ( !mScribbleArea->areLayersSane() )
184  {
185  return;
186  }
187 
188  if ( points.size() > 0 )
189  {
190  QPen pen( mEditor->color()->frontColor(),
191  properties.width,
192  Qt::SolidLine,
193  Qt::RoundCap,
194  Qt::RoundJoin );
195  Layer* layer = mEditor->layers()->currentLayer();
196 
197  // Bitmap by default
198  QPainterPath tempPath;
199  if ( properties.bezier_state )
200  {
201  tempPath = BezierCurve( points ).getSimplePath();
202  }
203  else
204  {
205  tempPath = BezierCurve( points ).getStraightPath();
206  }
207  tempPath.lineTo( endPoint );
208 
209  // Vector otherwise
210  if ( layer->type() == Layer::VECTOR )
211  {
212  if ( mEditor->layers()->currentLayer()->type() == Layer::VECTOR )
213  {
214  tempPath = mEditor->view()->mapCanvasToScreen( tempPath );
215  if ( mScribbleArea->makeInvisible() == true )
216  {
217  pen.setWidth( 0 );
218  pen.setStyle( Qt::DotLine );
219  }
220  else
221  {
222  pen.setWidth(properties.width * mEditor->view()->scaling() );
223  }
224  }
225  }
226 
227  mScribbleArea->drawPolyline(tempPath, pen, properties.useAA);
228  }
229 }
230 
231 
232 void PolylineTool::cancelPolyline()
233 {
234  // Clear the in-progress polyline from the bitmap buffer.
235  mScribbleArea->clearBitmapBuffer();
236  mScribbleArea->updateCurrentFrame();
237 }
238 
239 void PolylineTool::endPolyline( QList<QPointF> points )
240 {
241  if ( !mScribbleArea->areLayersSane() )
242  {
243  return;
244  }
245 
246  Layer* layer = mEditor->layers()->currentLayer();
247 
248  if ( layer->type() == Layer::VECTOR )
249  {
250  BezierCurve curve = BezierCurve( points );
251  if ( mScribbleArea->makeInvisible() == true )
252  {
253  curve.setWidth( 0 );
254  }
255  else
256  {
257  curve.setWidth( properties.width );
258  }
259  curve.setColourNumber( mEditor->color()->frontColorNumber() );
260  curve.setVariableWidth( false );
261  curve.setInvisibility( mScribbleArea->makeInvisible() );
262  //curve.setSelected(true);
263  ( ( LayerVector * )layer )->getLastVectorImageAtFrame( mEditor->currentFrame(), 0 )->addCurve( curve, mEditor->view()->scaling() );
264  }
265  if ( layer->type() == Layer::BITMAP )
266  {
267  drawPolyline( points, points.last() );
268  BitmapImage *bitmapImage = ( ( LayerBitmap * )layer )->getLastBitmapImageAtFrame( mEditor->currentFrame(), 0 );
269  bitmapImage->paste( mScribbleArea->mBufferImg );
270  }
271  mScribbleArea->mBufferImg->clear();
272  mScribbleArea->setModified( mEditor->layers()->currentLayerIndex(), mEditor->currentFrame() );
273 }
Definition: layer.h:32