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