1 #pragma once 2 3 #ifndef FLICONSOLE_H 4 #define FLICONSOLE_H 5 6 #include <QWidget> 7 #include <QAction> 8 #include <QMap> 9 #include <QList> 10 #include <QTime> 11 #include <QStyleOption> 12 #include <QStyleOptionFrameV3> 13 #include <QColor> 14 #include <QImage> 15 16 #include "tcommon.h" 17 #include "tpixel.h" 18 #include "toonzqt/intfield.h" 19 #include "toonz/imagepainter.h" 20 #include "tstopwatch.h" 21 #include <QThread> 22 23 #undef DVAPI 24 #undef DVVAR 25 #ifdef TOONZQT_EXPORTS 26 #define DVAPI DV_EXPORT_API 27 #define DVVAR DV_EXPORT_VAR 28 #else 29 #define DVAPI DV_IMPORT_API 30 #define DVVAR DV_IMPORT_VAR 31 #endif 32 33 class QToolBar; 34 class QLabel; 35 class QSlider; 36 class QTimerEvent; 37 class QVBoxLayout; 38 class QActionGroup; 39 class QAbstractButton; 40 class QPushButton; 41 class QScrollBar; 42 class DoubleButton; 43 class FlipSlider; 44 class FlipConsole; 45 class ToolBarContainer; 46 class FlipConsoleOwner; 47 class TFrameHandle; 48 //----------------------------------------------------------------------------- 49 50 class PlaybackExecutor final : public QThread { 51 Q_OBJECT 52 53 int m_fps; 54 bool m_abort; 55 56 public: 57 PlaybackExecutor(); 58 59 void resetFps(int fps); 60 61 void run() override; abort()62 void abort() { m_abort = true; } 63 emitNextFrame(int fps)64 void emitNextFrame(int fps) { emit nextFrame(fps); } 65 66 signals: 67 void nextFrame(int fps); // Must be connect with Qt::BlockingQueuedConnection 68 // connection type. 69 }; 70 71 //----------------------------------------------------------------------------- 72 73 // Implements a flipbook slider with a progress bar in background. 74 class FlipSlider final : public QAbstractSlider { 75 Q_OBJECT 76 77 Q_PROPERTY(int PBHeight READ getPBHeight WRITE setPBHeight) 78 79 Q_PROPERTY(QImage PBOverlay READ getPBOverlay WRITE setPBOverlay) 80 Q_PROPERTY(QImage PBMarker READ getPBMarker WRITE setPBMarker) 81 82 Q_PROPERTY(int PBColorMarginLeft READ getPBColorMarginLeft WRITE 83 setPBColorMarginLeft) 84 Q_PROPERTY( 85 int PBColorMarginTop READ getPBColorMarginTop WRITE setPBColorMarginTop) 86 Q_PROPERTY(int PBColorMarginRight READ getPBColorMarginRight WRITE 87 setPBColorMarginRight) 88 Q_PROPERTY(int PBColorMarginBottom READ getPBColorMarginBottom WRITE 89 setPBColorMarginBottom) 90 91 Q_PROPERTY(int PBMarkerMarginLeft READ getPBMarkerMarginLeft WRITE 92 setPBMarkerMarginLeft) 93 Q_PROPERTY(int PBMarkerMarginRight READ getPBMarkerMarginRight WRITE 94 setPBMarkerMarginRight) 95 96 Q_PROPERTY(QColor baseColor READ getBaseColor WRITE setBaseColor) 97 Q_PROPERTY( 98 QColor notStartedColor READ getNotStartedColor WRITE setNotStartedColor) 99 Q_PROPERTY(QColor startedColor READ getStartedColor WRITE setStartedColor) 100 Q_PROPERTY(QColor finishedColor READ getFinishedColor WRITE setFinishedColor) 101 102 bool m_enabled; 103 const std::vector<UCHAR> *m_progressBarStatus; 104 105 public: 106 enum { PBFrameNotStarted, PBFrameStarted, PBFrameFinished }; 107 108 FlipSlider(QWidget *parent); ~FlipSlider()109 ~FlipSlider() {} 110 setProgressBarEnabled(bool enabled)111 void setProgressBarEnabled(bool enabled) { m_enabled = enabled; } 112 setProgressBarStatus(const std::vector<UCHAR> * pbStatus)113 void setProgressBarStatus(const std::vector<UCHAR> *pbStatus) { 114 m_progressBarStatus = pbStatus; 115 } 116 getProgressBarStatus()117 const std::vector<UCHAR> *getProgressBarStatus() const { 118 return m_progressBarStatus; 119 } 120 121 public: 122 // Properties setters-getters 123 124 int getPBHeight() const; 125 void setPBHeight(int height); 126 127 QImage getPBOverlay() const; 128 void setPBOverlay(const QImage &img); 129 130 QImage getPBMarker() const; 131 void setPBMarker(const QImage &img); 132 133 int getPBColorMarginLeft() const; 134 void setPBColorMarginLeft(int margin); 135 136 int getPBColorMarginTop() const; 137 void setPBColorMarginTop(int margin); 138 139 int getPBColorMarginRight() const; 140 void setPBColorMarginRight(int margin); 141 142 int getPBColorMarginBottom() const; 143 void setPBColorMarginBottom(int margin); 144 145 int getPBMarkerMarginLeft() const; 146 void setPBMarkerMarginLeft(int margin); 147 148 int getPBMarkerMarginRight() const; 149 void setPBMarkerMarginRight(int margin); 150 151 QColor getBaseColor() const; 152 void setBaseColor(const QColor &color); 153 154 QColor getNotStartedColor() const; 155 void setNotStartedColor(const QColor &color); 156 157 QColor getStartedColor() const; 158 void setStartedColor(const QColor &color); 159 160 QColor getFinishedColor() const; 161 void setFinishedColor(const QColor &color); 162 163 protected: 164 void paintEvent(QPaintEvent *ev) override; 165 166 void mousePressEvent(QMouseEvent *me) override; 167 void mouseMoveEvent(QMouseEvent *me) override; 168 void mouseReleaseEvent(QMouseEvent *me) override; 169 170 private: 171 int sliderPositionFromValue(int min, int max, int pos, int span); 172 int sliderValueFromPosition(int min, int max, int step, int pos, int span); 173 int pageStepVal(int val); 174 175 signals: 176 void flipSliderReleased(); 177 void flipSliderPressed(); 178 }; 179 180 //----------------------------------------------------------------------------- 181 182 class DVAPI FlipConsole final : public QWidget { 183 Q_OBJECT 184 185 QColor m_fpsFieldColor; 186 Q_PROPERTY(QColor FpsFieldColor READ getFpsFieldColor WRITE setFpsFieldColor) 187 188 public: 189 enum EGadget { 190 eBegin, 191 ePlay, 192 eLoop, 193 ePause, 194 ePrev, 195 eNext, 196 eFirst, 197 eLast, 198 eRed, 199 eGreen, 200 eBlue, 201 eGRed, 202 eGGreen, 203 eGBlue, 204 eMatte, 205 eFrames, 206 eRate, 207 eSound, 208 eHisto, 209 eSaveImg, 210 eCompare, 211 eCustomize, 212 eSave, 213 eDefineSubCamera, 214 eFilledRaster, // Used only in LineTest 215 eDefineLoadBox, 216 eUseLoadBox, 217 eLocator, 218 eZoomIn, 219 eZoomOut, 220 eFlipHorizontal, 221 eFlipVertical, 222 eResetView, 223 // following values are hard-coded in ImagePainter 224 eBlackBg = 0x40000, 225 eWhiteBg = 0x80000, 226 eCheckBg = 0x100000, 227 eEnd 228 }; 229 230 static FlipConsole *m_currentConsole; 231 static QList<FlipConsole *> m_visibleConsoles; 232 static bool m_isLinkedPlaying; 233 static bool m_areLinked; 234 235 // blanksEnabled==true->at begin of each loop a number of blank frames are 236 // drawn (according to rpeferences settings) 237 FlipConsole(QVBoxLayout *layout, std::vector<int> gadgetsMask, 238 bool isLinkable, QWidget *customWidget, 239 const QString &customizeId, 240 FlipConsoleOwner *consoleOwner, // call 241 // consoleOwner->onDrawFrame() 242 // intead of emitting drawFrame 243 // signal 244 bool enableBlanks = false); 245 void enableBlanks(bool state); 246 247 void setFrameRange( 248 int from, int to, int step, 249 int current = -1); // if current==-1, current position will be ==from getFrameRange(int & from,int & to,int & step)250 void getFrameRange(int &from, int &to, int &step) const { 251 from = m_from, to = m_to, step = m_step; 252 } 253 void setFrameRate(int rate, bool forceUpdate = true); 254 // if doShowHide==true, applies set visible, otherwise applies setEnabled 255 void enableButton(UINT button, bool enable, bool doShowHide = true); 256 void showCurrentFrame(); getCurrentFrame()257 int getCurrentFrame() const { return m_currentFrame; } getCurrentFps()258 int getCurrentFps() const { return m_fps; } 259 void setChecked(UINT button, bool state); 260 bool isChecked(UINT button) const; 261 void setCurrentFrame(int frame, bool forceResetting = false); setMarkers(int fromIndex,int toIndex)262 void setMarkers(int fromIndex, int toIndex) { 263 m_markerFrom = fromIndex + 1; 264 m_markerTo = toIndex + 1; 265 } pressButton(UINT button)266 void pressButton(UINT button) { 267 doButtonPressed(button); 268 setChecked(button, !isChecked(button)); 269 } 270 271 // the main (currently the only) use for current flipconsole and setActive is 272 // to 273 // support shortcuts handling 274 // setActive() should be called every time the visibility state of the console 275 // changes 276 // a list of visible console is maintained. calling setActive(false) for the 277 // current 278 // console makes automatically current the next one in the list getCurrent()279 static FlipConsole *getCurrent() { return m_currentConsole; }; 280 281 static void toggleLinked(); 282 283 void makeCurrent(); 284 void setActive(bool active); 285 286 void pressButton(EGadget buttonId); 287 288 void showHideAllParts(bool); 289 void showHidePlaybar(bool); 290 void showHideFrameSlider(bool); 291 292 void enableProgressBar(bool enable); 293 void setProgressBarStatus(const std::vector<UCHAR> *status); 294 const std::vector<UCHAR> *getProgressBarStatus() const; 295 setFrameHandle(TFrameHandle * frameHandle)296 void setFrameHandle(TFrameHandle *frameHandle) { 297 m_frameHandle = frameHandle; 298 } 299 isLinkable()300 bool isLinkable() const { return m_isLinkable; } 301 void playNextFrame(); 302 void updateCurrentFPS(int val); 303 hasButton(std::vector<int> buttonMask,FlipConsole::EGadget buttonId)304 bool hasButton(std::vector<int> buttonMask, FlipConsole::EGadget buttonId) { 305 if (buttonMask.size() == 0) return true; 306 return std::find(buttonMask.begin(), buttonMask.end(), buttonId) == 307 buttonMask.end(); 308 } 309 setFpsFieldColor(const QColor & color)310 void setFpsFieldColor(const QColor &color) { m_fpsFieldColor = color; } getFpsFieldColor()311 QColor getFpsFieldColor() const { return m_fpsFieldColor; } 312 313 signals: 314 315 void buttonPressed(FlipConsole::EGadget button); 316 317 void playStateChanged(bool isPlaying); 318 void sliderReleased(); 319 320 private: 321 UINT m_customizeMask; 322 QString m_customizeId; 323 QAction *m_customAction; 324 PlaybackExecutor m_playbackExecutor; 325 326 QAction *m_customSep, *m_rateSep, *m_histoSep, *m_bgSep, *m_vcrSep, 327 *m_compareSep, *m_saveSep, *m_colorFilterSep, *m_soundSep, *m_subcamSep, 328 *m_filledRasterSep, *m_viewerSep; 329 330 QToolBar *m_playToolBar; 331 QActionGroup *m_colorFilterGroup; 332 ToolBarContainer *m_playToolBarContainer; 333 QFrame *m_frameSliderFrame; 334 335 QLabel *m_fpsLabel; 336 QScrollBar *m_fpsSlider; 337 DVGui::IntLineEdit *m_fpsField; 338 QAction *m_fpsFieldAction; 339 QAction *m_fpsLabelAction; 340 QAction *m_fpsSliderAction; 341 QFrame *createFpsSlider(); 342 QAction *m_doubleRedAction, *m_doubleGreenAction, *m_doubleBlueAction; 343 DoubleButton *m_doubleRed, *m_doubleGreen, *m_doubleBlue; 344 std::vector<int> m_gadgetsMask; 345 int m_from, m_to, m_step; 346 int m_currentFrame, m_framesCount; 347 ImagePainter::VisualSettings m_settings; 348 349 bool m_isPlay; 350 int m_fps, m_sceneFps; 351 bool m_reverse; 352 int m_markerFrom, m_markerTo; 353 bool m_drawBlanksEnabled; 354 int m_blanksCount; 355 TPixel m_blankColor; 356 int m_blanksToDraw; 357 bool m_isLinkable; 358 359 QMap<EGadget, QAbstractButton *> m_buttons; 360 QMap<EGadget, QAction *> m_actions; 361 362 void createCustomizeMenu(bool withCustomWidget); 363 void addMenuItem(UINT id, const QString &text, QMenu *menu); 364 void createButton(UINT buttonMask, const char *iconStr, const QString &tip, 365 bool checkable, QActionGroup *groupIt = 0); 366 QAction *createCheckedButtonWithBorderImage( 367 UINT buttonMask, const char *iconStr, const QString &tip, bool checkable, 368 QActionGroup *groupIt = 0, const char *cmdId = 0); 369 void createOnOffButton(UINT buttonMask, const char *iconStr, 370 const QString &tip, QActionGroup *group); 371 QAction *createDoubleButton(UINT buttonMask1, UINT buttonMask2, 372 const char *iconStr1, const char *iconStr2, 373 const QString &tip1, const QString &tip2, 374 QActionGroup *group, DoubleButton *&w); 375 376 QFrame *createFrameSlider(); 377 void createPlayToolBar(QWidget *customWidget); 378 DVGui::IntLineEdit *m_editCurrFrame; 379 FlipSlider *m_currFrameSlider; 380 381 void doButtonPressed(UINT button); 382 static void pressLinkedConsoleButton(UINT button, FlipConsole *skipIt); 383 void applyCustomizeMask(); 384 void onLoadBox(bool isDefine); 385 386 QPushButton *m_enableBlankFrameButton; 387 388 FlipConsoleOwner *m_consoleOwner; 389 TFrameHandle *m_frameHandle; 390 391 protected slots: 392 393 void OnSetCurrentFrame(); 394 void OnFrameSliderRelease(); 395 void OnFrameSliderPress(); 396 void OnSetCurrentFrame(int); 397 void setCurrentFPS(int); 398 void setCurrentFPS(bool dragging); onButtonPressed(QAction * action)399 inline void onButtonPressed(QAction *action) { 400 onButtonPressed(action->data().toUInt()); 401 } 402 void onButtonPressed(int button); 403 void incrementCurrentFrame(int delta); 404 void onNextFrame(int fps); 405 void onCustomizeButtonPressed(QAction *); 406 bool drawBlanks(int from, int to); 407 void onSliderRelease(); 408 409 void onFPSEdited(); 410 411 public slots: 412 void onPreferenceChanged(const QString &); 413 414 private: 415 friend class PlaybackExecutor; playbackExecutor()416 PlaybackExecutor &playbackExecutor() { return m_playbackExecutor; } 417 }; 418 419 #endif 420