1 #pragma once
2 
3 #ifndef FUNCTIONPANEL_H
4 #define FUNCTIONPANEL_H
5 
6 #include "tcommon.h"
7 #include "functiontreeviewer.h"
8 
9 #include <QDialog>
10 #include <set>
11 #include <cmath>
12 
13 #undef DVAPI
14 #undef DVVAR
15 #ifdef TOONZQT_EXPORTS
16 #define DVAPI DV_EXPORT_API
17 #define DVVAR DV_EXPORT_VAR
18 #else
19 #define DVAPI DV_IMPORT_API
20 #define DVVAR DV_IMPORT_VAR
21 #endif
22 
23 // forward declaration
24 class TDoubleParam;
25 class TDoubleKeyframe;
26 class TFrameHandle;
27 class FunctionSelection;
28 
29 //-----------------------------------------------------------------------------
30 
31 //! Channel edit panel (numcols + graph popup)
32 class FunctionPanel final : public QDialog {
33   Q_OBJECT
34 
35   QColor m_bgColor;
36   QColor m_valueLineColor;
37   QColor m_frameLineColor;
38   QColor m_otherCurvesColor;
39   QColor m_rulerBackground;
40 
41   Q_PROPERTY(QColor BGColor READ getBGColor WRITE setBGColor)
42   Q_PROPERTY(
43       QColor ValueLineColor READ getValueLineColor WRITE setValueLineColor)
44   Q_PROPERTY(
45       QColor FrameLineColor READ getFrameLineColor WRITE setFrameLineColor)
46   Q_PROPERTY(QColor OtherCurvesColor READ getOtherCurvesColor WRITE
47                  setOtherCurvesColor)
48   Q_PROPERTY(
49       QColor RulerBackground READ getRulerBackground WRITE setRulerBackground)
50 
51   QColor m_textColor;      // black
52   QColor m_subColor;       // white
53   QColor m_selectedColor;  // blue
54   Q_PROPERTY(QColor TextColor READ getTextColor WRITE setTextColor)
55   Q_PROPERTY(QColor SubColor READ getSubColor WRITE setSubColor)
56   Q_PROPERTY(QColor SelectedColor READ getSelectedColor WRITE setSelectedColor)
57 
58 public:
59   class DragTool;
60   enum Handle {
61     None,
62     Curve,
63     Point,
64     SpeedIn,
65     SpeedOut,
66     EaseIn,
67     EaseOut,
68     EaseInPercentage,
69     EaseOutPercentage
70   };
71 
72 private:
73   QTransform m_viewTransform;  // world -> window
74   int m_valueAxisX, m_frameAxisY, m_graphViewportY;
75   QPoint m_origin;              // axes origin (window coords)
76   QPoint m_startPos, m_oldPos;  // mouse click position, last mouse click/drag
77                                 // position (window coords)
78   bool m_isFloating = true;
79   struct Gadget {
80     Handle m_handle;
81     int m_kIndex;
82     QRect m_hitRegion;
83     QPointF m_pos, m_pointPos;
84     double m_keyframePosition;
85     FunctionTreeModel::Channel *m_channel;
86     Gadget(Handle handle, int kIndex, const QPointF &p, int rx, int ry,
87            const QPointF &pointPos = QPointF());
88   };
89   QList<Gadget> m_gadgets;
90 
91   DragTool *m_dragTool;
92   FunctionSelection *m_selection;
93   TFrameHandle *m_frameHandle;
94   FunctionTreeModel *m_functionTreeModel;
95 
96   int m_currentFrameStatus;
97 
98   struct Highlighted {
99     Handle handle;
100     int gIndex;
101   } m_highlighted;
102 
103   struct {
104     bool visible;
105     double frame, value;
106   } m_cursor;
107 
108   struct {
109     QPoint curvePos, labelPos;
110     std::string text;
111     TDoubleParam *curve;
112   } m_curveLabel;
113 
114   enum CURVE_SHAPE {
115     SMOOTH = 0,
116     FRAME_BASED  // curves with the connected polylines of integer frames
117   } m_curveShape;
118 
119 public:
120   FunctionPanel(QWidget *parent, bool isFloating = true);
121   ~FunctionPanel();
122 
setModel(FunctionTreeModel * model)123   void setModel(FunctionTreeModel *model) { m_functionTreeModel = model; };
getModel()124   FunctionTreeModel *getModel() const { return m_functionTreeModel; }
125 
getSelection()126   FunctionSelection *getSelection() const { return m_selection; }
setSelection(FunctionSelection * selection)127   void setSelection(FunctionSelection *selection) {
128     m_selection = selection;
129   }  // does NOT get ownership
130 
131   void setFrameHandle(TFrameHandle *frameHandle);
getFrameHandle()132   TFrameHandle *getFrameHandle() const { return m_frameHandle; }
133 
getViewTransform()134   QTransform getViewTransform() const { return m_viewTransform; }
setViewTransform(const QTransform & viewTransform)135   void setViewTransform(const QTransform &viewTransform) {
136     m_viewTransform = viewTransform;
137   }
138 
139   // frame pixel size / value pixel size
140   double getPixelRatio(TDoubleParam *curve) const;
141 
142   double xToFrame(double x) const;
143   double frameToX(double frame) const;
144 
145   // note: the y-unit depends on the unit (e.g. degress, inches,..) and
146   // therefore on the curve
147   double valueToY(TDoubleParam *curve, double value) const;
148   double yToValue(TDoubleParam *curve, double y) const;
149 
150   void pan(int dx, int dy);
pan(const QPoint & delta)151   void pan(const QPoint &delta) { pan(delta.x(), delta.y()); }
152 
153   void zoom(double sx, double sy, const QPoint &center);
154   void fitSelectedPoints();
155   void fitCurve();
156   void fitGraphToWindow(bool currentCurveOnly = false);
157   void fitRegion(double f0, double v0, double f1, double v1);
158 
159   QPointF getWinPos(TDoubleParam *curve, double frame, double value) const;
getWinPos(TDoubleParam * curve,const TPointD & frameValuePos)160   QPointF getWinPos(TDoubleParam *curve, const TPointD &frameValuePos) const {
161     return getWinPos(curve, frameValuePos.x, frameValuePos.y);
162   }
163   QPointF getWinPos(TDoubleParam *curve, double frame) const;
164   QPointF getWinPos(TDoubleParam *curve, const TDoubleKeyframe &kf) const;
165 
166   int getCurveDistance(TDoubleParam *curve, const QPoint &winPos);
167   TDoubleParam *findClosestCurve(const QPoint &winPos, int maxWinDistance);
168   FunctionTreeModel::Channel *findClosestChannel(const QPoint &winPos,
169                                                  int maxWinDistance);
170 
171   // returns the keyframe index (-1 if no keyframe found)
172   // int findClosestKeyframe(TDoubleParam* curve, const QPoint &winPos, Handle
173   // &handle, int maxWinDistance);
174 
175   int findClosestGadget(const QPoint &winPos, Handle &handle,
176                         int maxWinDistance);
177 
178   // creates a QPainterPath representing a curve segment, limited in [x0,x1]
179   // segmentIndex = -1 => ]-inf,first keyframe]
180   // segmentIndex = segmentCount => [last keyframe, inf[
181   QPainterPath getSegmentPainterPath(TDoubleParam *curve, int segmentIndex,
182                                      int x0, int x1);
183 
184   TDoubleParam *getCurrentCurve() const;
185 
emitKeyframeSelected(double frame)186   void emitKeyframeSelected(double frame) { emit keyframeSelected(frame); }
187 
setBGColor(const QColor & color)188   void setBGColor(const QColor &color) { m_bgColor = color; }
getBGColor()189   QColor getBGColor() const { return m_bgColor; }
setValueLineColor(const QColor & color)190   void setValueLineColor(const QColor &color) { m_valueLineColor = color; }
getValueLineColor()191   QColor getValueLineColor() const { return m_valueLineColor; }
setFrameLineColor(const QColor & color)192   void setFrameLineColor(const QColor &color) { m_frameLineColor = color; }
getFrameLineColor()193   QColor getFrameLineColor() const { return m_frameLineColor; }
setOtherCurvesColor(const QColor & color)194   void setOtherCurvesColor(const QColor &color) { m_otherCurvesColor = color; }
getOtherCurvesColor()195   QColor getOtherCurvesColor() const { return m_otherCurvesColor; }
setRulerBackground(const QColor & color)196   void setRulerBackground(const QColor &color) { m_rulerBackground = color; }
getRulerBackground()197   QColor getRulerBackground() const { return m_rulerBackground; }
setTextColor(const QColor & color)198   void setTextColor(const QColor &color) { m_textColor = color; }
getTextColor()199   QColor getTextColor() const { return m_textColor; }
setSubColor(const QColor & color)200   void setSubColor(const QColor &color) { m_subColor = color; }
getSubColor()201   QColor getSubColor() const { return m_subColor; }
setSelectedColor(const QColor & color)202   void setSelectedColor(const QColor &color) { m_selectedColor = color; }
getSelectedColor()203   QColor getSelectedColor() const { return m_selectedColor; }
204 
205 protected:
206   void updateGadgets(TDoubleParam *curve);
207 
208   void drawCurrentFrame(QPainter &);
209   void drawFrameGrid(QPainter &);
210   void drawValueGrid(QPainter &);
211   void drawOtherCurves(QPainter &);
212   void drawCurrentCurve(QPainter &);
213   void drawGroupKeyframes(QPainter &);
214 
215   void paintEvent(QPaintEvent *e) override;
216   void mousePressEvent(QMouseEvent *e) override;
217   void mouseReleaseEvent(QMouseEvent *e) override;
218   void mouseMoveEvent(QMouseEvent *e) override;
219   void wheelEvent(QWheelEvent *e) override;
220   void openContextMenu(QMouseEvent *e);
221 
222   void keyPressEvent(QKeyEvent *e) override;
223   void enterEvent(QEvent *) override;
224   void leaveEvent(QEvent *) override;
225 
226   void showEvent(QShowEvent *) override;
227   void hideEvent(QHideEvent *) override;
228 
229 public slots:
230   void onFrameSwitched();
231 
232 signals:
233   // void segmentSelected(TDoubleParam *curve, int segmentIndex);
234   void keyframeSelected(double frame);
235 };
236 
237 #endif
238