1
2 // TnzCore includes
3 #include "tconvert.h"
4 #include "tgeometry.h"
5 #include "tgl.h"
6 #include "trop.h"
7 #include "tstopwatch.h"
8 #include "tsystem.h"
9
10 // TnzLib includes
11 #include "toonz/tscenehandle.h"
12 #include "toonz/txsheethandle.h"
13 #include "toonz/tframehandle.h"
14 #include "toonz/tcolumnhandle.h"
15 #include "toonz/txshlevelhandle.h"
16 #include "toonz/toonzscene.h"
17 #include "toonz/sceneproperties.h"
18 #include "toonz/txsheet.h"
19 #include "toonz/stage.h"
20 #include "toonz/stage2.h"
21 #include "toonz/txshlevel.h"
22 #include "toonz/txshcell.h"
23 #include "toonz/tcamera.h"
24 #include "toonz/tstageobjecttree.h"
25 #include "toonz/tobjecthandle.h"
26 #include "toonz/tpalettehandle.h"
27 #include "toonz/tonionskinmaskhandle.h"
28 #include "toutputproperties.h"
29 #include "toonz/palettecontroller.h"
30 #include "toonz/toonzfolders.h"
31 #include "toonz/preferences.h"
32 #include "toonz/tproject.h"
33
34 // TnzQt includes
35 #include "toonzqt/menubarcommand.h"
36 #include "toonzqt/dvdialog.h"
37 #include "toonzqt/gutil.h"
38 #include "toonzqt/imageutils.h"
39 #include "toonzqt/flipconsole.h"
40
41 // TnzTools includes
42 #include "tools/toolhandle.h"
43 #include "tools/tooloptions.h"
44
45 // Tnz6 includes
46 #include "tapp.h"
47 #include "mainwindow.h"
48 #include "sceneviewer.h"
49 #include "xsheetdragtool.h"
50 #include "ruler.h"
51 #include "menubarcommandids.h"
52 #include "toolbar.h"
53
54 // Qt includes
55 #include <QPainter>
56 #include <QVBoxLayout>
57 #include <QAction>
58 #include <QDialogButtonBox>
59 #include <QAbstractButton>
60 #include <QMouseEvent>
61 #include <QWheelEvent>
62 #include <QLabel>
63 #include <QRadioButton>
64 #include <QLineEdit>
65 #include <QSlider>
66 #include <QButtonGroup>
67 #include <QMenu>
68 #include <QToolBar>
69 #include <QMainWindow>
70 #include <QSettings>
71
72 #include "comboviewerpane.h"
73
74 using namespace DVGui;
75
76 //=============================================================================
77 //
78 // ComboViewerPanel
79 //
80 //-----------------------------------------------------------------------------
81
82 //-----------------------------------------------------------------------------
83
84 #if QT_VERSION >= 0x050500
ComboViewerPanel(QWidget * parent,Qt::WindowFlags flags)85 ComboViewerPanel::ComboViewerPanel(QWidget *parent, Qt::WindowFlags flags)
86 #else
87 ComboViewerPanel::ComboViewerPanel(QWidget *parent, Qt::WFlags flags)
88 #endif
89 : QFrame(parent) {
90 TApp *app = TApp::instance();
91
92 setFrameStyle(QFrame::StyledPanel);
93 setObjectName("ComboViewerPanel");
94
95 // ToolBar
96 m_toolbar = new Toolbar(this, false);
97 // Tool Options
98 m_toolOptions = new ToolOptions();
99 m_toolOptions->setObjectName("ComboViewerToolOptions");
100
101 // Viewer
102 ImageUtils::FullScreenWidget *fsWidget =
103 new ImageUtils::FullScreenWidget(this);
104 fsWidget->setWidget(m_sceneViewer = new SceneViewer(fsWidget));
105 m_sceneViewer->setIsStyleShortcutSwitchable();
106
107 #if defined(Q_OS_WIN) && (QT_VERSION >= 0x050500) && (QT_VERSION < 0x050600)
108 // Workaround for QTBUG-48288
109 // This code should be removed after updating Qt.
110 // Qt may crash in handling WM_SIZE of m_sceneViewer in splash.finish(&w)
111 // in main.cpp. To suppress sending WM_SIZE, set window position here.
112 // WM_SIZE will not be sent if window poistion is not changed.
113 ::SetWindowPos(reinterpret_cast<HWND>(m_sceneViewer->winId()), HWND_TOP, 0, 0,
114 0, 0, SWP_NOMOVE | SWP_NOSIZE);
115 #endif
116
117 m_vRuler = new Ruler(this, m_sceneViewer, true);
118 m_hRuler = new Ruler(this, m_sceneViewer, false);
119
120 m_sceneViewer->setRulers(m_vRuler, m_hRuler);
121
122 m_keyFrameButton = new ViewerKeyframeNavigator(this, app->getCurrentFrame());
123 m_keyFrameButton->setObjectHandle(app->getCurrentObject());
124 m_keyFrameButton->setXsheetHandle(app->getCurrentXsheet());
125
126 // FlipConsole
127 std::vector<int> buttonMask = {FlipConsole::eFilledRaster,
128 FlipConsole::eDefineLoadBox,
129 FlipConsole::eUseLoadBox};
130
131 /* --- layout --- */
132 QVBoxLayout *mainLayout = new QVBoxLayout();
133 mainLayout->setMargin(0);
134 mainLayout->setSpacing(0);
135 {
136 mainLayout->addWidget(m_toolbar, 0);
137 mainLayout->addWidget(m_toolOptions, 0);
138
139 QGridLayout *viewerL = new QGridLayout();
140 viewerL->setMargin(0);
141 viewerL->setSpacing(0);
142 {
143 viewerL->addWidget(m_vRuler, 1, 0);
144 viewerL->addWidget(m_hRuler, 0, 1);
145 viewerL->addWidget(fsWidget, 1, 1);
146 }
147 mainLayout->addLayout(viewerL, 1);
148 m_flipConsole =
149 new FlipConsole(mainLayout, buttonMask, false, m_keyFrameButton,
150 "SceneViewerConsole", this, true);
151 }
152 setLayout(mainLayout);
153
154 m_flipConsole->enableButton(FlipConsole::eMatte, false, false);
155 m_flipConsole->enableButton(FlipConsole::eSave, false, false);
156 m_flipConsole->enableButton(FlipConsole::eCompare, false, false);
157 m_flipConsole->enableButton(FlipConsole::eSaveImg, false, false);
158 m_flipConsole->enableButton(FlipConsole::eGRed, false, false);
159 m_flipConsole->enableButton(FlipConsole::eGGreen, false, false);
160 m_flipConsole->enableButton(FlipConsole::eGBlue, false, false);
161 // m_flipConsole->enableButton(FlipConsole::eSound, false, false);
162
163 m_flipConsole->setFrameRate(app->getCurrentScene()
164 ->getScene()
165 ->getProperties()
166 ->getOutputProperties()
167 ->getFrameRate());
168 m_flipConsole->setFrameHandle(TApp::instance()->getCurrentFrame());
169
170 bool ret = true;
171
172 // When zoom changed, only if the viewer is active, change window title.
173 ret =
174 ret && connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)),
175 this, SLOT(onButtonPressed(FlipConsole::EGadget)));
176 ret = connect(m_sceneViewer, SIGNAL(onZoomChanged()),
177 SLOT(changeWindowTitle()));
178 ret = ret && connect(m_sceneViewer, SIGNAL(previewToggled()),
179 SLOT(changeWindowTitle()));
180 ret = ret &&
181 connect(m_flipConsole, SIGNAL(playStateChanged(bool)),
182 TApp::instance()->getCurrentFrame(), SLOT(setPlaying(bool)));
183 ret = ret && connect(m_flipConsole, SIGNAL(playStateChanged(bool)), this,
184 SLOT(onPlayingStatusChanged(bool)));
185 ret = ret &&
186 connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)),
187 m_sceneViewer, SLOT(onButtonPressed(FlipConsole::EGadget)));
188 ret = ret && connect(m_sceneViewer, SIGNAL(previewStatusChanged()), this,
189 SLOT(update()));
190 ret = ret && connect(m_sceneViewer, SIGNAL(onFlipHChanged(bool)), this,
191 SLOT(setFlipHButtonChecked(bool)));
192 ret = ret && connect(m_sceneViewer, SIGNAL(onFlipVChanged(bool)), this,
193 SLOT(setFlipVButtonChecked(bool)));
194 ret = ret && connect(app->getCurrentScene(), SIGNAL(sceneSwitched()), this,
195 SLOT(onSceneSwitched()));
196
197 assert(ret);
198
199 m_flipConsole->setChecked(FlipConsole::eSound, true);
200 m_playSound = m_flipConsole->isChecked(FlipConsole::eSound);
201
202 // initial state of the parts
203 m_visiblePartsFlag = CVPARTS_ALL;
204 updateShowHide();
205
206 setFocusProxy(m_sceneViewer);
207 }
208
209 //-----------------------------------------------------------------------------
210 /*! toggle show/hide of the widgets according to m_visibleFlag
211 */
212
updateShowHide()213 void ComboViewerPanel::updateShowHide() {
214 // toolbar
215 m_toolbar->setVisible(m_visiblePartsFlag & CVPARTS_TOOLBAR);
216 // tool options bar
217 m_toolOptions->setVisible(m_visiblePartsFlag & CVPARTS_TOOLOPTIONS);
218 // flip console
219 m_flipConsole->showHideAllParts(m_visiblePartsFlag & CVPARTS_FLIPCONSOLE);
220 update();
221 }
222
223 //-----------------------------------------------------------------------------
224 /*! showing the show/hide commands
225 */
226
contextMenuEvent(QContextMenuEvent * event)227 void ComboViewerPanel::contextMenuEvent(QContextMenuEvent *event) {
228 QMenu *menu = new QMenu(this);
229 addShowHideContextMenu(menu);
230 menu->exec(event->globalPos());
231 }
232
233 //-----------------------------------------------------------------------------
234
addShowHideContextMenu(QMenu * menu)235 void ComboViewerPanel::addShowHideContextMenu(QMenu *menu) {
236 QMenu *showHideMenu = menu->addMenu(tr("GUI Show / Hide"));
237 // actions
238 QAction *toolbarSHAct = showHideMenu->addAction(tr("Toolbar"));
239 QAction *toolOptionsSHAct = showHideMenu->addAction(tr("Tool Options Bar"));
240 QAction *flipConsoleSHAct = showHideMenu->addAction(tr("Console"));
241
242 toolbarSHAct->setCheckable(true);
243 toolbarSHAct->setChecked(m_visiblePartsFlag & CVPARTS_TOOLBAR);
244 toolbarSHAct->setData((UINT)CVPARTS_TOOLBAR);
245
246 toolOptionsSHAct->setCheckable(true);
247 toolOptionsSHAct->setChecked(m_visiblePartsFlag & CVPARTS_TOOLOPTIONS);
248 toolOptionsSHAct->setData((UINT)CVPARTS_TOOLOPTIONS);
249
250 flipConsoleSHAct->setCheckable(true);
251 flipConsoleSHAct->setChecked(m_visiblePartsFlag & CVPARTS_FLIPCONSOLE);
252 flipConsoleSHAct->setData((UINT)CVPARTS_FLIPCONSOLE);
253
254 QActionGroup *showHideActGroup = new QActionGroup(this);
255 showHideActGroup->setExclusive(false);
256 showHideActGroup->addAction(toolbarSHAct);
257 showHideActGroup->addAction(toolOptionsSHAct);
258 showHideActGroup->addAction(flipConsoleSHAct);
259
260 connect(showHideActGroup, SIGNAL(triggered(QAction *)), this,
261 SLOT(onShowHideActionTriggered(QAction *)));
262
263 showHideMenu->addSeparator();
264 showHideMenu->addAction(CommandManager::instance()->getAction(MI_ViewCamera));
265 showHideMenu->addAction(CommandManager::instance()->getAction(MI_ViewTable));
266 showHideMenu->addAction(CommandManager::instance()->getAction(MI_FieldGuide));
267 showHideMenu->addAction(CommandManager::instance()->getAction(MI_SafeArea));
268 showHideMenu->addAction(CommandManager::instance()->getAction(MI_ViewBBox));
269 showHideMenu->addAction(
270 CommandManager::instance()->getAction(MI_ViewColorcard));
271 showHideMenu->addAction(CommandManager::instance()->getAction(MI_ViewRuler));
272 }
273
274 //-----------------------------------------------------------------------------
275 /*! slot function for show/hide the parts
276 */
277
onShowHideActionTriggered(QAction * act)278 void ComboViewerPanel::onShowHideActionTriggered(QAction *act) {
279 CV_Parts part = (CV_Parts)act->data().toUInt();
280 assert(part < CVPARTS_End);
281
282 m_visiblePartsFlag ^= part;
283
284 updateShowHide();
285 }
286
287 //-----------------------------------------------------------------------------
288
onDrawFrame(int frame,const ImagePainter::VisualSettings & settings)289 void ComboViewerPanel::onDrawFrame(
290 int frame, const ImagePainter::VisualSettings &settings) {
291 TApp *app = TApp::instance();
292 m_sceneViewer->setVisual(settings);
293 TFrameHandle *frameHandle = app->getCurrentFrame();
294
295 if (m_sceneViewer->isPreviewEnabled()) {
296 class Previewer *pr = Previewer::instance(m_sceneViewer->getPreviewMode() ==
297 SceneViewer::SUBCAMERA_PREVIEW);
298
299 pr->getRaster(frame - 1); // the 'getRaster' starts the render of the frame
300 // is not already started
301 int curFrame = frame;
302 if (frameHandle->isPlaying() &&
303 !pr->isFrameReady(
304 frame - 1)) // stops on last rendered frame until current is ready!
305 {
306 while (frame > 0 && !pr->isFrameReady(frame - 1)) frame--;
307 if (frame == 0)
308 frame = curFrame; // if no frame is ready, I stay on current...no use
309 // to rewind
310 m_flipConsole->setCurrentFrame(frame);
311 }
312 }
313
314 assert(frame >= 0);
315 if (frame != frameHandle->getFrameIndex() + 1) {
316 int oldFrame = frameHandle->getFrame();
317 frameHandle->setCurrentFrame(frame);
318 if (!frameHandle->isPlaying() && !frameHandle->isEditingLevel() &&
319 oldFrame != frameHandle->getFrame())
320 frameHandle->scrubXsheet(
321 frame - 1, frame - 1,
322 TApp::instance()->getCurrentXsheet()->getXsheet());
323 }
324
325 else if (settings.m_blankColor != TPixel::Transparent)
326 m_sceneViewer->update();
327 }
328
329 //-----------------------------------------------------------------------------
330
~ComboViewerPanel()331 ComboViewerPanel::~ComboViewerPanel() {}
332
333 //-----------------------------------------------------------------------------
334
showEvent(QShowEvent * event)335 void ComboViewerPanel::showEvent(QShowEvent *event) {
336 TApp *app = TApp::instance();
337 TFrameHandle *frameHandle = app->getCurrentFrame();
338 TSceneHandle *sceneHandle = app->getCurrentScene();
339 TXshLevelHandle *levelHandle = app->getCurrentLevel();
340 TObjectHandle *objectHandle = app->getCurrentObject();
341 TXsheetHandle *xshHandle = app->getCurrentXsheet();
342
343 bool ret = true;
344
345 /*!
346 onSceneChanged(): called when the scene changed
347 - set new scene's FPS
348 - update the range of frame slider with a new framehandle
349 - set the marker
350 - update key frames
351 */
352 ret =
353 connect(xshHandle, SIGNAL(xsheetChanged()), this, SLOT(onSceneChanged()));
354 ret = ret && connect(sceneHandle, SIGNAL(sceneSwitched()), this,
355 SLOT(onSceneChanged()));
356 ret = ret && connect(sceneHandle, SIGNAL(sceneChanged()), this,
357 SLOT(onSceneChanged()));
358
359 /*!
360 changeWindowTitle(): called when the scene / level / frame is changed
361 - chenge the title text
362 */
363 ret = ret && connect(sceneHandle, SIGNAL(nameSceneChanged()), this,
364 SLOT(changeWindowTitle()));
365 ret =
366 ret && connect(sceneHandle, SIGNAL(preferenceChanged(const QString &)),
367 m_flipConsole, SLOT(onPreferenceChanged(const QString &)));
368
369 ret = ret && connect(levelHandle, SIGNAL(xshLevelChanged()), this,
370 SLOT(changeWindowTitle()));
371 ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this,
372 SLOT(changeWindowTitle()));
373 // onXshLevelSwitched(TXshLevel*): changeWindowTitle() + updateFrameRange()
374 ret = ret && connect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)), this,
375 SLOT(onXshLevelSwitched(TXshLevel *)));
376 ret = ret && connect(levelHandle, SIGNAL(xshLevelTitleChanged()), this,
377 SLOT(changeWindowTitle()));
378 // updateFrameRange(): update the frame slider's range
379 ret = ret && connect(levelHandle, SIGNAL(xshLevelChanged()), this,
380 SLOT(updateFrameRange()));
381
382 // onFrameTypeChanged(): reset the marker positions in the flip console
383 ret = ret && connect(frameHandle, SIGNAL(frameTypeChanged()), this,
384 SLOT(onFrameTypeChanged()));
385
386 // onFrameChanged(): update the flipconsole according to the current frame
387 ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this,
388 SLOT(onFrameChanged()));
389
390 ret = ret && connect(app->getCurrentTool(), SIGNAL(toolSwitched()),
391 m_sceneViewer, SLOT(onToolSwitched()));
392
393 assert(ret);
394
395 m_flipConsole->setActive(true);
396 m_flipConsole->onPreferenceChanged("");
397
398 // refresh
399 onSceneChanged();
400 changeWindowTitle();
401 }
402
403 //-----------------------------------------------------------------------------
404
hideEvent(QHideEvent * event)405 void ComboViewerPanel::hideEvent(QHideEvent *event) {
406 TApp *app = TApp::instance();
407 disconnect(app->getCurrentFrame(), 0, this, 0);
408 disconnect(app->getCurrentScene(), 0, this, 0);
409 disconnect(app->getCurrentLevel(), 0, this, 0);
410 disconnect(app->getCurrentObject(), 0, this, 0);
411 disconnect(app->getCurrentXsheet(), 0, this, 0);
412
413 disconnect(app->getCurrentTool(), SIGNAL(toolSwitched()), m_sceneViewer,
414 SLOT(onToolSwitched()));
415 disconnect(app->getCurrentScene(), SIGNAL(preferenceChanged(const QString &)),
416 m_flipConsole, SLOT(onPreferenceChanged(const QString &)));
417
418 m_flipConsole->setActive(false);
419 }
420
421 //-----------------------------------------------------------------------------
422
initializeTitleBar(TPanelTitleBar * titleBar)423 void ComboViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) {
424 bool ret = true;
425
426 TPanelTitleBarButtonSet *viewModeButtonSet;
427 m_referenceModeBs = viewModeButtonSet = new TPanelTitleBarButtonSet();
428 int x = -232;
429 int iconWidth = 20;
430 TPanelTitleBarButton *button;
431
432 // buttons for show / hide toggle for the field guide and the safe area
433 TPanelTitleBarButtonForSafeArea *safeAreaButton =
434 new TPanelTitleBarButtonForSafeArea(
435 titleBar, getIconThemePath("actions/20/pane_safe.svg"));
436 safeAreaButton->setToolTip(tr("Safe Area (Right Click to Select)"));
437 titleBar->add(QPoint(x, 0), safeAreaButton);
438 ret = ret && connect(safeAreaButton, SIGNAL(toggled(bool)),
439 CommandManager::instance()->getAction(MI_SafeArea),
440 SLOT(trigger()));
441 ret = ret && connect(CommandManager::instance()->getAction(MI_SafeArea),
442 SIGNAL(triggered(bool)), safeAreaButton,
443 SLOT(setPressed(bool)));
444 // initialize state
445 safeAreaButton->setPressed(
446 CommandManager::instance()->getAction(MI_SafeArea)->isChecked());
447
448 button = new TPanelTitleBarButton(
449 titleBar, getIconThemePath("actions/20/pane_grid.svg"));
450 button->setToolTip(tr("Field Guide"));
451 x += 1 + iconWidth;
452 titleBar->add(QPoint(x, 0), button);
453 ret = ret && connect(button, SIGNAL(toggled(bool)),
454 CommandManager::instance()->getAction(MI_FieldGuide),
455 SLOT(trigger()));
456 ret = ret && connect(CommandManager::instance()->getAction(MI_FieldGuide),
457 SIGNAL(triggered(bool)), button, SLOT(setPressed(bool)));
458 // initialize state
459 button->setPressed(
460 CommandManager::instance()->getAction(MI_FieldGuide)->isChecked());
461
462 // view mode toggles
463 button = new TPanelTitleBarButton(
464 titleBar, getIconThemePath("actions/20/pane_table.svg"));
465 button->setToolTip(tr("Camera Stand View"));
466 x += 10 + 1 + iconWidth;
467 titleBar->add(QPoint(x, 0), button);
468 button->setButtonSet(viewModeButtonSet, SceneViewer::NORMAL_REFERENCE);
469 button->setPressed(true);
470
471 button = new TPanelTitleBarButton(titleBar,
472 getIconThemePath("actions/20/pane_3d.svg"));
473 button->setToolTip(tr("3D View"));
474 x += +1 + iconWidth;
475 titleBar->add(QPoint(x, 0), button);
476 button->setButtonSet(viewModeButtonSet, SceneViewer::CAMERA3D_REFERENCE);
477
478 button = new TPanelTitleBarButton(
479 titleBar, getIconThemePath("actions/20/pane_cam.svg"));
480 button->setToolTip(tr("Camera View"));
481 x += +1 + iconWidth;
482 titleBar->add(QPoint(x, 0), button);
483 button->setButtonSet(viewModeButtonSet, SceneViewer::CAMERA_REFERENCE);
484 ret = ret && connect(viewModeButtonSet, SIGNAL(selected(int)), m_sceneViewer,
485 SLOT(setReferenceMode(int)));
486
487 // freeze button
488 button = new TPanelTitleBarButton(
489 titleBar, getIconThemePath("actions/20/pane_freeze.svg"));
490 x += 10 + iconWidth;
491
492 button->setToolTip(tr("Freeze"));
493 titleBar->add(QPoint(x, 0), button);
494 ret = ret && connect(button, SIGNAL(toggled(bool)), m_sceneViewer,
495 SLOT(freeze(bool)));
496
497 // preview toggles
498 m_previewButton = new TPanelTitleBarButton(
499 titleBar, getIconThemePath("actions/20/pane_preview.svg"));
500 x += 10 + iconWidth;
501 titleBar->add(QPoint(x, 0), m_previewButton);
502 m_previewButton->setToolTip(tr("Preview"));
503 ret = ret && connect(m_previewButton, SIGNAL(toggled(bool)),
504 SLOT(enableFullPreview(bool)));
505
506 m_subcameraPreviewButton = new TPanelTitleBarButton(
507 titleBar, getIconThemePath("actions/20/pane_subpreview.svg"));
508 x += +1 + 24; // width of pane_preview_off.svg = 22px
509
510 titleBar->add(QPoint(x, 0), m_subcameraPreviewButton);
511 m_subcameraPreviewButton->setToolTip(tr("Sub-camera Preview"));
512 ret = ret && connect(m_subcameraPreviewButton, SIGNAL(toggled(bool)),
513 SLOT(enableSubCameraPreview(bool)));
514
515 assert(ret);
516 }
517
518 //-----------------------------------------------------------------------------
519
enableFullPreview(bool enabled)520 void ComboViewerPanel::enableFullPreview(bool enabled) {
521 m_subcameraPreviewButton->setPressed(false);
522 m_sceneViewer->enablePreview(enabled ? SceneViewer::FULL_PREVIEW
523 : SceneViewer::NO_PREVIEW);
524 m_flipConsole->setProgressBarStatus(
525 &Previewer::instance(false)->getProgressBarStatus());
526 enableFlipConsoleForCamerastand(enabled);
527 }
528
529 //-----------------------------------------------------------------------------
530
enableSubCameraPreview(bool enabled)531 void ComboViewerPanel::enableSubCameraPreview(bool enabled) {
532 m_previewButton->setPressed(false);
533 m_sceneViewer->enablePreview(enabled ? SceneViewer::SUBCAMERA_PREVIEW
534 : SceneViewer::NO_PREVIEW);
535 m_flipConsole->setProgressBarStatus(
536 &Previewer::instance(true)->getProgressBarStatus());
537 enableFlipConsoleForCamerastand(enabled);
538 }
539
540 //-----------------------------------------------------------------------------
541
enableFlipConsoleForCamerastand(bool on)542 void ComboViewerPanel::enableFlipConsoleForCamerastand(bool on) {
543 m_flipConsole->enableButton(FlipConsole::eMatte, on, false);
544 m_flipConsole->enableButton(FlipConsole::eSave, on, false);
545 m_flipConsole->enableButton(FlipConsole::eCompare, on, false);
546 m_flipConsole->enableButton(FlipConsole::eSaveImg, on, false);
547 m_flipConsole->enableButton(FlipConsole::eGRed, on, false);
548 m_flipConsole->enableButton(FlipConsole::eGGreen, on, false);
549 m_flipConsole->enableButton(FlipConsole::eGBlue, on, false);
550 m_flipConsole->enableButton(FlipConsole::eBlackBg, on, false);
551 m_flipConsole->enableButton(FlipConsole::eWhiteBg, on, false);
552 m_flipConsole->enableButton(FlipConsole::eCheckBg, on, false);
553
554 m_flipConsole->enableProgressBar(on);
555 update();
556 }
557
558 //-----------------------------------------------------------------------------
559
onXshLevelSwitched(TXshLevel *)560 void ComboViewerPanel::onXshLevelSwitched(TXshLevel *) {
561 changeWindowTitle();
562 m_sceneViewer->update();
563 // If the level is switched by using the combobox in the film strip, the
564 // current level switches without change in the frame type (level or scene).
565 // For such case, update the frame range of the console here.
566 if (TApp::instance()->getCurrentFrame()->isEditingLevel()) updateFrameRange();
567 }
568
569 //-----------------------------------------------------------------------------
570
onPlayingStatusChanged(bool playing)571 void ComboViewerPanel::onPlayingStatusChanged(bool playing) {
572 if (playing) {
573 m_playing = true;
574 } else {
575 m_playing = false;
576 m_first = true;
577 }
578 if (Preferences::instance()->getOnionSkinDuringPlayback()) return;
579 OnionSkinMask osm =
580 TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask();
581 if (playing) {
582 m_onionSkinActive = osm.isEnabled();
583 if (m_onionSkinActive) {
584 osm.enable(false);
585 TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(osm);
586 TApp::instance()->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
587 }
588 } else {
589 if (m_onionSkinActive) {
590 osm.enable(true);
591 TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(osm);
592 TApp::instance()->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
593 }
594 }
595 m_sceneViewer->invalidateToolStatus();
596 }
597
598 //-----------------------------------------------------------------------------
599
changeWindowTitle()600 void ComboViewerPanel::changeWindowTitle() {
601 TApp *app = TApp::instance();
602 ToonzScene *scene = app->getCurrentScene()->getScene();
603 if (!scene) return;
604 if (!parentWidget()) return;
605 int frame = app->getCurrentFrame()->getFrame();
606
607 // put the titlebar texts in this string
608 QString name;
609
610 // if the frame type is "scene editing"
611 if (app->getCurrentFrame()->isEditingScene()) {
612 TProject *project = scene->getProject();
613 QString sceneName = QString::fromStdWString(scene->getSceneName());
614 if (sceneName.isEmpty()) sceneName = tr("Untitled");
615
616 if (app->getCurrentScene()->getDirtyFlag()) sceneName += QString("*");
617 name = tr("Scene: ") + sceneName;
618 if (frame >= 0)
619 name =
620 name + tr(" :: Frame: ") + tr(std::to_string(frame + 1).c_str());
621 int col = app->getCurrentColumn()->getColumnIndex();
622 if (col < 0) {
623 if ((m_sceneViewer->getIsFlippedX() || m_sceneViewer->getIsFlippedY()) &&
624 !m_sceneViewer->is3DView()) {
625 name = name + tr(" (Flipped)");
626 }
627 parentWidget()->setWindowTitle(name);
628 return;
629 }
630 TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
631 TXshCell cell = xsh->getCell(frame, col);
632 if (cell.isEmpty()) {
633 if ((m_sceneViewer->getIsFlippedX() || m_sceneViewer->getIsFlippedY()) &&
634 !m_sceneViewer->is3DView()) {
635 name = name + tr(" (Flipped)");
636 }
637 parentWidget()->setWindowTitle(name);
638 return;
639 }
640 assert(cell.m_level.getPointer());
641 TFilePath fp(cell.m_level->getName());
642 QString imageName =
643 QString::fromStdWString(fp.withFrame(cell.m_frameId).getWideString());
644 name = name + tr(" :: Level: ") + imageName;
645
646 if (!m_sceneViewer->is3DView()) {
647 TAffine aff = m_sceneViewer->getViewMatrix();
648 if (m_sceneViewer->getIsFlippedX()) aff = aff * TScale(-1, 1);
649 if (m_sceneViewer->getIsFlippedY()) aff = aff * TScale(1, -1);
650 name = name + " :: Zoom : " +
651 QString::number((int)(100.0 * sqrt(aff.det()) *
652 m_sceneViewer->getDpiFactor())) +
653 "%";
654 }
655
656 // If the current level exists and some option is set in the preference,
657 // set the zoom value to the current level's dpi
658 else if (Preferences::instance()
659 ->isActualPixelViewOnSceneEditingModeEnabled() &&
660 TApp::instance()->getCurrentLevel()->getSimpleLevel() &&
661 !CleanupPreviewCheck::instance()
662 ->isEnabled() // cleanup preview must be OFF
663 &&
664 !CameraTestCheck::instance() // camera test mode must be OFF
665 // neither
666 ->isEnabled() &&
667 !m_sceneViewer->is3DView()) {
668 TAffine aff = m_sceneViewer->getViewMatrix();
669 if (m_sceneViewer->getIsFlippedX()) aff = aff * TScale(-1, 1);
670 if (m_sceneViewer->getIsFlippedY()) aff = aff * TScale(1, -1);
671 name = name + " :: Zoom : " +
672 QString::number((int)(100.0 * sqrt(aff.det()) *
673 m_sceneViewer->getDpiFactor())) +
674 "%";
675 }
676
677 }
678 // if the frame type is "level editing"
679 else {
680 TXshLevel *level = app->getCurrentLevel()->getLevel();
681 if (level) {
682 TFilePath fp(level->getName());
683 QString imageName = QString::fromStdWString(
684 fp.withFrame(app->getCurrentFrame()->getFid()).getWideString());
685
686 name = name + tr("Level: ") + imageName;
687 if (!m_sceneViewer->is3DView()) {
688 TAffine aff = m_sceneViewer->getViewMatrix();
689 if (m_sceneViewer->getIsFlippedX()) aff = aff * TScale(-1, 1);
690 if (m_sceneViewer->getIsFlippedY()) aff = aff * TScale(1, -1);
691 name = name + " :: Zoom : " +
692 QString::number((int)(100.0 * sqrt(aff.det()) *
693 m_sceneViewer->getDpiFactor())) +
694 "%";
695 }
696 }
697 }
698 if ((m_sceneViewer->getIsFlippedX() || m_sceneViewer->getIsFlippedY()) &&
699 !m_sceneViewer->is3DView()) {
700 name = name + tr(" (Flipped)");
701 }
702 parentWidget()->setWindowTitle(name);
703 }
704
705 //-----------------------------------------------------------------------------
706 /*! update the frame range according to the current frame type
707 */
updateFrameRange()708 void ComboViewerPanel::updateFrameRange() {
709 TFrameHandle *fh = TApp::instance()->getCurrentFrame();
710 int frameIndex = fh->getFrameIndex();
711 int maxFrameIndex = fh->getMaxFrameIndex();
712 if (frameIndex > maxFrameIndex) frameIndex = maxFrameIndex;
713 m_flipConsole->setFrameRange(1, maxFrameIndex + 1, 1, frameIndex + 1);
714 }
715
716 //-----------------------------------------------------------------------------
717
onSceneChanged()718 void ComboViewerPanel::onSceneChanged() {
719 TFrameHandle *fh = TApp::instance()->getCurrentFrame();
720 int frameIndex = fh->getFrameIndex();
721 int maxFrameIndex = fh->getMaxFrameIndex();
722 if (frameIndex > maxFrameIndex) maxFrameIndex = frameIndex;
723 // update fps only when the scene settings is changed
724 m_flipConsole->setFrameRate(TApp::instance()
725 ->getCurrentScene()
726 ->getScene()
727 ->getProperties()
728 ->getOutputProperties()
729 ->getFrameRate(),
730 false);
731 // update the frame slider's range with new frameHandle
732 m_flipConsole->setFrameRange(1, maxFrameIndex + 1, 1, frameIndex + 1);
733
734 // set the markers
735 int fromIndex, toIndex, dummy;
736 XsheetGUI::getPlayRange(fromIndex, toIndex, dummy);
737 m_flipConsole->setMarkers(fromIndex, toIndex);
738
739 // update the key frames
740 if (m_keyFrameButton && (m_keyFrameButton->getCurrentFrame() != frameIndex))
741 m_keyFrameButton->setCurrentFrame(frameIndex);
742 hasSoundtrack();
743 }
744
745 //-----------------------------------------------------------------------------
746
onSceneSwitched()747 void ComboViewerPanel::onSceneSwitched() {
748 m_previewButton->setPressed(false);
749 m_subcameraPreviewButton->setPressed(false);
750 enableFlipConsoleForCamerastand(false);
751 m_sceneViewer->enablePreview(SceneViewer::NO_PREVIEW);
752 m_flipConsole->setChecked(FlipConsole::eDefineSubCamera, false);
753 m_flipConsole->setFrameRate(TApp::instance()
754 ->getCurrentScene()
755 ->getScene()
756 ->getProperties()
757 ->getOutputProperties()
758 ->getFrameRate());
759 m_sceneViewer->setEditPreviewSubcamera(false);
760 onSceneChanged();
761 }
762
763 //-----------------------------------------------------------------------------
764
onFrameChanged()765 void ComboViewerPanel::onFrameChanged() {
766 int frameIndex = TApp::instance()->getCurrentFrame()->getFrameIndex();
767 m_flipConsole->setCurrentFrame(frameIndex + 1);
768 if (m_keyFrameButton && (m_keyFrameButton->getCurrentFrame() != frameIndex))
769 m_keyFrameButton->setCurrentFrame(frameIndex);
770
771 if (m_playing && m_playSound) {
772 if (m_first == true && hasSoundtrack()) {
773 playAudioFrame(frameIndex);
774 } else if (m_hasSoundtrack) {
775 playAudioFrame(frameIndex);
776 }
777 }
778 }
779
780 //-----------------------------------------------------------------------------
781 /*! reset the marker positions in the flip console
782 */
onFrameTypeChanged()783 void ComboViewerPanel::onFrameTypeChanged() {
784 if (TApp::instance()->getCurrentFrame()->getFrameType() ==
785 TFrameHandle::LevelFrame &&
786 m_sceneViewer->isPreviewEnabled()) {
787 m_previewButton->setPressed(false);
788 m_subcameraPreviewButton->setPressed(false);
789 enableFlipConsoleForCamerastand(false);
790 m_sceneViewer->enablePreview(SceneViewer::NO_PREVIEW);
791 }
792 m_flipConsole->setChecked(FlipConsole::eDefineSubCamera, false);
793 m_sceneViewer->setEditPreviewSubcamera(false);
794
795 updateFrameRange();
796
797 // if in the scene editing mode, get the preview marker positions
798 if (TApp::instance()->getCurrentFrame()->isEditingScene()) {
799 // set the markers
800 int fromIndex, toIndex, dummy;
801 XsheetGUI::getPlayRange(fromIndex, toIndex, dummy);
802 m_flipConsole->setMarkers(fromIndex, toIndex);
803 }
804 // if in the level editing mode, ignore the preview marker
805 else
806 m_flipConsole->setMarkers(0, -1);
807 }
808
809 //-----------------------------------------------------------------------------
810
playAudioFrame(int frame)811 void ComboViewerPanel::playAudioFrame(int frame) {
812 if (m_first) {
813 m_first = false;
814 m_fps = TApp::instance()
815 ->getCurrentScene()
816 ->getScene()
817 ->getProperties()
818 ->getOutputProperties()
819 ->getFrameRate();
820 m_samplesPerFrame = m_sound->getSampleRate() / std::abs(m_fps);
821 }
822 if (!m_sound) return;
823 m_viewerFps = m_flipConsole->getCurrentFps();
824 double s0 = frame * m_samplesPerFrame, s1 = s0 + m_samplesPerFrame;
825 // make the sound stop if the viewerfps is higher so the next sound can play
826 // on time.
827 if (m_fps < m_viewerFps)
828 TApp::instance()->getCurrentXsheet()->getXsheet()->stopScrub();
829 TApp::instance()->getCurrentXsheet()->getXsheet()->play(m_sound, s0, s1,
830 false);
831 }
832
833 //-----------------------------------------------------------------------------
834
hasSoundtrack()835 bool ComboViewerPanel::hasSoundtrack() {
836 if (m_sound != NULL) {
837 m_sound = NULL;
838 m_hasSoundtrack = false;
839 m_first = true;
840 }
841 TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet();
842 TXsheet::SoundProperties *prop = new TXsheet::SoundProperties();
843 if (!m_sceneViewer->isPreviewEnabled()) prop->m_isPreview = true;
844 m_sound = xsheetHandle->getXsheet()->makeSound(prop);
845 if (m_sound == NULL) {
846 m_hasSoundtrack = false;
847 return false;
848 } else {
849 m_hasSoundtrack = true;
850 return true;
851 }
852 }
853
onButtonPressed(FlipConsole::EGadget button)854 void ComboViewerPanel::onButtonPressed(FlipConsole::EGadget button) {
855 if (button == FlipConsole::eSound) {
856 m_playSound = !m_playSound;
857 }
858 }
859
setFlipHButtonChecked(bool checked)860 void ComboViewerPanel::setFlipHButtonChecked(bool checked) {
861 m_flipConsole->setChecked(FlipConsole::eFlipHorizontal, checked);
862 }
863
setFlipVButtonChecked(bool checked)864 void ComboViewerPanel::setFlipVButtonChecked(bool checked) {
865 m_flipConsole->setChecked(FlipConsole::eFlipVertical, checked);
866 }
867
868 //-----------------------------------------------------------------------------
869
setVisiblePartsFlag(UINT flag)870 void ComboViewerPanel::setVisiblePartsFlag(UINT flag) {
871 m_visiblePartsFlag = flag;
872 updateShowHide();
873 }
874
875 // SaveLoadQSettings
save(QSettings & settings) const876 void ComboViewerPanel::save(QSettings &settings) const {
877 settings.setValue("visibleParts", m_visiblePartsFlag);
878 }
879
load(QSettings & settings)880 void ComboViewerPanel::load(QSettings &settings) {
881 m_visiblePartsFlag = settings.value("visibleParts", CVPARTS_ALL).toUInt();
882 updateShowHide();
883 }