1 
2 
3 #include "functionpaneltools.h"
4 
5 // TnzQt includes
6 #include "toonzqt/functionselection.h"
7 
8 // TnzLib includes
9 #include "toonz/tframehandle.h"
10 
11 // TnzCore includes
12 #include "tundo.h"
13 
14 // Qt includes
15 #include <QPainter>
16 #include <QMouseEvent>
17 
18 //=============================================================================
19 
MoveFrameDragTool(FunctionPanel * panel,TFrameHandle * frameHandle)20 MoveFrameDragTool::MoveFrameDragTool(FunctionPanel *panel,
21                                      TFrameHandle *frameHandle)
22     : m_panel(panel), m_frameHandle(frameHandle) {}
23 
drag(QMouseEvent * e)24 void MoveFrameDragTool::drag(QMouseEvent *e) {
25   double frame = m_panel->xToFrame(e->pos().x());
26   m_panel->getSelection()->deselectAllKeyframes();
27   m_frameHandle->setFrame(frame);
28 }
29 
30 //=============================================================================
31 
PanDragTool(FunctionPanel * panel,bool xLocked,bool yLocked)32 PanDragTool::PanDragTool(FunctionPanel *panel, bool xLocked, bool yLocked)
33     : m_panel(panel), m_xLocked(xLocked), m_yLocked(yLocked) {}
34 
click(QMouseEvent * e)35 void PanDragTool::click(QMouseEvent *e) { m_oldPos = e->pos(); }
36 
drag(QMouseEvent * e)37 void PanDragTool::drag(QMouseEvent *e) {
38   QPoint delta = e->pos() - m_oldPos;
39   if (m_xLocked) delta.setX(0);
40   if (m_yLocked) delta.setY(0);
41   m_panel->pan(delta);
42   m_oldPos = e->pos();
43 }
44 
45 //=============================================================================
46 /*--- Ruler部分ドラッグによるズーム ---*/
click(QMouseEvent * e)47 void ZoomDragTool::click(QMouseEvent *e) {
48   m_startPos = m_oldPos = m_startPos = e->pos();
49 }
50 
drag(QMouseEvent * e)51 void ZoomDragTool::drag(QMouseEvent *e) {
52   QPoint delta = e->pos() - m_oldPos;
53   m_oldPos     = e->pos();
54   double sx = 1, sy = 1;
55   // reflect horizontal drag for frame zoom
56   double zoomFactor =
57       exp(-0.0075 * ((m_zoomType == FrameZoom) ? -delta.x() : delta.y()));
58   if (m_zoomType == FrameZoom)
59     sx = zoomFactor;
60   else
61     sy = zoomFactor;
62   m_panel->zoom(sx, sy, m_startPos);
63 }
64 
release(QMouseEvent * e)65 void ZoomDragTool::release(QMouseEvent *e) {
66   if ((e->pos() - m_startPos).manhattanLength() < 2) {
67     double frame = m_panel->xToFrame(e->pos().x());
68     if (m_panel->getFrameHandle()) m_panel->getFrameHandle()->setFrame(frame);
69   }
70 }
71 
72 //=============================================================================
73 
click(QMouseEvent * e)74 void RectSelectTool::click(QMouseEvent *e) {
75   m_startPos = e->pos();
76   m_rect     = QRect();
77 }
78 
drag(QMouseEvent * e)79 void RectSelectTool::drag(QMouseEvent *e) {
80   m_rect = QRect(m_startPos, e->pos()).normalized();
81   m_panel->getSelection()->deselectAllKeyframes();
82   for (int i = 0; i < m_curve->getKeyframeCount(); i++) {
83     QPointF p = m_panel->getWinPos(m_curve, m_curve->getKeyframe(i));
84     if (m_rect.contains(tround(p.x()), tround(p.y())))
85       m_panel->getSelection()->select(m_curve, i);
86   }
87   m_panel->update();
88 }
89 
release(QMouseEvent * e)90 void RectSelectTool::release(QMouseEvent *e) { m_panel->update(); }
91 
draw(QPainter & painter)92 void RectSelectTool::draw(QPainter &painter) {
93   painter.setPen(Qt::white);
94   painter.setBrush(QColor(255, 255, 255, 127));
95   if (!m_rect.isEmpty()) painter.drawRect(m_rect);
96 }
97 
98 //=============================================================================
99 
MovePointDragTool(FunctionPanel * panel,TDoubleParam * curve)100 MovePointDragTool::MovePointDragTool(FunctionPanel *panel, TDoubleParam *curve)
101     : m_panel(panel)
102     , m_deltaFrame(0)
103     , m_speed0Length(0)
104     , m_speed0Index(-1)
105     , m_speed1Length(0)
106     , m_speed1Index(-1)
107     , m_groupEnabled(false)
108     , m_selection(0) {
109   // This undo block is closed in the destructor
110   TUndoManager::manager()->beginBlock();
111 
112   if (curve) {
113     KeyframeSetter *setter = new KeyframeSetter(curve);
114     m_setters.push_back(setter);
115   } else {
116     m_groupEnabled           = true;
117     FunctionTreeModel *model = panel->getModel();
118     for (int i = 0; i < model->getActiveChannelCount(); i++) {
119       FunctionTreeModel::Channel *channel = model->getActiveChannel(i);
120       if (channel && channel->getParam()) {
121         TDoubleParam *curve    = channel->getParam();
122         KeyframeSetter *setter = new KeyframeSetter(curve);
123         m_setters.push_back(setter);
124       }
125     }
126   }
127 }
128 
129 //-----------------------------------------------------------------------------
130 
~MovePointDragTool()131 MovePointDragTool::~MovePointDragTool() {
132   for (int i = 0; i < (int)m_setters.size(); i++) delete m_setters[i];
133   m_setters.clear();
134   TUndoManager::manager()->endBlock();
135 }
136 
137 //-----------------------------------------------------------------------------
138 
addKeyframe2(int kIndex)139 void MovePointDragTool::addKeyframe2(int kIndex) {
140   assert(m_setters.size() == 1);
141   if (m_setters.size() == 1) m_setters[0]->selectKeyframe(kIndex);
142 }
143 
144 //-----------------------------------------------------------------------------
145 
createKeyframe(double frame)146 void MovePointDragTool::createKeyframe(double frame) {
147   for (int i = 0; i < (int)m_setters.size(); i++) {
148     KeyframeSetter *setter = m_setters[i];
149     int kIndex             = setter->createKeyframe(tround(frame));
150     setter->selectKeyframe(kIndex);
151   }
152 }
153 
154 //-----------------------------------------------------------------------------
155 
selectKeyframes(double frame)156 void MovePointDragTool::selectKeyframes(double frame) {
157   for (int i = 0; i < (int)m_setters.size(); i++) {
158     KeyframeSetter *setter = m_setters[i];
159     TDoubleParam *curve    = setter->getCurve();
160     setter->setPixelRatio(m_panel->getPixelRatio(curve));
161     int kIndex = curve->getClosestKeyframe(frame);
162     if (kIndex >= 0) {
163       double kf = curve->keyframeIndexToFrame(kIndex);
164       if (fabs(kf - frame) < 0.01) setter->selectKeyframe(kIndex);
165     }
166   }
167 }
168 
169 //-----------------------------------------------------------------------------
170 
setSelection(FunctionSelection * selection)171 void MovePointDragTool::setSelection(FunctionSelection *selection) {
172   if (selection) {
173     assert(m_setters.size() == 1);
174     if (m_setters.size() == 1) {
175       TDoubleParam *curve = m_setters[0]->getCurve();
176       assert(curve);
177       if (curve) {
178         m_selection = selection;
179         for (int i = 0; i < curve->getKeyframeCount(); i++)
180           if (selection->isSelected(curve, i)) addKeyframe2(i);
181       }
182     }
183   } else
184     m_selection = selection;
185 }
186 
187 //-----------------------------------------------------------------------------
188 
click(QMouseEvent * e)189 void MovePointDragTool::click(QMouseEvent *e) {
190   m_startPos = m_oldPos = e->pos();
191   m_deltaFrame          = 0;
192   double frame          = m_panel->xToFrame(e->pos().x());
193 
194   for (int i = 0; i < (int)m_setters.size(); i++) {
195     KeyframeSetter *setter = m_setters[i];
196     TDoubleParam *curve    = setter->getCurve();
197     setter->setPixelRatio(m_panel->getPixelRatio(curve));
198     if (!m_groupEnabled) {
199       int kIndex = curve->getClosestKeyframe(frame);
200       if (kIndex >= 0) {
201         double kf = curve->keyframeIndexToFrame(kIndex);
202         if (fabs(kf - frame) < 1) setter->selectKeyframe(kIndex);
203       }
204     }
205   }
206 }
207 
208 //-----------------------------------------------------------------------------
209 
drag(QMouseEvent * e)210 void MovePointDragTool::drag(QMouseEvent *e) {
211   QPoint pos = e->pos();
212 
213   // if shift is pressed then apply constraints (only horizontal or vertical
214   // moves)
215   if (e->modifiers() & Qt::ShiftModifier) {
216     QPoint delta = e->pos() - m_startPos;
217     if (abs(delta.x()) > abs(delta.y()))
218       pos.setY(m_startPos.y());
219     else
220       pos.setX(m_startPos.x());
221   }
222 
223   if (m_groupEnabled) pos.setY(m_startPos.y());
224 
225   QPoint oldPos = m_oldPos;
226   m_oldPos      = pos;
227 
228   // compute frame increment. it must be an integer
229   double totalDFrame =
230       tround(m_panel->xToFrame(pos.x()) - m_panel->xToFrame(m_startPos.x()));
231   double dFrame = totalDFrame - m_deltaFrame;
232   m_deltaFrame  = totalDFrame;
233 
234   for (int i = 0; i < (int)m_setters.size(); i++) {
235     KeyframeSetter *setter = m_setters[i];
236     TDoubleParam *curve    = setter->getCurve();
237 
238     // compute value increment
239     double dValue = m_panel->yToValue(curve, pos.y()) -
240                     m_panel->yToValue(curve, oldPos.y());
241 
242     setter->moveKeyframes(dFrame, dValue);
243   }
244   if (m_selection != 0 && m_setters.size() == 1) {
245     KeyframeSetter *setter = m_setters[0];
246 
247     m_selection->deselectAllKeyframes();
248     for (int i = 0; i < setter->getCurve()->getKeyframeCount(); i++)
249       if (setter->isSelected(i)) m_selection->select(setter->getCurve(), i);
250   }
251 
252   m_panel->update();
253 }
254 
255 //-----------------------------------------------------------------------------
256 
release(QMouseEvent * e)257 void MovePointDragTool::release(QMouseEvent *e) {}
258 
259 //=============================================================================
260 
MoveHandleDragTool(FunctionPanel * panel,TDoubleParam * curve,int kIndex,Handle handle)261 MoveHandleDragTool::MoveHandleDragTool(FunctionPanel *panel,
262                                        TDoubleParam *curve, int kIndex,
263                                        Handle handle)
264     : m_panel(panel)
265     , m_curve(curve)
266     , m_kIndex(kIndex)
267     , m_handle(handle)
268     , m_deltaFrame(0)
269     , m_setter(curve, kIndex)
270     , m_segmentWidth(0)
271     , m_channelGroup(0) {}
272 
273 //-----------------------------------------------------------------------------
274 
click(QMouseEvent * e)275 void MoveHandleDragTool::click(QMouseEvent *e) {
276   m_startPos = e->pos();
277   // m_startPos = m_oldPos = e->pos();
278   m_deltaFrame       = 0;
279   m_keyframe         = m_curve->getKeyframe(m_kIndex);
280   m_keyframe.m_value = m_curve->getValue(m_keyframe.m_frame);
281   if (m_handle == FunctionPanel::SpeedIn)
282     m_keyframe.m_value = m_curve->getValue(m_keyframe.m_frame, true);
283 
284   if (m_channelGroup) {
285     for (int i = 0; i < m_channelGroup->getChildCount(); i++) {
286       TreeModel::Item *child = m_channelGroup->getChild(i);
287       FunctionTreeModel::Channel *channel =
288           dynamic_cast<FunctionTreeModel::Channel *>(child);
289       if (channel && m_curve != channel->getParam()) {
290         if (channel->getParam()->isKeyframe(m_keyframe.m_frame)) {
291         }
292       }
293     }
294   }
295 
296   if (m_handle == FunctionPanel::EaseInPercentage && m_kIndex > 0) {
297     double previousFrame = m_curve->keyframeIndexToFrame(m_kIndex - 1);
298     m_segmentWidth       = m_keyframe.m_frame - previousFrame;
299   }
300   if (m_handle == FunctionPanel::EaseOutPercentage &&
301       m_kIndex + 1 < m_curve->getKeyframeCount()) {
302     double nextFrame = m_curve->keyframeIndexToFrame(m_kIndex + 1);
303     m_segmentWidth   = nextFrame - m_keyframe.m_frame;
304   }
305   TPointD speed;
306 
307   if (m_keyframe.m_linkedHandles) {
308     if (m_handle == FunctionPanel::SpeedIn &&
309         m_kIndex + 1 < m_curve->getKeyframeCount() &&
310         (m_keyframe.m_type != TDoubleKeyframe::SpeedInOut &&
311          (m_keyframe.m_type != TDoubleKeyframe::Expression ||
312           m_keyframe.m_expressionText.find("cycle") == std::string::npos)))
313       speed = m_curve->getSpeedIn(m_kIndex);
314     else if (m_handle == FunctionPanel::SpeedOut &&
315              m_keyframe.m_prevType != TDoubleKeyframe::SpeedInOut &&
316              m_kIndex > 0)
317       speed = m_curve->getSpeedOut(m_kIndex);
318   }
319   if (norm2(speed) > 0.001) {
320     QPointF a = m_panel->getWinPos(m_curve, speed) -
321                 m_panel->getWinPos(m_curve, TPointD());
322     double aa = 1.0 / sqrt(a.x() * a.x() + a.y() * a.y());
323     m_nSpeed  = QPointF(-a.y() * aa, a.x() * aa);
324   } else
325     m_nSpeed = QPointF();
326   m_setter.setPixelRatio(m_panel->getPixelRatio(m_curve));
327 }
328 
329 //-----------------------------------------------------------------------------
330 
drag(QMouseEvent * e)331 void MoveHandleDragTool::drag(QMouseEvent *e) {
332   if (!m_curve) return;
333   QPoint pos = e->pos();
334 
335   // if shift is pressed then apply constraints (only horizontal or vertical
336   // moves)
337   if (e->modifiers() & Qt::ShiftModifier) {
338     QPoint delta = e->pos() - m_startPos;
339     if (abs(delta.x()) > abs(delta.y()))
340       pos.setY(m_startPos.y());
341     else
342       pos.setX(m_startPos.x());
343   }
344 
345   // QPoint oldPos = m_oldPos;
346   // m_oldPos = pos;
347 
348   QPointF p0 = m_panel->getWinPos(m_curve, m_keyframe);
349   QPointF posF(pos);
350 
351   if (m_nSpeed != QPointF(0, 0)) {
352     QPointF delta = posF - p0;
353     posF -= m_nSpeed * (delta.x() * m_nSpeed.x() + delta.y() * m_nSpeed.y());
354     if ((m_handle == FunctionPanel::SpeedIn && posF.x() > p0.x()) ||
355         (m_handle == FunctionPanel::SpeedOut && posF.x() < p0.x()))
356       posF = p0;
357   } else {
358     if ((m_handle == FunctionPanel::SpeedIn && posF.x() > p0.x()) ||
359         (m_handle == FunctionPanel::SpeedOut && posF.x() < p0.x()))
360       posF.setX(p0.x());
361   }
362 
363   double frame = m_panel->xToFrame(posF.x());
364   double value = m_panel->yToValue(m_curve, posF.y());
365   TPointD handlePos(frame - m_keyframe.m_frame, value - m_keyframe.m_value);
366   switch (m_handle) {
367   case FunctionPanel::SpeedIn:
368     if (m_keyframe.m_type != TDoubleKeyframe::SpeedInOut) {
369     }
370     m_setter.setSpeedIn(handlePos);
371     break;
372   case FunctionPanel::SpeedOut:
373     m_setter.setSpeedOut(handlePos);
374     break;
375   case FunctionPanel::EaseIn:
376     m_setter.setEaseIn(handlePos.x);
377     break;
378   case FunctionPanel::EaseOut:
379     m_setter.setEaseOut(handlePos.x);
380     break;
381   case FunctionPanel::EaseInPercentage:
382     if (m_segmentWidth > 0)
383       m_setter.setEaseIn(100.0 * handlePos.x / m_segmentWidth);
384     break;
385   case FunctionPanel::EaseOutPercentage:
386     if (m_segmentWidth > 0)
387       m_setter.setEaseOut(100.0 * handlePos.x / m_segmentWidth);
388     break;
389   case 100:
390   case 101:
391   case 102:
392     break;
393   default:
394     assert(0);
395   }
396   m_panel->update();
397 }
398 
399 //-----------------------------------------------------------------------------
400 
release(QMouseEvent * e)401 void MoveHandleDragTool::release(QMouseEvent *e) {}
402 
403 //=============================================================================
404 
405 //-----------------------------------------------------------------------------
406 
MoveGroupHandleDragTool(FunctionPanel * panel,double keyframePosition,Handle handle)407 MoveGroupHandleDragTool::MoveGroupHandleDragTool(FunctionPanel *panel,
408                                                  double keyframePosition,
409                                                  Handle handle)
410     : m_panel(panel), m_keyframePosition(keyframePosition), m_handle(handle) {
411   TUndoManager::manager()->beginBlock();
412 }
413 
414 //-----------------------------------------------------------------------------
415 
~MoveGroupHandleDragTool()416 MoveGroupHandleDragTool::~MoveGroupHandleDragTool() {
417   for (int i = 0; i < (int)m_setters.size(); i++) delete m_setters[i].second;
418   m_setters.clear();
419   TUndoManager::manager()->endBlock();
420 }
421 
422 //-----------------------------------------------------------------------------
423 
click(QMouseEvent * e)424 void MoveGroupHandleDragTool::click(QMouseEvent *e) {
425   for (int i = 0; i < (int)m_setters.size(); i++) delete m_setters[i].second;
426   m_setters.clear();
427 
428   FunctionTreeModel *model = m_panel->getModel();
429   for (int i = 0; i < model->getActiveChannelCount(); i++) {
430     FunctionTreeModel::Channel *channel = model->getActiveChannel(i);
431     if (channel && channel->getParam()) {
432       TDoubleParam *curve    = channel->getParam();
433       int kIndex             = curve->getClosestKeyframe(m_keyframePosition);
434       KeyframeSetter *setter = new KeyframeSetter(curve, kIndex);
435       setter->setPixelRatio(m_panel->getPixelRatio(curve));
436       TDoubleKeyframe kf = curve->getKeyframe(kIndex);
437       m_setters.push_back(std::make_pair(kf, setter));
438     }
439   }
440 }
441 
442 //-----------------------------------------------------------------------------
443 
drag(QMouseEvent * e)444 void MoveGroupHandleDragTool::drag(QMouseEvent *e) {
445   //  if(!m_curve) return;
446   QPoint pos = e->pos();
447   QPointF posF(pos);
448 
449   /*
450 if(m_nSpeed != QPointF(0,0))
451 {
452 QPointF delta = posF-p0;
453 posF -= m_nSpeed*(delta.x()*m_nSpeed.x()+delta.y()*m_nSpeed.y());
454 if(  m_handle == FunctionPanel::SpeedIn && posF.x()>p0.x()
455 || m_handle == FunctionPanel::SpeedOut && posF.x()<p0.x())
456 posF = p0;
457 }
458 else
459 {
460 if(  m_handle == FunctionPanel::SpeedIn && posF.x()>p0.x()
461 || m_handle == FunctionPanel::SpeedOut && posF.x()<p0.x())
462 posF.setX(p0.x());
463 }
464 */
465 
466   double frame = m_panel->xToFrame(posF.x());
467 
468   for (int i = 0; i < (int)m_setters.size(); i++) {
469     TDoubleKeyframe kf     = m_setters[i].first;
470     KeyframeSetter *setter = m_setters[i].second;
471 
472     if (m_handle == 101)  // why the magic numbers... use enums!
473     {
474       kf.m_speedOut.x = frame - kf.m_frame;
475 
476       switch (kf.m_type) {
477       case TDoubleKeyframe::SpeedInOut:
478         setter->setSpeedOut(kf.m_speedOut);
479         break;
480       case TDoubleKeyframe::EaseInOut:
481         setter->setEaseOut(kf.m_speedOut.x);
482         break;
483       default:
484         assert(false);
485       }
486     } else if (m_handle == 102)  // aagghhrrr
487     {
488       kf.m_speedIn.x = frame - kf.m_frame;
489 
490       switch (kf.m_prevType) {
491       case TDoubleKeyframe::SpeedInOut:
492         setter->setSpeedIn(kf.m_speedIn);
493         break;
494       case TDoubleKeyframe::EaseInOut:
495         setter->setEaseIn(kf.m_speedIn.x);
496         break;
497       default:
498         assert(false);
499       }
500     }
501   }
502 
503   /*
504 switch(m_handle)
505 {
506 
507 
508 case FunctionPanel::SpeedIn:
509 if(m_keyframe.m_type != TDoubleKeyframe::SpeedInOut)
510 {
511 
512 }
513 m_setter.setSpeedIn(handlePos);
514 break;
515 case FunctionPanel::SpeedOut:m_setter.setSpeedOut(handlePos); break;
516 case FunctionPanel::EaseIn:m_setter.setEaseIn(handlePos.x); break;
517 case FunctionPanel::EaseOut:m_setter.setEaseOut(handlePos.x); break;
518 case FunctionPanel::EaseInPercentage:
519 if(m_segmentWidth>0)
520 m_setter.setEaseIn(100.0*handlePos.x/m_segmentWidth);
521 break;
522 case FunctionPanel::EaseOutPercentage:
523 if(m_segmentWidth>0)
524 m_setter.setEaseOut(100.0*handlePos.x/m_segmentWidth);
525 break;
526 case 100:
527 case 101:
528 case 102:
529 break;
530 default:assert(0);
531 }
532 */
533   m_panel->update();
534 }
535 
536 //-----------------------------------------------------------------------------
537 
release(QMouseEvent * e)538 void MoveGroupHandleDragTool::release(QMouseEvent *e) {
539   for (int i = 0; i < (int)m_setters.size(); i++) delete m_setters[i].second;
540   m_setters.clear();
541 }
542