1 #pragma once 2 3 #ifndef FUNCTIONTREEMODEL_H 4 #define FUNCTIONTREEMODEL_H 5 6 // TnzCore includes 7 #include "tcommon.h" 8 #include "tdoubleparam.h" 9 10 // TnzQt includes 11 #include "treemodel.h" 12 13 // Qt includes 14 #include <QScrollBar> 15 16 #undef DVAPI 17 #undef DVVAR 18 #ifdef TOONZQT_EXPORTS 19 #define DVAPI DV_EXPORT_API 20 #define DVVAR DV_EXPORT_VAR 21 #else 22 #define DVAPI DV_IMPORT_API 23 #define DVVAR DV_IMPORT_VAR 24 #endif 25 26 //================================================================= 27 28 // Forward declarations 29 30 class TStageObject; 31 class TFx; 32 class TDoubleParam; 33 class TXsheet; 34 class TParamContainer; 35 class TFxHandle; 36 class TObjectHandle; 37 class TXsheetHandle; 38 39 class FunctionTreeView; 40 class FunctionViewer; 41 42 //================================================================= 43 44 //***************************************************************************************** 45 // FunctionTreeModel declaration 46 //***************************************************************************************** 47 48 /*! 49 \brief The Function Editor's (tree-like) \a model, as in the 50 <I>model-view</I> architecture. 51 52 \details This class represents the data associated to Toonz's Function Editor 53 panels in a 54 view-independent way. The model's purpose is that of representing 55 all \a channels of the 56 objects in a scene. A \a channel is here intended as an 57 <I>animatable parameter</I> 58 represented by a <I>single real-valued function</I>. 59 60 Animatable objects are currently subdivided in two main types: 61 <I>stage objects</I> 62 (which consist roughly all the objects represented in the \a stage 63 schematic view, 64 including cameras, spline curves and pegbars), and \a fxs. Stage 65 objects typically 66 feature a uniform channels group structure, whereas each fx type 67 have a different set 68 of parameters (and thus channels). Recently, \a column objects can 69 sport an additional 70 group of channels, related to Plastic skeleton animations (see 71 TnzExt library). 72 */ 73 74 class DVAPI FunctionTreeModel final : public TreeModel, public TParamObserver { 75 Q_OBJECT 76 77 public: 78 /*! 79 \brief FunctionTreeModel's abstract base item class, adding the requirement 80 to 81 return features visibility data. 82 */ 83 class Item : public TreeModel::Item { 84 public: Item()85 Item() {} 86 87 virtual bool isActive() const = 0; 88 virtual bool isAnimated() const = 0; 89 virtual bool isIgnored() const = 0; 90 }; 91 92 //---------------------------------------------------------------------------------- 93 94 //! The model item representing a channels group. 95 class ChannelGroup : public Item { 96 public: 97 enum ShowFilter { ShowAllChannels, ShowAnimatedChannels }; 98 99 private: 100 QString m_name; 101 ShowFilter m_showFilter; 102 103 public: 104 ChannelGroup(const QString &name = ""); 105 ~ChannelGroup(); 106 107 bool isActive() const override; 108 bool isAnimated() const override; 109 bool isIgnored() const override; 110 getShortName()111 virtual QString getShortName() const { return m_name; } getLongName()112 virtual QString getLongName() const { return m_name; } 113 114 virtual QString getIdName() const; 115 116 void setShowFilter(ShowFilter showFilter); getShowFilter()117 ShowFilter getShowFilter() const { return m_showFilter; } 118 119 void applyShowFilter(); // call this method when a channel changes 120 // its animation status 121 QVariant data(int role) const override; 122 123 // used in FunctionTreeView::onActivated 124 void setChildrenAllActive(bool active); 125 126 void displayAnimatedChannels(); 127 }; 128 129 //---------------------------------------------------------------------------------- 130 131 /*! 132 \brief The common class representing a \a parameter in the model. 133 134 \remark This class's concept is different from that of a Channel, as a \a 135 parameter could 136 be composed of <I>multiple channels</I>, e.g. like an animated \p RGBA 137 color, which 138 has 4 channels. 139 */ 140 class ParamWrapper { 141 protected: 142 TParamP m_param; //!< The wrapped parameter. 143 std::wstring m_fxId; //!< Fx identifier for m_param's owner, if any. 144 145 public: ParamWrapper(const TParamP & param,const std::wstring & fxId)146 ParamWrapper(const TParamP ¶m, const std::wstring &fxId) 147 : m_param(param), m_fxId(fxId) {} ~ParamWrapper()148 virtual ~ParamWrapper() {} 149 getFxId()150 const std::wstring &getFxId() const { return m_fxId; } 151 getParam()152 TParamP getParam() const { return m_param; } setParam(const TParamP & param)153 virtual void setParam(const TParamP ¶m) { m_param = param; } 154 }; 155 156 //---------------------------------------------------------------------------------- 157 158 //! The model item representing a channel (i.e. a real-valued function). 159 class DVAPI Channel final : public ParamWrapper, 160 public Item, 161 public TParamObserver { 162 FunctionTreeModel *m_model; //!< (\p not \p owned) Reference to the model 163 ChannelGroup 164 *m_group; //!< (\p not \p owned) Reference to the enclosing group 165 166 std::string m_paramNamePref; 167 168 bool m_isActive; //!< Whether the channels is active, ie visible 169 //!< as a curve and numeric column 170 public: 171 Channel(FunctionTreeModel *model, TDoubleParam *param, 172 std::string paramNamePrefix = "", std::wstring fxId = L""); 173 ~Channel(); 174 getParam()175 TDoubleParam *getParam() const { 176 return (TDoubleParam *)m_param.getPointer(); 177 } 178 void setParam(const TParamP ¶m) override; 179 180 QString getShortName() const; 181 QString getLongName() const; 182 183 // in order to show the expression name in the tooltip 184 QString getExprRefName() const; 185 getChannelGroup()186 ChannelGroup *getChannelGroup() const { return m_group; } setChannelGroup(ChannelGroup * group)187 void setChannelGroup(ChannelGroup *group) { m_group = group; } 188 189 QVariant data(int role) const override; 190 isActive()191 bool isActive() const override { return m_isActive; } 192 void setIsActive(bool active); 193 194 bool isAnimated() const override; 195 bool isIgnored() const override; 196 197 bool isCurrent() const; 198 void setIsCurrent(bool current); 199 200 bool isHidden() const; // the channel is hidden if it is filtered out 201 // by its channelgroup 202 void onChange(const TParamChange &) override; 203 204 void *getInternalPointer() const override; 205 }; 206 207 private: 208 ChannelGroup 209 *m_stageObjects, //!< Predefined group for stage object channels. 210 *m_fxs; //!< Predefined group for fx parameters. 211 212 std::vector<Channel *> m_activeChannels; 213 214 Channel *m_currentChannel; //!< (\p not \p owned) Current channel. 215 TStageObject 216 *m_currentStageObject; //!< (\p not \p owned) Current stage object. 217 TFx *m_currentFx; //!< (\p not \p owned) Current fx. 218 219 bool m_paramsChanged; 220 221 TFxHandle *m_fxHandle; 222 TObjectHandle *m_objectHandle; 223 224 public: 225 FunctionTreeModel( 226 FunctionTreeView *parent = 0); // BUT! Should be view-independent! :o 227 ~FunctionTreeModel(); 228 getCurrentChannel()229 Channel *getCurrentChannel() const { return m_currentChannel; } 230 231 Channel *getActiveChannel(int index) const; getActiveChannelCount()232 int getActiveChannelCount() const { return m_activeChannels.size(); } 233 234 int getColumnIndexByCurve(TDoubleParam *param) const; 235 236 double getValue(Channel *channel, double frame) const; 237 int getClosestKeyframe(Channel *channel, 238 double frame) const; // -1 if not found 239 Channel *getClosestChannel(double frame, double value) const; 240 241 void refreshActiveChannels(); 242 void refreshData(TXsheet *xsh); // call this method when the stageObject/Fx 243 // structure has been modified 244 void resetAll(); 245 246 void applyShowFilters(); 247 setCurrentStageObject(TStageObject * obj)248 void setCurrentStageObject(TStageObject *obj) { m_currentStageObject = obj; } getCurrentStageObject()249 TStageObject *getCurrentStageObject() const { return m_currentStageObject; } 250 251 void setCurrentFx(TFx *fx); getCurrentFx()252 TFx *getCurrentFx() const { return m_currentFx; } 253 254 void addParameter( 255 TParam *parameter, 256 const TFilePath 257 &folder); //!< See function FunctionViewer::addParameter(). 258 getFxHandle()259 TFxHandle *getFxHandle() { return m_fxHandle; } setFxHandle(TFxHandle * fxHandle)260 void setFxHandle(TFxHandle *fxHandle) { m_fxHandle = fxHandle; } 261 getObjectHandle()262 TObjectHandle *getObjectHandle() { return m_objectHandle; } setObjectHandle(TObjectHandle * objectHandle)263 void setObjectHandle(TObjectHandle *objectHandle) { 264 m_objectHandle = objectHandle; 265 } 266 267 signals: 268 269 void activeChannelsChanged(); 270 void curveSelected(TDoubleParam *); 271 void curveChanged(bool isDragging); 272 void currentChannelChanged(FunctionTreeModel::Channel *); 273 274 private: 275 void addParameter(ChannelGroup *group, const std::string &prefixString, 276 const std::wstring &fxId, TParam *param); 277 278 //! remove channel from m_activeChannels and m_currentChannel 279 void onChannelDestroyed(Channel *channel); 280 281 //! called when channel status (active/current) has been modified emitDataChanged(Channel * channel)282 void emitDataChanged(Channel *channel) { 283 QModelIndex index = channel->createIndex(); 284 emit dataChanged(index, index); 285 emit activeChannelsChanged(); 286 } 287 emitCurveSelected(TDoubleParam * curve)288 void emitCurveSelected(TDoubleParam *curve) { emit curveSelected(curve); } 289 emitCurrentChannelChanged(FunctionTreeModel::Channel * channel)290 void emitCurrentChannelChanged(FunctionTreeModel::Channel *channel) { 291 emit currentChannelChanged(channel); 292 } 293 294 void addChannels(TFx *fx, ChannelGroup *fxItem, TParamContainer *params); 295 296 // Observers notification functions 297 298 void onChange( 299 const TParamChange &) override; // Multiple param notifications ... 300 void onParamChange(bool isDragging); // ... that get compressed into one 301 302 // Update functions 303 304 void refreshStageObjects(TXsheet *xsh); 305 void refreshFxs(TXsheet *xsh); 306 void refreshPlasticDeformations(); 307 void addActiveChannels(TreeModel::Item *item); 308 309 public: 310 ChannelGroup *getStageObjectChannel(int index) const; 311 ChannelGroup *getFxChannel(int index) const; getStageObjectsChannelCount()312 int getStageObjectsChannelCount() const { 313 return m_stageObjects->getChildCount(); 314 } getFxsChannelCount()315 int getFxsChannelCount() const { return m_fxs->getChildCount(); } 316 }; 317 318 //============================================================================= 319 320 class DVAPI FxChannelGroup final : public FunctionTreeModel::ChannelGroup { 321 public: 322 TFx *m_fx; 323 324 public: 325 FxChannelGroup(TFx *fx); 326 ~FxChannelGroup(); 327 328 QString getShortName() const override; 329 QString getLongName() const override; 330 331 QString getIdName() const override; 332 getInternalPointer()333 void *getInternalPointer() const override { 334 return static_cast<void *>(m_fx); 335 } getFx()336 TFx *getFx() const { return m_fx; } 337 QVariant data(int role) const override; 338 339 void refresh() override; 340 }; 341 342 //============================================================================= 343 344 class DVAPI StageObjectChannelGroup final 345 : public FunctionTreeModel::ChannelGroup { 346 public: 347 TStageObject *m_stageObject; //!< (not owned) Referenced stage object 348 FunctionTreeModel::ChannelGroup 349 *m_plasticGroup; //!< (not owned) Eventual plastic channels group 350 351 public: 352 StageObjectChannelGroup(TStageObject *pegbar); 353 ~StageObjectChannelGroup(); 354 355 QString getShortName() const override; 356 QString getLongName() const override; 357 358 QString getIdName() const override; 359 getInternalPointer()360 void *getInternalPointer() const override { 361 return static_cast<void *>(m_stageObject); 362 } 363 getStageObject()364 TStageObject *getStageObject() const { return m_stageObject; } 365 QVariant data(int role) const override; 366 }; 367 368 //***************************************************************************************** 369 // FunctionTreeView declaration 370 //***************************************************************************************** 371 372 //! TreeView with stage object and fx channels. controls channel visibility and 373 //! current channel 374 class FunctionTreeView final : public TreeView { 375 Q_OBJECT 376 377 TFilePath m_scenePath; 378 FunctionTreeModel::Channel *m_clickedItem; 379 380 FunctionTreeModel::Channel *m_draggingChannel; 381 QPoint m_dragStartPosition; 382 FunctionViewer *m_viewer; 383 //--- 384 385 // set color by using style sheet 386 QColor m_textColor; // text color (black) 387 Q_PROPERTY(QColor TextColor READ getTextColor WRITE setTextColor) 388 389 TXsheetHandle *m_xshHandle; 390 391 public: 392 FunctionTreeView(FunctionViewer *parent); 393 setCurrentScenePath(TFilePath scenePath)394 void setCurrentScenePath(TFilePath scenePath) { m_scenePath = scenePath; } 395 396 void openContextMenu(TreeModel::Item *item, const QPoint &globalPos) override; 397 setTextColor(const QColor & color)398 void setTextColor(const QColor &color) { m_textColor = color; } getTextColor()399 QColor getTextColor() const { return m_textColor; } getViewer()400 FunctionViewer *getViewer() { return m_viewer; } 401 setXsheetHandle(TXsheetHandle * xshHandle)402 void setXsheetHandle(TXsheetHandle *xshHandle) { m_xshHandle = xshHandle; } getXsheetHandle()403 TXsheetHandle *getXsheetHandle() { return m_xshHandle; } 404 405 protected: 406 void onClick(TreeModel::Item *item, const QPoint &itemPos, 407 QMouseEvent *e) override; 408 409 void onMidClick(TreeModel::Item *item, const QPoint &itemPos, 410 QMouseEvent *e) override; 411 412 void onDrag(TreeModel::Item *item, const QPoint &itemPos, 413 QMouseEvent *e) override; 414 void onRelease() override; 415 416 void openContextMenu(FunctionTreeModel::Channel *channel, 417 const QPoint &globalPos); 418 void openContextMenu(FunctionTreeModel::ChannelGroup *group, 419 const QPoint &globalPos); 420 421 public slots: 422 423 void onActivated(const QModelIndex &index); 424 void updateAll(); 425 426 // show all the animated channels when the scene switched 427 void displayAnimatedChannels(); 428 429 signals: 430 431 void switchCurrentObject(TStageObject *obj); 432 void switchCurrentFx(TFx *fx); 433 }; 434 435 #endif // FUNCTIONTREEMODEL_H 436