1 
2 
3 #include "rasterselectiontool.h"
4 #include "vectorselectiontool.h"
5 #include "drawutil.h"
6 #include "tenv.h"
7 #include "tools/toolhandle.h"
8 #include "toonz/tdistort.h"
9 #include "toonz/glrasterpainter.h"
10 #include "toonz/toonzimageutils.h"
11 #include "toonzqt/tselectionhandle.h"
12 #include "toonzqt/imageutils.h"
13 #include "toonz/txshlevelhandle.h"
14 
15 using namespace ToolUtils;
16 using namespace DragSelectionTool;
17 
18 //=============================================================================
19 // RasterFreeDeformer
20 //-----------------------------------------------------------------------------
21 
RasterFreeDeformer(TRasterP ras)22 RasterFreeDeformer::RasterFreeDeformer(TRasterP ras)
23     : FreeDeformer(), m_ras(ras), m_newRas(), m_noAntialiasing(false) {
24   TRect r       = ras->getBounds();
25   m_originalP00 = convert(r.getP00());
26   m_originalP11 = convert(r.getP11());
27   m_newPoints.push_back(m_originalP00);
28   m_newPoints.push_back(convert(r.getP10()));
29   m_newPoints.push_back(m_originalP11);
30   m_newPoints.push_back(convert(r.getP01()));
31 }
32 
33 //-----------------------------------------------------------------------------
34 
~RasterFreeDeformer()35 RasterFreeDeformer::~RasterFreeDeformer() {}
36 
37 //-----------------------------------------------------------------------------
38 
setPoint(int index,const TPointD & p)39 void RasterFreeDeformer::setPoint(int index, const TPointD &p) {
40   m_newPoints[index] = p;
41 }
42 
43 //-----------------------------------------------------------------------------
44 
setPoints(const TPointD & p0,const TPointD & p1,const TPointD & p2,const TPointD & p3)45 void RasterFreeDeformer::setPoints(const TPointD &p0, const TPointD &p1,
46                                    const TPointD &p2, const TPointD &p3) {
47   m_newPoints[0] = p0;
48   m_newPoints[1] = p1;
49   m_newPoints[2] = p2;
50   m_newPoints[3] = p3;
51 }
52 
53 //-----------------------------------------------------------------------------
54 
deformImage()55 void RasterFreeDeformer::deformImage() {
56   TPointD p00 = TPointD();
57   TPointD p10 = m_newPoints[1] - m_newPoints[0];
58   TPointD p11 = m_newPoints[2] - m_newPoints[0];
59   TPointD p01 = m_newPoints[3] - m_newPoints[0];
60 
61   double x0 = std::min({p00.x, p10.x, p11.x, p01.x});
62   double y0 = std::min({p00.y, p10.y, p11.y, p01.y});
63   double x1 = std::max({p00.x, p10.x, p11.x, p01.x});
64   double y1 = std::max({p00.y, p10.y, p11.y, p01.y});
65 
66   TRectD sourceRect(TPointD(), TPointD(m_ras->getLx(), m_ras->getLy()));
67   BilinearDistorterBase dist(sourceRect.getP00(), sourceRect.getP10(),
68                              sourceRect.getP01(), sourceRect.getP11(), p00, p10,
69                              p01, p11);
70 
71   TRect destRect(tfloor(x0), tfloor(y0), tceil(x1) - 1, tceil(y1) - 1);
72   if (TRasterCM32P ras = (TRasterCM32P)m_ras)
73     m_newRas = TRasterCM32P(destRect.getLx(), destRect.getLy());
74   else if (TRaster32P ras = (TRaster32P)m_ras)
75     m_newRas = TRaster32P(destRect.getLx(), destRect.getLy());
76   TRasterP newRas(m_newRas);  // Someway, conversion from TRasterCM32P to
77                               // TRasterP is not automatic
78   distort(newRas, m_ras, dist, destRect.getP00(),
79           m_noAntialiasing ? TRop::ClosestPixel : TRop::Bilinear);
80 }
81 
82 //=============================================================================
83 // UndoRasterDeform
84 //-----------------------------------------------------------------------------
85 
UndoRasterDeform(RasterSelectionTool * tool)86 DragSelectionTool::UndoRasterDeform::UndoRasterDeform(RasterSelectionTool *tool)
87     : TUndo()
88     , m_tool(tool)
89     , m_oldBBox(tool->getBBox())
90     , m_newBBox()
91     , m_oldCenter(tool->getCenter())
92     , m_newCenter()
93     , m_dim() {
94   RasterSelection *selection = (RasterSelection *)tool->getSelection();
95   m_oldStrokes               = selection->getStrokes();
96   m_oldFloatingImageId =
97       "UndoRasterDeform_old_floating_" + std::to_string(m_id++);
98   TRasterP floatingRas = selection->getFloatingSelection();
99   TImageP floatingImage;
100   if (TRasterCM32P toonzRas = (TRasterCM32P)(floatingRas)) {
101     floatingImage = TToonzImageP(toonzRas, toonzRas->getBounds());
102     m_dim         = toonzRas->getSize();
103     m_pixelSize   = toonzRas->getPixelSize();
104   }
105   if (TRaster32P fullColorRas = (TRaster32P)(floatingRas)) {
106     floatingImage = TRasterImageP(fullColorRas);
107     m_dim         = fullColorRas->getSize();
108     m_pixelSize   = fullColorRas->getPixelSize();
109   }
110   if (TRasterGR8P grRas = (TRasterGR8P)(floatingRas)) {
111     floatingImage = TRasterImageP(grRas);
112     m_dim         = grRas->getSize();
113     m_pixelSize   = grRas->getPixelSize();
114   }
115   TImageCache::instance()->add(m_oldFloatingImageId, floatingImage, false);
116 }
117 
118 //-----------------------------------------------------------------------------
119 
~UndoRasterDeform()120 DragSelectionTool::UndoRasterDeform::~UndoRasterDeform() {
121   if (TImageCache::instance()->isCached(m_oldFloatingImageId))
122     TImageCache::instance()->remove(m_oldFloatingImageId);
123   if (TImageCache::instance()->isCached(m_newFloatingImageId))
124     TImageCache::instance()->remove(m_newFloatingImageId);
125 }
126 
127 //-----------------------------------------------------------------------------
128 
registerRasterDeformation()129 void DragSelectionTool::UndoRasterDeform::registerRasterDeformation() {
130   RasterSelection *selection = (RasterSelection *)m_tool->getSelection();
131   m_newStrokes               = selection->getStrokes();
132   m_newFloatingImageId =
133       "UndoRasterDeform_new_floating_" + std::to_string(m_id);
134   TRasterP floatingRas = selection->getFloatingSelection();
135   TImageP floatingImage;
136   if (TRasterCM32P toonzRas = (TRasterCM32P)(floatingRas))
137     floatingImage = TToonzImageP(toonzRas, toonzRas->getBounds());
138   if (TRaster32P fullColorRas = (TRaster32P)(floatingRas))
139     floatingImage = TRasterImageP(fullColorRas);
140   if (TRasterGR8P grRas = (TRasterGR8P)(floatingRas))
141     floatingImage = TRasterImageP(grRas);
142   TImageCache::instance()->add(m_newFloatingImageId, floatingImage, false);
143   m_newBBox   = m_tool->getBBox();
144   m_newCenter = m_tool->getCenter();
145 }
146 
147 //-----------------------------------------------------------------------------
148 
undo() const149 void DragSelectionTool::UndoRasterDeform::undo() const {
150   RasterSelection *selection = (RasterSelection *)m_tool->getSelection();
151   if (!selection->isFloating()) return;
152   TImageP img = TImageCache::instance()->get(m_oldFloatingImageId, false);
153   TRasterP ras;
154   if (TToonzImageP ti = (TToonzImageP)(img)) ras = ti->getRaster();
155   if (TRasterImageP ri = (TRasterImageP)(img)) ras = ri->getRaster();
156   selection->setFloatingSeletion(ras);
157   selection->setStrokes(m_oldStrokes);
158   m_tool->setBBox(m_oldBBox);
159   m_tool->setCenter(m_oldCenter);
160   m_tool->invalidate();
161   m_tool->decreaseTransformationCount();
162 }
163 
164 //-----------------------------------------------------------------------------
165 
redo() const166 void DragSelectionTool::UndoRasterDeform::redo() const {
167   RasterSelection *selection = (RasterSelection *)m_tool->getSelection();
168   if (!selection->isFloating()) return;
169   TToonzImageP img = TImageCache::instance()->get(m_newFloatingImageId, false);
170   TRasterP ras;
171   if (TToonzImageP ti = (TToonzImageP)(img)) ras = ti->getRaster();
172   if (TRasterImageP ri = (TRasterImageP)(img)) ras = ri->getRaster();
173   selection->setStrokes(m_newStrokes);
174   m_tool->setBBox(m_newBBox);
175   m_tool->setCenter(m_newCenter);
176   m_tool->invalidate();
177   m_tool->increaseTransformationCount();
178 }
179 
180 //-----------------------------------------------------------------------------
181 
getSize() const182 int DragSelectionTool::UndoRasterDeform::getSize() const {
183   return sizeof(*this) + (m_dim.lx * m_dim.ly * m_pixelSize);
184 }
185 
186 //-----------------------------------------------------------------------------
187 
188 int DragSelectionTool::UndoRasterDeform::m_id = 0;
189 
190 //=============================================================================
191 // UndoRasterTransform
192 //-----------------------------------------------------------------------------
193 
UndoRasterTransform(RasterSelectionTool * tool)194 DragSelectionTool::UndoRasterTransform::UndoRasterTransform(
195     RasterSelectionTool *tool)
196     : m_tool(tool) {
197   m_oldDeformValues = m_tool->m_deformValues;
198   RasterSelection *selection =
199       dynamic_cast<RasterSelection *>(tool->getSelection());
200   m_oldTransform = selection->getTransformation();
201   m_oldCenter    = tool->getCenter();
202   m_oldBbox      = tool->getBBox();
203 }
204 
205 //-----------------------------------------------------------------------------
206 
setChangedValues()207 void DragSelectionTool::UndoRasterTransform::setChangedValues() {
208   m_newDeformValues = m_tool->m_deformValues;
209   RasterSelection *selection =
210       dynamic_cast<RasterSelection *>(m_tool->getSelection());
211   m_newTransform = selection->getTransformation();
212   m_newCenter    = m_tool->getCenter();
213   m_newBbox      = m_tool->getBBox();
214 }
215 
216 //-----------------------------------------------------------------------------
217 
undo() const218 void DragSelectionTool::UndoRasterTransform::undo() const {
219   m_tool->transformFloatingSelection(m_oldTransform, m_oldCenter, m_oldBbox);
220   m_tool->m_deformValues = m_oldDeformValues;
221   m_tool->decreaseTransformationCount();
222   TTool::getApplication()->getCurrentTool()->notifyToolChanged();
223 }
224 
225 //-----------------------------------------------------------------------------
226 
redo() const227 void DragSelectionTool::UndoRasterTransform::redo() const {
228   m_tool->transformFloatingSelection(m_newTransform, m_newCenter, m_newBbox);
229   m_tool->m_deformValues = m_newDeformValues;
230   m_tool->increaseTransformationCount();
231   TTool::getApplication()->getCurrentTool()->notifyToolChanged();
232 }
233 
234 //=============================================================================
235 // RasterDeformTool
236 //-----------------------------------------------------------------------------
237 
RasterDeformTool(RasterSelectionTool * tool,bool freeDeformer)238 DragSelectionTool::RasterDeformTool::RasterDeformTool(RasterSelectionTool *tool,
239                                                       bool freeDeformer)
240     : DeformTool(tool)
241     , m_transformUndo(0)
242     , m_deformUndo(0)
243     , m_isFreeDeformer(freeDeformer) {
244   if (!m_isFreeDeformer) m_transformUndo = new UndoRasterTransform(tool);
245 }
246 
247 //-----------------------------------------------------------------------------
248 
applyTransform(FourPoints bbox)249 void DragSelectionTool::RasterDeformTool::applyTransform(FourPoints bbox) {
250   RasterSelectionTool *tool = (RasterSelectionTool *)getTool();
251   tool->setNewFreeDeformer();
252   if (!m_deformUndo) m_deformUndo = new UndoRasterDeform(tool);
253   RasterSelection *selection =
254       dynamic_cast<RasterSelection *>(tool->getSelection());
255   assert(selection);
256   FourPoints realBbox = bbox * selection->getTransformation().inv();
257   RasterFreeDeformer *freeDeformer =
258       (RasterFreeDeformer *)tool->getFreeDeformer();
259   if (!freeDeformer) return;
260   freeDeformer->setNoAntialiasing(tool->getNoAntialiasingValue());
261   freeDeformer->setPoints(realBbox.getP00(), realBbox.getP10(),
262                           realBbox.getP11(), realBbox.getP01());
263   freeDeformer->deformImage();
264   selection->setFloatingSeletion(freeDeformer->getImage());
265   VectorFreeDeformer *vectorFreeDeformer = tool->getSelectionFreeDeformer();
266   if (vectorFreeDeformer) {
267     vectorFreeDeformer->setPoints(realBbox.getP00(), realBbox.getP10(),
268                                   realBbox.getP11(), realBbox.getP01());
269     vectorFreeDeformer->deformImage();
270     TVectorImage *vi = vectorFreeDeformer->getDeformedImage();
271     std::vector<TStroke> newStrokes;
272     int i;
273     for (i = 0; i < (int)vi->getStrokeCount(); i++)
274       newStrokes.push_back(*(vi->getStroke(i)));
275     selection->setStrokes(newStrokes);
276   }
277   tool->m_deformValues.m_isSelectionModified = true;
278   if (!m_isDragging) tool->notifyImageChanged();
279 }
280 
281 //-----------------------------------------------------------------------------
282 
applyTransform(TAffine aff,bool modifyCenter)283 void DragSelectionTool::RasterDeformTool::applyTransform(TAffine aff,
284                                                          bool modifyCenter) {
285   m_transform *= aff;
286   RasterSelectionTool *tool = dynamic_cast<RasterSelectionTool *>(getTool());
287   RasterSelection *rasterSelection =
288       dynamic_cast<RasterSelection *>(getTool()->getSelection());
289   rasterSelection->transform(aff);
290   tool->setBBox(tool->getBBox() * aff);
291   if (modifyCenter) tool->setCenter(aff * tool->getCenter());
292   if (!m_isDragging && !rasterSelection->isFloating())
293     rasterSelection->makeFloating();
294   else if (!m_isDragging)
295     tool->notifyImageChanged();
296 }
297 
298 //-----------------------------------------------------------------------------
299 
addTransformUndo()300 void DragSelectionTool::RasterDeformTool::addTransformUndo() {
301   RasterSelection *rasterSelection =
302       dynamic_cast<RasterSelection *>(getTool()->getSelection());
303   if (!rasterSelection || !rasterSelection->isFloating()) return;
304   RasterSelectionTool *tool = dynamic_cast<RasterSelectionTool *>(getTool());
305   assert(tool);
306   if (!m_isFreeDeformer) {
307     if (!m_transformUndo) return;
308     m_transformUndo->setChangedValues();
309     m_transform = TAffine();
310     TUndoManager::manager()->add(m_transformUndo);
311   } else {
312     if (!m_deformUndo) return;
313     m_deformUndo->registerRasterDeformation();
314     TUndoManager::manager()->add(m_deformUndo);
315   }
316   tool->increaseTransformationCount();
317 }
318 
319 //=============================================================================
320 // RasterRotationTool
321 //-----------------------------------------------------------------------------
322 
RasterRotationTool(RasterSelectionTool * tool)323 DragSelectionTool::RasterRotationTool::RasterRotationTool(
324     RasterSelectionTool *tool)
325     : RasterDeformTool(tool, false) {
326   m_rotation = new Rotation(this);
327 }
328 
329 //-----------------------------------------------------------------------------
330 
transform(TAffine aff,double angle)331 void DragSelectionTool::RasterRotationTool::transform(TAffine aff,
332                                                       double angle) {
333   applyTransform(aff, false);
334 }
335 
336 //-----------------------------------------------------------------------------
337 
leftButtonDrag(const TPointD & pos,const TMouseEvent & e)338 void DragSelectionTool::RasterRotationTool::leftButtonDrag(
339     const TPointD &pos, const TMouseEvent &e) {
340   m_rotation->leftButtonDrag(pos, e);
341 }
342 
343 //-----------------------------------------------------------------------------
344 
draw()345 void DragSelectionTool::RasterRotationTool::draw() { m_rotation->draw(); }
346 
347 //=============================================================================
348 // RasterFreeDeformTool
349 //-----------------------------------------------------------------------------
350 
RasterFreeDeformTool(RasterSelectionTool * tool)351 DragSelectionTool::RasterFreeDeformTool::RasterFreeDeformTool(
352     RasterSelectionTool *tool)
353     : RasterDeformTool(tool, true) {
354   m_freeDeform = new FreeDeform(this);
355 }
356 
357 //-----------------------------------------------------------------------------
358 
leftButtonDrag(const TPointD & pos,const TMouseEvent & e)359 void DragSelectionTool::RasterFreeDeformTool::leftButtonDrag(
360     const TPointD &pos, const TMouseEvent &e) {
361   m_freeDeform->leftButtonDrag(pos, e);
362 }
363 
364 //=============================================================================
365 // RasterMoveSelectionTool
366 //-----------------------------------------------------------------------------
367 
RasterMoveSelectionTool(RasterSelectionTool * tool)368 DragSelectionTool::RasterMoveSelectionTool::RasterMoveSelectionTool(
369     RasterSelectionTool *tool)
370     : RasterDeformTool(tool, false) {
371   m_moveSelection = new MoveSelection(this);
372 }
373 
374 //-----------------------------------------------------------------------------
375 
transform(TAffine aff)376 void DragSelectionTool::RasterMoveSelectionTool::transform(TAffine aff) {
377   applyTransform(aff, true);
378 }
379 
380 //-----------------------------------------------------------------------------
381 
leftButtonDown(const TPointD & pos,const TMouseEvent & e)382 void DragSelectionTool::RasterMoveSelectionTool::leftButtonDown(
383     const TPointD &pos, const TMouseEvent &e) {
384   m_moveSelection->leftButtonDown(pos, e);
385   RasterDeformTool::leftButtonDown(pos, e);
386 }
387 
388 //-----------------------------------------------------------------------------
389 
leftButtonDrag(const TPointD & pos,const TMouseEvent & e)390 void DragSelectionTool::RasterMoveSelectionTool::leftButtonDrag(
391     const TPointD &pos, const TMouseEvent &e) {
392   m_moveSelection->leftButtonDrag(pos, e);
393 }
394 
395 //=============================================================================
396 // RasterScaleTool
397 //-----------------------------------------------------------------------------
398 
RasterScaleTool(RasterSelectionTool * tool,ScaleType type)399 DragSelectionTool::RasterScaleTool::RasterScaleTool(RasterSelectionTool *tool,
400                                                     ScaleType type)
401     : RasterDeformTool(tool, true) {
402   m_scale = new Scale(this, type);
403 }
404 
405 //-----------------------------------------------------------------------------
406 
transform(int index,TPointD newPos)407 TPointD DragSelectionTool::RasterScaleTool::transform(int index,
408                                                       TPointD newPos) {
409   SelectionTool *tool = getTool();
410   TPointD scaleValue  = tool->m_deformValues.m_scaleValue;
411 
412   std::vector<FourPoints> startBboxs = m_scale->getStartBboxs();
413   FourPoints bbox =
414       m_scale->bboxScaleInCenter(index, startBboxs[0], newPos, scaleValue,
415                                  m_scale->getStartCenter(), true);
416   if (bbox == startBboxs[0]) return scaleValue;
417 
418   // Se non ho scalato rispetto al centro calcolo la posizione del nuovo centro
419   if (!m_scale->scaleInCenter())
420     tool->setCenter(m_scale->getNewCenter(index, startBboxs[0], scaleValue));
421 
422   applyTransform(bbox);
423 
424   tool->setBBox(bbox);
425 
426   return scaleValue;
427 }
428 
429 //-----------------------------------------------------------------------------
430 
leftButtonDown(const TPointD & pos,const TMouseEvent & e)431 void DragSelectionTool::RasterScaleTool::leftButtonDown(const TPointD &pos,
432                                                         const TMouseEvent &e) {
433   m_scale->leftButtonDown(pos, e);
434   RasterDeformTool::leftButtonDown(pos, e);
435 }
436 
437 //-----------------------------------------------------------------------------
438 
leftButtonDrag(const TPointD & pos,const TMouseEvent & e)439 void DragSelectionTool::RasterScaleTool::leftButtonDrag(const TPointD &pos,
440                                                         const TMouseEvent &e) {
441   m_scale->leftButtonDrag(pos, e);
442 }
443 
444 TEnv::IntVar ModifySavebox("ModifySavebox", 0);
445 TEnv::IntVar NoAntialiasing("NoAntialiasing", 0);
446 
447 //=============================================================================
448 // RasterSelectionTool
449 //-----------------------------------------------------------------------------
450 
RasterSelectionTool(int targetType)451 RasterSelectionTool::RasterSelectionTool(int targetType)
452     : SelectionTool(targetType)
453     , m_transformationCount(0)
454     , m_selectionFreeDeformer(0)
455     , m_noAntialiasing("No Antialiasing", false)
456     , m_modifySavebox("Modify Savebox", false)
457     , m_setSaveboxTool(0) {
458   m_prop.bind(m_noAntialiasing);
459   m_rasterSelection.setView(this);
460   if (m_targetType & ToonzImage) {
461     m_setSaveboxTool = new SetSaveboxTool(this);
462     m_modifySavebox.setId("ModifySavebox");
463   }
464 }
465 
466 //-----------------------------------------------------------------------------
467 
setBBox(const DragSelectionTool::FourPoints & points,int index)468 void RasterSelectionTool::setBBox(const DragSelectionTool::FourPoints &points,
469                                   int index) {
470   if (m_bboxs.empty()) return;
471   assert((int)m_bboxs.size() > index);
472   m_bboxs[index]                  = points;
473   TAffine aff                     = m_rasterSelection.getTransformation();
474   DragSelectionTool::FourPoints p = points * aff.inv();
475   m_rasterSelection.setSelectionBbox(p.getBox());
476 }
477 
478 //-----------------------------------------------------------------------------
479 
setNewFreeDeformer()480 void RasterSelectionTool::setNewFreeDeformer() {
481   if (!m_freeDeformers.empty() || isSelectionEmpty()) return;
482 
483   TImageP image = (TImageP)getImage(true);
484 
485   TToonzImageP ti  = (TToonzImageP)image;
486   TRasterImageP ri = (TRasterImageP)image;
487   if (!ti && !ri) return;
488 
489   if (!m_rasterSelection.isEditable()) return;
490 
491   if (!isFloating()) m_rasterSelection.makeFloating();
492   m_freeDeformers.push_back(
493       new RasterFreeDeformer(m_rasterSelection.getFloatingSelection()));
494   std::vector<TStroke> strokes = m_rasterSelection.getOriginalStrokes();
495   if (!strokes.empty()) {
496     TVectorImage *vi = new TVectorImage();
497     std::set<int> indices;
498     // Devo deformare anche gli strokes della selezione!!!
499     int i;
500     for (i = 0; i < (int)strokes.size(); i++) {
501       vi->addStroke(new TStroke(strokes[i]));
502       indices.insert(i);
503     }
504     m_selectionFreeDeformer = new VectorFreeDeformer(vi, indices);
505     m_selectionFreeDeformer->setPreserveThickness(true);
506   }
507 }
508 
509 //-----------------------------------------------------------------------------
510 
getSelectionFreeDeformer() const511 VectorFreeDeformer *RasterSelectionTool::getSelectionFreeDeformer() const {
512   return m_selectionFreeDeformer;
513 }
514 
515 //-----------------------------------------------------------------------------
516 
isFloating() const517 bool RasterSelectionTool::isFloating() const {
518   return m_rasterSelection.isFloating();
519 }
520 
521 //-----------------------------------------------------------------------------
522 
modifySelectionOnClick(TImageP image,const TPointD & pos,const TMouseEvent & e)523 void RasterSelectionTool::modifySelectionOnClick(TImageP image,
524                                                  const TPointD &pos,
525                                                  const TMouseEvent &e) {
526   const TXshCell &imageCell = TTool::getImageCell();
527 
528   TToonzImageP ti  = (TToonzImageP)image;
529   TRasterImageP ri = (TRasterImageP)image;
530   if (!ti && !ri) return;
531   m_rasterSelection.makeCurrent();
532   updateAction(pos, e);
533 
534   m_firstPos = m_curPos = pos;
535   if (!m_rasterSelection.isEmpty() && !m_rasterSelection.isFloating() &&
536       e.isShiftPressed() && !m_rasterSelection.isTransformed()) {
537     m_selectingRect.empty();
538     m_transformationCount = 0;
539     m_selecting           = true;
540   } else if (!m_rasterSelection.isEmpty()) {
541     m_selectingRect.empty();
542     m_selecting = false;
543     if (m_what == Outside && m_rasterSelection.isFloating()) {
544       m_rasterSelection.pasteFloatingSelection();
545     } else if (m_what == Outside && !m_rasterSelection.isFloating()) {
546       m_rasterSelection.setCurrentImage(image, imageCell);
547       m_rasterSelection.selectNone();
548       m_bboxs.clear();
549       m_selectingRect.empty();
550       m_selecting = true;
551     } else {
552       if (!m_rasterSelection.isFloating() &&
553           (m_what == Inside || m_what == ROTATION || m_what == SCALE ||
554            m_what == SCALE_X || m_what == SCALE_Y)) {
555         m_rasterSelection.makeFloating();
556         m_transformationCount = 0;
557         m_rasterSelection.setTransformationCount(0);
558       }
559     }
560   } else {
561     if (m_what == Outside) {
562       m_rasterSelection.setCurrentImage(image, imageCell);
563       m_rasterSelection.selectNone();
564       m_bboxs.clear();
565       m_selectingRect.empty();
566       m_selecting = true;
567     }
568   }
569 
570   TTool::getApplication()
571       ->getCurrentTool()
572       ->notifyToolChanged();  // Refreshes toolbar values
573 
574   invalidate();
575 }
576 
577 //-----------------------------------------------------------------------------
578 
leftButtonDown(const TPointD & pos,const TMouseEvent & e)579 void RasterSelectionTool::leftButtonDown(const TPointD &pos,
580                                          const TMouseEvent &e) {
581   if (m_setSaveboxTool && m_modifySavebox.getValue()) {
582     m_setSaveboxTool->leftButtonDown(pos);
583     return;
584   }
585   SelectionTool::leftButtonDown(pos, e);
586 }
587 
588 //-----------------------------------------------------------------------------
589 
mouseMove(const TPointD & pos,const TMouseEvent & e)590 void RasterSelectionTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
591   if (m_setSaveboxTool && m_modifySavebox.getValue()) {
592     if (!m_leftButtonMousePressed)
593       m_cursorId = m_setSaveboxTool->getCursorId(pos);
594     return;
595   }
596   SelectionTool::mouseMove(pos, e);
597 }
598 
599 //-----------------------------------------------------------------------------
600 
leftButtonDrag(const TPointD & pos,const TMouseEvent & e)601 void RasterSelectionTool::leftButtonDrag(const TPointD &pos,
602                                          const TMouseEvent &e) {
603   if (m_setSaveboxTool && m_modifySavebox.getValue()) {
604     m_setSaveboxTool->leftButtonDrag(pos);
605     invalidate();
606     return;
607   }
608   if (m_dragTool) {
609     if (!m_rasterSelection.isEditable()) return;
610 
611     m_dragTool->leftButtonDrag(pos, e);
612     invalidate();
613     return;
614   }
615 
616   TImageP image    = getImage(true);
617   TToonzImageP ti  = (TToonzImageP)image;
618   TRasterImageP ri = (TRasterImageP)image;
619   if (!ti && !ri) return;
620 
621   if (m_selecting) {
622     if (m_strokeSelectionType.getValue() == RECT_SELECTION) {
623       TDimension imageSize;
624       if (ti)
625         imageSize = ti->getSize();
626       else if (ri)
627         imageSize = ri->getRaster()->getSize();
628       TPointD p(imageSize.lx % 2 ? 0.5 : 0.0, imageSize.ly % 2 ? 0.5 : 0.0);
629       TRectD rectD(tround(std::min(m_firstPos.x, pos.x) - p.x) + p.x,
630                    tround(std::min(m_firstPos.y, pos.y) - p.y) + p.y,
631                    tround(std::max(m_firstPos.x, pos.x) - p.x) + p.x,
632                    tround(std::max(m_firstPos.y, pos.y) - p.y) + p.y);
633 
634       m_selectingRect = rectD;
635       m_bboxs.clear();
636 
637       TTool::getApplication()
638           ->getCurrentTool()
639           ->notifyToolChanged();  // Refreshes toolbar values
640 
641       invalidate();
642     } else if (m_strokeSelectionType.getValue() == FREEHAND_SELECTION) {
643       freehandDrag(pos);
644       invalidate();
645     }
646     return;
647   }
648 
649   double pixelSize        = getPixelSize();
650   TTool::Application *app = TTool::getApplication();
651   if (!app || m_justSelected || !m_selecting ||
652       tdistance2(pos, m_curPos) < 9.0 * pixelSize * pixelSize)
653     return;
654 
655   m_curPos = pos;
656 
657   if (m_strokeSelectionType.getValue() == FREEHAND_SELECTION) {
658     freehandDrag(pos);
659     invalidate();
660   } else if (m_strokeSelectionType.getValue() == RECT_SELECTION) {
661     bool selectOverlappingStroke = (m_firstPos.x > pos.x);
662     TRectD rect(m_firstPos, pos);
663     m_selectingRect = rect;
664 
665     TTool::getApplication()
666         ->getCurrentTool()
667         ->notifyToolChanged();  // Refreshes toolbar values
668 
669     invalidate();
670   }
671 }
672 
673 //-----------------------------------------------------------------------------
674 
leftButtonUp(const TPointD & pos,const TMouseEvent & e)675 void RasterSelectionTool::leftButtonUp(const TPointD &pos,
676                                        const TMouseEvent &e) {
677   if (m_setSaveboxTool && m_modifySavebox.getValue()) {
678     m_setSaveboxTool->leftButtonUp(pos);
679     invalidate();
680     return;
681   }
682   m_leftButtonMousePressed = false;
683   m_shiftPressed           = false;
684 
685   if (m_dragTool) {
686     if (!m_rasterSelection.isEditable()) {
687       delete m_dragTool;
688       m_dragTool = 0;
689       return;
690     }
691 
692     m_dragTool->leftButtonUp(pos, e);
693     delete m_dragTool;
694     m_dragTool = 0;
695     invalidate();
696     notifyImageChanged();
697     return;
698   }
699 
700   if (!m_selecting) return;
701 
702   // Se stavo modificando la selezione la completo
703 
704   TImageP image    = getImage(true);
705   TToonzImageP ti  = (TToonzImageP)image;
706   TRasterImageP ri = (TRasterImageP)image;
707   if (ti || ri) {
708     if (m_strokeSelectionType.getValue() == RECT_SELECTION) {
709       m_bboxs.push_back(m_selectingRect);
710       m_rasterSelection.select(
711           TRectD(m_selectingRect.getP00(), m_selectingRect.getP11()));
712       m_rasterSelection.setFrameId(getCurrentFid());
713       m_selectingRect.empty();
714     } else if (m_strokeSelectionType.getValue() == FREEHAND_SELECTION) {
715       closeFreehand(pos);
716       if (m_stroke->getControlPointCount() > 5) {
717         m_rasterSelection.select(*m_stroke);
718         m_rasterSelection.setFrameId(getCurrentFid());
719         m_rasterSelection.makeCurrent();
720       }
721       m_track.clear();
722     }
723   }
724   m_selecting    = false;
725   m_justSelected = false;
726   invalidate();
727 }
728 
729 //-----------------------------------------------------------------------------
730 
leftButtonDoubleClick(const TPointD & pos,const TMouseEvent & e)731 void RasterSelectionTool::leftButtonDoubleClick(const TPointD &pos,
732                                                 const TMouseEvent &e) {
733   TImageP image    = getImage(true);
734   TToonzImageP ti  = (TToonzImageP)image;
735   TRasterImageP ri = (TRasterImageP)image;
736   if (!ti && !ri) return;
737   if (m_strokeSelectionType.getValue() == POLYLINE_SELECTION &&
738       !m_polyline.empty()) {
739     closePolyline(pos);
740     if (m_stroke) {
741       m_rasterSelection.select(*m_stroke);
742       m_rasterSelection.setFrameId(getCurrentFid());
743       m_rasterSelection.makeCurrent();
744     }
745     m_selecting = false;
746     return;
747   }
748 
749   TTool::getApplication()
750       ->getCurrentTool()
751       ->notifyToolChanged();  // Refreshes toolbar values
752 }
753 
754 //-----------------------------------------------------------------------------
755 /*-- Paste後のフローティング状態の画像の描画 --*/
drawFloatingSelection()756 void RasterSelectionTool::drawFloatingSelection() {
757   double pixelSize =
758       TTool::getApplication()->getCurrentTool()->getTool()->getPixelSize();
759 
760   TAffine aff = m_rasterSelection.getTransformation();
761   glPushMatrix();
762   tglMultMatrix(aff);
763 
764   // draw m_floatingSelection
765   if (isFloating()) {
766     TRasterP floatingSelection = m_rasterSelection.getFloatingSelection();
767     TImageP app;
768     if (TRasterCM32P toonzRas = (TRasterCM32P)(floatingSelection))
769       app = TToonzImageP(toonzRas, toonzRas->getBounds());
770     if (TRaster32P fullColorRas = (TRaster32P)(floatingSelection))
771       app = TRasterImageP(fullColorRas);
772     if (TRasterGR8P grRas = (TRasterGR8P)(floatingSelection))
773       app = TRasterImageP(grRas);
774     app->setPalette(m_rasterSelection.getCurrentImage()->getPalette());
775     FourPoints points = getBBox() * aff.inv();
776     TRectD bbox       = points.getBox();
777     TPointD center((bbox.getP00() + bbox.getP11()) * 0.5);
778     if (TToonzImageP ti = (TToonzImageP)app)
779       GLRasterPainter::drawRaster(TTranslation(center), ti, false);
780     if (TRasterImageP ri = (TRasterImageP)app)
781       GLRasterPainter::drawRaster(TTranslation(center), ri, true);
782   }
783 
784   std::vector<TStroke> strokes = m_rasterSelection.getStrokes();
785   int i;
786   for (i = 0; i < (int)strokes.size(); i++) {
787     TStroke stroke = strokes[i];
788     glEnable(GL_LINE_STIPPLE);
789     glLineStipple(1, 0xF0F0);
790     tglColor(TPixel32::Black);
791     drawStrokeCenterline(stroke, pixelSize);
792     glDisable(GL_LINE_STIPPLE);
793   }
794 
795   glPopMatrix();
796 }
797 
798 //-----------------------------------------------------------------------------
799 
draw()800 void RasterSelectionTool::draw() {
801   TImageP image    = getImage(false);
802   TToonzImageP ti  = (TToonzImageP)image;
803   TRasterImageP ri = (TRasterImageP)image;
804   if (!ti && !ri) return;
805 
806   if (m_setSaveboxTool && m_modifySavebox.getValue()) {
807     m_setSaveboxTool->draw();
808     return;
809   }
810 
811   glPushMatrix();
812 
813   /*-- フローティング画像の描画 --*/
814   drawFloatingSelection();
815 
816   if (m_strokeSelectionType.getValue() == POLYLINE_SELECTION &&
817       !m_rasterSelection.isFloating())
818     drawPolylineSelection();
819   else if (m_strokeSelectionType.getValue() == FREEHAND_SELECTION &&
820            !m_rasterSelection.isFloating())
821     drawFreehandSelection();
822   if (m_rasterSelection.isEmpty()) m_bboxs.clear();
823 
824   /*-- 選択範囲の変形ハンドルの描画 --*/
825   if (getBBoxsCount() > 0) drawCommandHandle(image.getPointer());
826 
827   /*-- 選択範囲の四角形の描画 --*/
828   if (m_selecting && !m_selectingRect.isEmpty())
829     drawRectSelection(image.getPointer());
830 
831   /*-- バウンディングボックスの描画 --*/
832   /*
833 if(ti)
834 {
835    TRectD saveBox = ToonzImageUtils::convertRasterToWorld(ti->getSavebox(), ti);
836 drawRect(saveBox.enlarge(0.5)*ti->getSubsampling(), TPixel32::Black, 0x5555,
837 true);
838 }
839 */
840 
841   glPopMatrix();
842 }
843 
844 //-----------------------------------------------------------------------------
845 
getSelection()846 TSelection *RasterSelectionTool::getSelection() { return &m_rasterSelection; }
847 
848 //-----------------------------------------------------------------------------
849 
isSelectionEmpty()850 bool RasterSelectionTool::isSelectionEmpty() {
851   TImageP image    = getImage(false);
852   TToonzImageP ti  = (TToonzImageP)image;
853   TRasterImageP ri = (TRasterImageP)image;
854 
855   if (!ti && !ri) return true;
856 
857   return m_rasterSelection.isEmpty();
858 }
859 
860 //-----------------------------------------------------------------------------
861 
computeBBox()862 void RasterSelectionTool::computeBBox() {
863   TImageP image    = getImage(false);
864   TToonzImageP ti  = (TToonzImageP)image;
865   TRasterImageP ri = (TRasterImageP)image;
866   if (!ti && !ri) return;
867 
868   m_deformValues.reset();
869 
870   m_bboxs.clear();
871   m_centers.clear();
872 
873   {
874     std::vector<TStroke> strokes = m_rasterSelection.getStrokes();
875     TRectD strokesRect           = m_rasterSelection.getStrokesBound(strokes);
876     DragSelectionTool::FourPoints p;
877     p = strokesRect;
878     p = p * m_rasterSelection.getTransformation();
879     m_bboxs.push_back(p);
880     m_centers.push_back((p.getP00() + p.getP11()) * 0.5);
881     m_rasterSelection.setSelectionBbox(strokesRect);
882   }
883 
884   if (!m_freeDeformers.empty()) clearPointerContainer(m_freeDeformers);
885 
886   if (m_selectionFreeDeformer) {
887     delete m_selectionFreeDeformer;
888     m_selectionFreeDeformer = 0;
889   }
890 
891   TTool::getApplication()->getCurrentTool()->notifyToolChanged();
892 }
893 
894 //-----------------------------------------------------------------------------
895 
doOnActivate()896 void RasterSelectionTool::doOnActivate() {
897   const TXshCell &imageCell = TTool::getImageCell();
898 
899   TImageP image =
900       imageCell.getImage(false, 1);  // => See the onImageChanged() warning !
901 
902   TToonzImageP ti  = (TToonzImageP)image;
903   TRasterImageP ri = (TRasterImageP)image;
904   if (!ti && !ri) return;
905 
906   m_rasterSelection.makeCurrent();
907   m_rasterSelection.setCurrentImage(image, imageCell);
908   m_rasterSelection.selectNone();
909   m_noAntialiasing.setValue(NoAntialiasing);
910   m_rasterSelection.setNoAntialiasing(m_noAntialiasing.getValue());
911 
912   TTool::getApplication()
913       ->getCurrentTool()
914       ->notifyToolChanged();  // Refreshes toolbar values
915 }
916 
917 //-----------------------------------------------------------------------------
918 
doOnDeactivate()919 void RasterSelectionTool::doOnDeactivate() {
920   TTool::getApplication()->getCurrentSelection()->setSelection(0);
921   m_rasterSelection.setCurrentImage(0, TXshCell());
922   m_rasterSelection.selectNone();
923 }
924 
925 //-----------------------------------------------------------------------------
926 
onImageChanged()927 void RasterSelectionTool::onImageChanged() {
928   // ATTENTION: using getImage(false, 1) *works* here, but it's trickier than
929   // you could
930   // expect. It works because:
931 
932   // 1. Invoking getImage(true) after getImage(false, 1) will return the same
933   // image
934   // 2. The cached fullsampled image may be in the 'not modified' ImageManager
935   // state.
936   //    Users could then alter the required image level subsampling - but doing
937   //    so will
938   //    immediately redirect here through 'onXshLevelChanged()' (thus resetting
939   //    the subs back to 1).
940 
941   TImageP image    = getImage(false, 1);
942   TToonzImageP ti  = image;
943   TRasterImageP ri = image;
944 
945   if ((!ti && !ri) || image != m_rasterSelection.getCurrentImage())
946     m_rasterSelection.selectNone();
947 
948   TTool::getApplication()
949       ->getCurrentTool()
950       ->notifyToolChanged();  // Refreshes toolbar values
951 }
952 
953 //-----------------------------------------------------------------------------
954 
transformFloatingSelection(const TAffine & affine,const TPointD & center,const DragSelectionTool::FourPoints & points)955 void RasterSelectionTool::transformFloatingSelection(
956     const TAffine &affine, const TPointD &center,
957     const DragSelectionTool::FourPoints &points) {
958   m_rasterSelection.setTransformation(affine);
959   if (isFloating()) {
960     setBBox(points);
961     setCenter(center);
962   }
963   invalidate();
964 }
965 
966 //-----------------------------------------------------------------------------
967 
increaseTransformationCount()968 void RasterSelectionTool::increaseTransformationCount() {
969   if (m_rasterSelection.getTransformationCount() != m_transformationCount)
970     m_transformationCount = 0;
971   m_transformationCount++;
972   m_rasterSelection.setTransformationCount(m_transformationCount);
973 }
974 
975 //-----------------------------------------------------------------------------
976 
decreaseTransformationCount()977 void RasterSelectionTool::decreaseTransformationCount() {
978   m_transformationCount--;
979   m_rasterSelection.setTransformationCount(m_transformationCount);
980   if (m_rasterSelection.getTransformationCount() == 0)
981     m_rasterSelection.pasteFloatingSelection();
982 }
983 
984 //-----------------------------------------------------------------------------
985 
onActivate()986 void RasterSelectionTool::onActivate() {
987   if (m_firstTime) {
988     if (m_targetType & ToonzImage)
989       m_modifySavebox.setValue(ModifySavebox ? 1 : 0);
990   }
991 
992   SelectionTool::onActivate();
993 }
994 
995 //-----------------------------------------------------------------------------
996 
onPropertyChanged(std::string propertyName)997 bool RasterSelectionTool::onPropertyChanged(std::string propertyName) {
998   if (!m_rasterSelection.isEditable()) return false;
999 
1000   if (SelectionTool::onPropertyChanged(propertyName)) return true;
1001   if (m_targetType & ToonzImage) {
1002     ModifySavebox = (int)(m_modifySavebox.getValue());
1003     invalidate();
1004   }
1005   if (propertyName == m_noAntialiasing.getName()) {
1006     NoAntialiasing = m_noAntialiasing.getValue() ? 1 : 0;
1007     m_rasterSelection.setNoAntialiasing(m_noAntialiasing.getValue());
1008   }
1009 
1010   return true;
1011 }
1012 
1013 //-----------------------------------------------------------------------------
1014 
updateTranslation()1015 void RasterSelectionTool::updateTranslation() {
1016   if (m_targetType & ToonzImage)
1017     m_modifySavebox.setQStringName(tr("Modify Savebox"));
1018 
1019   m_noAntialiasing.setQStringName(tr("No Antialiasing"));
1020   SelectionTool::updateTranslation();
1021 }
1022 
1023 //=============================================================================
1024 
1025 RasterSelectionTool toonzRasterSelectionTool(TTool::ToonzImage);
1026 RasterSelectionTool fullColorRasterSelectionTool(TTool::RasterImage);
1027