#pragma once #ifndef FUNCTIONPANEL_H #define FUNCTIONPANEL_H #include "tcommon.h" #include "functiontreeviewer.h" #include #include #include #undef DVAPI #undef DVVAR #ifdef TOONZQT_EXPORTS #define DVAPI DV_EXPORT_API #define DVVAR DV_EXPORT_VAR #else #define DVAPI DV_IMPORT_API #define DVVAR DV_IMPORT_VAR #endif // forward declaration class TDoubleParam; class TDoubleKeyframe; class TFrameHandle; class FunctionSelection; //----------------------------------------------------------------------------- //! Channel edit panel (numcols + graph popup) class FunctionPanel final : public QDialog { Q_OBJECT QColor m_bgColor; QColor m_valueLineColor; QColor m_frameLineColor; QColor m_otherCurvesColor; QColor m_rulerBackground; Q_PROPERTY(QColor BGColor READ getBGColor WRITE setBGColor) Q_PROPERTY( QColor ValueLineColor READ getValueLineColor WRITE setValueLineColor) Q_PROPERTY( QColor FrameLineColor READ getFrameLineColor WRITE setFrameLineColor) Q_PROPERTY(QColor OtherCurvesColor READ getOtherCurvesColor WRITE setOtherCurvesColor) Q_PROPERTY( QColor RulerBackground READ getRulerBackground WRITE setRulerBackground) QColor m_textColor; // black QColor m_subColor; // white QColor m_selectedColor; // blue Q_PROPERTY(QColor TextColor READ getTextColor WRITE setTextColor) Q_PROPERTY(QColor SubColor READ getSubColor WRITE setSubColor) Q_PROPERTY(QColor SelectedColor READ getSelectedColor WRITE setSelectedColor) public: class DragTool; enum Handle { None, Curve, Point, SpeedIn, SpeedOut, EaseIn, EaseOut, EaseInPercentage, EaseOutPercentage }; private: QTransform m_viewTransform; // world -> window int m_valueAxisX, m_frameAxisY, m_graphViewportY; QPoint m_origin; // axes origin (window coords) QPoint m_startPos, m_oldPos; // mouse click position, last mouse click/drag // position (window coords) bool m_isFloating = true; bool m_spacePressed = false; struct Gadget { Handle m_handle; int m_kIndex; QRect m_hitRegion; QPointF m_pos, m_pointPos; double m_keyframePosition; FunctionTreeModel::Channel *m_channel; Gadget(Handle handle, int kIndex, const QPointF &p, int rx, int ry, const QPointF &pointPos = QPointF()); }; QList m_gadgets; DragTool *m_dragTool; FunctionSelection *m_selection; TFrameHandle *m_frameHandle; FunctionTreeModel *m_functionTreeModel; int m_currentFrameStatus; struct Highlighted { Handle handle; int gIndex; } m_highlighted; struct { bool visible; double frame, value; } m_cursor; struct { QPoint curvePos, labelPos; std::string text; TDoubleParam *curve; } m_curveLabel; enum CURVE_SHAPE { SMOOTH = 0, FRAME_BASED // curves with the connected polylines of integer frames } m_curveShape; public: FunctionPanel(QWidget *parent, bool isFloating = true); ~FunctionPanel(); void setModel(FunctionTreeModel *model) { m_functionTreeModel = model; }; FunctionTreeModel *getModel() const { return m_functionTreeModel; } FunctionSelection *getSelection() const { return m_selection; } void setSelection(FunctionSelection *selection) { m_selection = selection; } // does NOT get ownership void setFrameHandle(TFrameHandle *frameHandle); TFrameHandle *getFrameHandle() const { return m_frameHandle; } QTransform getViewTransform() const { return m_viewTransform; } void setViewTransform(const QTransform &viewTransform) { m_viewTransform = viewTransform; } // frame pixel size / value pixel size double getPixelRatio(TDoubleParam *curve) const; double xToFrame(double x) const; double frameToX(double frame) const; // note: the y-unit depends on the unit (e.g. degress, inches,..) and // therefore on the curve double valueToY(TDoubleParam *curve, double value) const; double yToValue(TDoubleParam *curve, double y) const; void pan(int dx, int dy); void pan(const QPoint &delta) { pan(delta.x(), delta.y()); } void zoom(double sx, double sy, const QPoint ¢er); void fitSelectedPoints(); void fitCurve(); void fitGraphToWindow(bool currentCurveOnly = false); void fitRegion(double f0, double v0, double f1, double v1); QPointF getWinPos(TDoubleParam *curve, double frame, double value) const; QPointF getWinPos(TDoubleParam *curve, const TPointD &frameValuePos) const { return getWinPos(curve, frameValuePos.x, frameValuePos.y); } QPointF getWinPos(TDoubleParam *curve, double frame) const; QPointF getWinPos(TDoubleParam *curve, const TDoubleKeyframe &kf) const; int getCurveDistance(TDoubleParam *curve, const QPoint &winPos); TDoubleParam *findClosestCurve(const QPoint &winPos, int maxWinDistance); FunctionTreeModel::Channel *findClosestChannel(const QPoint &winPos, int maxWinDistance); // returns the keyframe index (-1 if no keyframe found) // int findClosestKeyframe(TDoubleParam* curve, const QPoint &winPos, Handle // &handle, int maxWinDistance); int findClosestGadget(const QPoint &winPos, Handle &handle, int maxWinDistance); // creates a QPainterPath representing a curve segment, limited in [x0,x1] // segmentIndex = -1 => ]-inf,first keyframe] // segmentIndex = segmentCount => [last keyframe, inf[ QPainterPath getSegmentPainterPath(TDoubleParam *curve, int segmentIndex, int x0, int x1); TDoubleParam *getCurrentCurve() const; void emitKeyframeSelected(double frame) { emit keyframeSelected(frame); } void setBGColor(const QColor &color) { m_bgColor = color; } QColor getBGColor() const { return m_bgColor; } void setValueLineColor(const QColor &color) { m_valueLineColor = color; } QColor getValueLineColor() const { return m_valueLineColor; } void setFrameLineColor(const QColor &color) { m_frameLineColor = color; } QColor getFrameLineColor() const { return m_frameLineColor; } void setOtherCurvesColor(const QColor &color) { m_otherCurvesColor = color; } QColor getOtherCurvesColor() const { return m_otherCurvesColor; } void setRulerBackground(const QColor &color) { m_rulerBackground = color; } QColor getRulerBackground() const { return m_rulerBackground; } void setTextColor(const QColor &color) { m_textColor = color; } QColor getTextColor() const { return m_textColor; } void setSubColor(const QColor &color) { m_subColor = color; } QColor getSubColor() const { return m_subColor; } void setSelectedColor(const QColor &color) { m_selectedColor = color; } QColor getSelectedColor() const { return m_selectedColor; } protected: void updateGadgets(TDoubleParam *curve); void drawCurrentFrame(QPainter &); void drawFrameGrid(QPainter &); void drawValueGrid(QPainter &); void drawOtherCurves(QPainter &); void drawCurrentCurve(QPainter &); void drawGroupKeyframes(QPainter &); void paintEvent(QPaintEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void mouseDoubleClickEvent(QMouseEvent *) override; void wheelEvent(QWheelEvent *e) override; void openContextMenu(QMouseEvent *e); void keyPressEvent(QKeyEvent *e) override; void keyReleaseEvent(QKeyEvent *e) override; void enterEvent(QEvent *) override; void leaveEvent(QEvent *) override; void showEvent(QShowEvent *) override; void hideEvent(QHideEvent *) override; QColor getChannelColor(QString name, bool active); public slots: void onFrameSwitched(); void onFitCalled(); signals: // void segmentSelected(TDoubleParam *curve, int segmentIndex); void keyframeSelected(double frame); }; #endif