#pragma once #ifndef FUNCTIONSELECTION_H #define FUNCTIONSELECTION_H #include "tcommon.h" #include "functiontreeviewer.h" #include "toonzqt/selection.h" #include "toonzqt/dvmimedata.h" #include "tdoublekeyframe.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 TFrameHandle; //----------------------------------------------------------------------------- class ColumnToCurveMapper { public: virtual TDoubleParam *getCurve(int columnIndex) const = 0; }; //----------------------------------------------------------------------------- class FunctionSelection final : public QObject, public TSelection { Q_OBJECT QRect m_selectedCells; // yrange = rowrange of the selected keyframes; // xrange = columnrange (functionsheet only) QList>> m_selectedKeyframes; // first = curve, second = set of selected keyframes index int m_selectedSegment; // index of the first keyframe of the segment; -1 if // no segment selected // (functionpanel only) // assert(m_selectedSegment<0 || m_selectedKeyframes.size()==1) TFrameHandle *m_frameHandle; ColumnToCurveMapper *m_columnToCurveMapper; int getCurveIndex(TDoubleParam *curve) const; // finds i : m_selectedKeyframes[i].first == curve //-1 if curve not found int touchCurveIndex(TDoubleParam *curve); // as getCurve(); if curve not found then add it public: FunctionSelection(); ~FunctionSelection(); void setFrameHandle(TFrameHandle *frameHandle) { m_frameHandle = frameHandle; } // function graph void selectCurve(TDoubleParam *curve); void deselectAllKeyframes(); // function sheet QRect getSelectedCells() const { return m_selectedCells; } void selectCells(const QRect &selectedCells, const QList &curves); void selectCells(const QRect &selectedCells); void deselectAllCells(); bool isEmpty() const override { return m_selectedKeyframes.empty(); } void selectNone() override; void select(TDoubleParam *curve, int k); bool isSelected(TDoubleParam *curve, int k) const; void selectSegment(TDoubleParam *, int k, QRect selectedCells = QRect()); // note: if a segment is // selected then also the // segment ends are // selected int getSelectedKeyframeCount() const; QPair getSelectedKeyframe(int index) const; // if index<0 || index>=getSelectedKeyframeCount() returns (0,-1) QPair getSelectedSegment() const; // if no segment is selected returns (0,-1) bool isSegmentSelected(TDoubleParam *, int k) const; void setColumnToCurveMapper(ColumnToCurveMapper *mapper); // gets ownership TDoubleParam *getCurveFromColumn(int columnIndex) const { return m_columnToCurveMapper ? m_columnToCurveMapper->getCurve(columnIndex) : 0; } void enableCommands() override; void doCopy(); void doPaste(); void doCut(); void doDelete(); void insertCells(); // if inclusive == true, consider all segments overlapping the selection void setStep(int, bool inclusive = true); void setStep1() { setStep(1); } void setStep2() { setStep(2); } void setStep3() { setStep(3); } void setStep4() { setStep(4); } // return step if all the selected segments has the same value. // return -1 if the selection does not overlap any segments // return 0 if the step value is uneven in the selection // if inclusive == true, consider all segments overlapping the selection int getCommonStep(bool inclusive = true); void setSegmentType(TDoubleKeyframe::Type type, bool inclusive = true); // return TDoubleKeyframe::Type value if the selected segments has the same // interpolation type. return -1 if the selection does not overlap any // segments return 0 (TDoubleKeyframe::None) if the interpolation is not // identical in the selection if inclusive == true, consider all segments // overlapping the selection int getCommonSegmentType(bool inclusive = true); signals: void selectionChanged(); }; //----------------------------------------------------------------------------- class FunctionKeyframesData final : public DvMimeData { public: FunctionKeyframesData(); ~FunctionKeyframesData(); typedef std::vector Keyframes; void setColumnCount(int columnCount); int getColumnCount() const { return (int)m_keyframes.size(); } int getRowCount() const; void getData(int columnIndex, TDoubleParam *curve, double frame, const QSet &kIndices); void setData(int columnIndex, TDoubleParam *curve, double frame) const; const Keyframes &getKeyframes(int columnIndex) const; DvMimeData *clone() const override; bool isCircularReferenceFree(int columnIndex, TDoubleParam *curve) const; private: std::vector m_keyframes; }; #endif