Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAnimTimelineDocker Class Reference

Krita's Animation Timeline Docker. This is the GUI heart of Krita's traditional animation workflow, and is where artists can configure, edit, scrub and play their animation. More...

#include <KisAnimTimelineDocker.h>

+ Inheritance diagram for KisAnimTimelineDocker:

Classes

struct  Private
 

Public Slots

void handleFrameRateChange ()
 
void handleThemeChange ()
 
void setAutoKey (bool value)
 
void setImageAnimSettings ()
 
void togglePlayback ()
 
void updateFrameCache ()
 
void updateFrameRegister ()
 
void updatePlaybackStatistics ()
 

Public Member Functions

 KisAnimTimelineDocker ()
 
QString observerName () override
 
void setCanvas (KoCanvasBase *canvas) override
 
void setPlaybackEngine (KisPlaybackEngine *playbackEngine)
 
void setViewManager (KisViewManager *kisview) override
 
void unsetCanvas () override
 
 ~KisAnimTimelineDocker () override
 
- Public Member Functions inherited from KisMainwindowObserver
 KisMainwindowObserver ()
 
 ~KisMainwindowObserver () override
 
- Public Member Functions inherited from KoCanvasObserverBase
 KoCanvasObserverBase ()
 
KoCanvasBaseobservedCanvas () const
 
void setObservedCanvas (KoCanvasBase *canvas)
 
void unsetObservedCanvas ()
 
virtual ~KoCanvasObserverBase ()
 

Private Member Functions

void establishPlaybackEngineConnections (KisPlaybackEngine *playbackEngine, KisActionManager *actionManager=nullptr)
 

Private Attributes

const QScopedPointer< Privatem_d
 

Additional Inherited Members

Detailed Description

Krita's Animation Timeline Docker. This is the GUI heart of Krita's traditional animation workflow, and is where artists can configure, edit, scrub and play their animation.

Currently interacts with the TimelineFramesView/Model as well as the KisImageAnimationInterface. (TODO: Consider refactoring to streamline this interaction towards Docker -> AnimationPlayer -> ImageAnimInterface)

Definition at line 91 of file KisAnimTimelineDocker.h.

Constructor & Destructor Documentation

◆ KisAnimTimelineDocker()

KisAnimTimelineDocker::KisAnimTimelineDocker ( )

Definition at line 300 of file KisAnimTimelineDocker.cpp.

301 : QDockWidget(i18n("Animation Timeline"))
302 , m_d(new Private(this))
303{
304 setWidget(m_d->framesView);
305
306 // Titlebar Widget..
307 setTitleBarWidget(m_d->titlebar);
308
309 connect(m_d->titlebar->btnOnionSkinsMenu, &QToolButton::released, [this](){
310 if (m_d->mainWindow) {
311 QDockWidget *docker = m_d->mainWindow->dockWidget("OnionSkinsDocker");
312 if (docker) {
313 docker->setVisible(!docker->isVisible());
314 }
315 }
316 });
317
318 {
319 using namespace KisWidgetConnectionUtils;
320 connectControl(m_d->titlebar->sbSpeed, &m_d->controlsModel, "playbackSpeedDenorm");
321 }
322
323 // Watch for KisPlaybackEngine changes and initialize current one..
325 setPlaybackEngine(KisPart::instance()->playbackEngine());
326
327 setEnabled(false);
328}
void setPlaybackEngine(KisPlaybackEngine *playbackEngine)
const QScopedPointer< Private > m_d
static KisPart * instance()
Definition KisPart.cpp:130
void playbackEngineChanged(KisPlaybackEngine *newPlaybackEngine)
void connectControl(KisCompositeOpListWidget *widget, QObject *source, const char *property)

References m_d.

◆ ~KisAnimTimelineDocker()

KisAnimTimelineDocker::~KisAnimTimelineDocker ( )
override

Definition at line 330 of file KisAnimTimelineDocker.cpp.

331{
332}

Member Function Documentation

◆ establishPlaybackEngineConnections()

void KisAnimTimelineDocker::establishPlaybackEngineConnections ( KisPlaybackEngine * playbackEngine,
KisActionManager * actionManager = nullptr )
private

Definition at line 515 of file KisAnimTimelineDocker.cpp.

516{
517 if (actionManager) {
518 // Connect actions..
519 KisAction *action = nullptr;
520
521 action = actionManager->createAction("stop_playback");
523 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(stop()));
524
525 action = actionManager->createAction("previous_frame");
527 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(previousFrame()));
528
529 action = actionManager->createAction("next_frame");
531 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(nextFrame()));
532
533 action = actionManager->createAction("previous_keyframe");
535 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(previousKeyframe()));
536
537 action = actionManager->createAction("next_keyframe");
539 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(nextKeyframe()));
540
541 action = actionManager->createAction("previous_matching_keyframe");
543 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(previousMatchingKeyframe()));
544
545 action = actionManager->createAction("next_matching_keyframe");
547 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(nextMatchingKeyframe()));
548
549 action = actionManager->createAction("previous_unfiltered_keyframe");
551 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(previousUnfilteredKeyframe()));
552
553 action = actionManager->createAction("next_unfiltered_keyframe");
555 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(nextUnfilteredKeyframe()));
556
557 action = actionManager->createAction("first_frame");
559 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(firstFrame()));
560
561 action = actionManager->createAction("last_frame");
563 connect(action, SIGNAL(triggered(bool)), playbackEngine, SLOT(lastFrame()));
564 }
565
566 // Connect transport controls gui..
567 connect(m_d->titlebar->transport, SIGNAL(skipBack()), playbackEngine, SLOT(previousKeyframe()), Qt::UniqueConnection);
568 connect(m_d->titlebar->transport, SIGNAL(back()), playbackEngine, SLOT(previousFrame()), Qt::UniqueConnection);
569 connect(m_d->titlebar->transport, SIGNAL(stop()), playbackEngine, SLOT(stop()), Qt::UniqueConnection);
570 connect(m_d->titlebar->transport, SIGNAL(playPause()), this, SLOT(togglePlayback()), Qt::UniqueConnection);
571 connect(m_d->titlebar->transport, SIGNAL(forward()), playbackEngine, SLOT(nextFrame()), Qt::UniqueConnection);
572 connect(m_d->titlebar->transport, SIGNAL(skipForward()), playbackEngine, SLOT(nextKeyframe()), Qt::UniqueConnection);
573
574 connect(m_d->titlebar->frameRegister, SIGNAL(valueChanged(int)), playbackEngine, SLOT(seek(int)), Qt::UniqueConnection);
575}
KisAction * createAction(const QString &name)
void setActivationFlags(ActivationFlags flags)
@ ACTIVE_IMAGE
Activate if there is at least one image.
Definition kis_action.h:43
QAction * back(const QObject *recvr, const char *slot, QObject *parent)
QAction * forward(const QObject *recvr, const char *slot, QObject *parent)

References KisAction::ACTIVE_IMAGE, KisActionManager::createAction(), m_d, KisAction::setActivationFlags(), and togglePlayback().

◆ handleFrameRateChange

void KisAnimTimelineDocker::handleFrameRateChange ( )
slot

Definition at line 764 of file KisAnimTimelineDocker.cpp.

765{
766 if (!m_d->canvas || !m_d->canvas->image()) return;
767
768 KisImageAnimationInterface *animInterface = m_d->canvas->image()->animationInterface();
769
770 m_d->titlebar->sbFrameRate->setValue(animInterface->framerate());
771}
KisImageAnimationInterface * animationInterface() const

References KisImage::animationInterface(), KisImageAnimationInterface::framerate(), KisImageAnimationInterface::image(), and m_d.

◆ handleThemeChange

void KisAnimTimelineDocker::handleThemeChange ( )
slot

Definition at line 486 of file KisAnimTimelineDocker.cpp.

487{
488 if (m_d->framesView) {
489 m_d->framesView->slotUpdateIcons();
490 }
491}

References m_d.

◆ observerName()

QString KisAnimTimelineDocker::observerName ( )
inlineoverridevirtual

Reimplemented from KoCanvasObserverBase.

Definition at line 98 of file KisAnimTimelineDocker.h.

98{ return "TimelineDocker"; }

◆ setAutoKey

void KisAnimTimelineDocker::setAutoKey ( bool value)
slot

Definition at line 750 of file KisAnimTimelineDocker.cpp.

751{
752 {
753 KisImageConfig cfg(false);
754 if (value != cfg.autoKeyEnabled()) {
755 cfg.setAutoKeyEnabled(value);
756 const QIcon icon = cfg.autoKeyEnabled() ? KisIconUtils::loadIcon("auto-key-on") : KisIconUtils::loadIcon("auto-key-off");
757 QAction* action = m_d->titlebar->btnAutoKey->defaultAction();
758 action->setIcon(icon);
759 }
760 }
762}
float value(const T *src, size_t ch)
static KisImageConfigNotifier * instance()
QIcon loadIcon(const QString &name)

References KisImageConfig::autoKeyEnabled(), KisImageConfigNotifier::instance(), KisIconUtils::loadIcon(), m_d, KisImageConfigNotifier::notifyAutoKeyFrameConfigurationChanged(), KisImageConfig::setAutoKeyEnabled(), and value().

◆ setCanvas()

void KisAnimTimelineDocker::setCanvas ( KoCanvasBase * canvas)
overridevirtual

re-implement this method in your canvas observer. It will be called whenever a canvas becomes active. Note that you are responsible for not connecting more than one time to the signals of a canvas or any of the QObjects you can access through the canvas.

Implements KoCanvasObserverBase.

Definition at line 355 of file KisAnimTimelineDocker.cpp.

356{
357 if (m_d->canvas == canvas) return;
358
359 if (m_d->framesModel->hasConnectionToCanvas()) {
360 m_d->canvasConnections.clear();
361 m_d->framesModel->setDummiesFacade(0, 0, 0);
362 m_d->framesModel->setFrameCache(0);
363 m_d->framesModel->setAnimationPlayer(0);
364 m_d->framesModel->setDocument(0);
365 m_d->framesModel->setNodeManipulationInterface(0);
366 }
367
368 // Deinitialize from previous canvas...
369 if (m_d->canvas) {
370 m_d->canvas->disconnectCanvasObserver(this);
371 m_d->canvas->animationState()->disconnect(this);
372 m_d->titlebar->transport->setPlaying(false);
373
374 m_d->titlebar->btnAudioMenu->setEnabled(false);
375
376 if(m_d->canvas->image()) {
377 m_d->canvas->image()->animationInterface()->disconnect(this);
378 m_d->titlebar->sbStartFrame->disconnect(m_d->canvas->image()->animationInterface());
379 m_d->titlebar->sbEndFrame->disconnect(m_d->canvas->image()->animationInterface());
380 m_d->titlebar->sbFrameRate->disconnect(m_d->canvas->image()->animationInterface());
381 }
382 }
383
384 m_d->canvas = dynamic_cast<KisCanvas2*>(canvas);
385 setEnabled(m_d->canvas != 0);
386 m_d->framesView->slotCanvasUpdate(m_d->canvas);
387
388 // Reinitialize new canvas..
389 if (m_d->canvas) {
390 KisDocument *doc = static_cast<KisDocument*>(m_d->canvas->imageView()->document());
391 KisShapeController *kritaShapeController = dynamic_cast<KisShapeController*>(doc->shapeController());
392 m_d->framesModel->setDummiesFacade(kritaShapeController,
393 m_d->canvas->image(),
394 m_d->canvas->viewManager()->nodeManager()->nodeDisplayModeAdapter());
395
396 m_d->framesModel->setDocument(doc);
397
399
400 { // Titlebar widgets...
401 KisSignalsBlocker blocker(m_d->titlebar->sbStartFrame,
402 m_d->titlebar->sbEndFrame,
403 m_d->titlebar->sbFrameRate,
404 m_d->titlebar->frameRegister);
405
406 KisImageAnimationInterface *animinterface = m_d->canvas->image()->animationInterface();
407 m_d->titlebar->sbStartFrame->setValue(animinterface->documentPlaybackRange().start());
408 m_d->titlebar->sbEndFrame->setValue(animinterface->documentPlaybackRange().end());
409 m_d->titlebar->sbFrameRate->setValue(animinterface->framerate());
410 m_d->titlebar->frameRegister->setValue(animinterface->currentTime());
411
412 m_d->titlebar->btnAudioMenu->setEnabled(true); // Menu is disabled until a canvas is loaded.
413 }
414
415 m_d->framesModel->setAnimationPlayer(m_d->canvas->animationState());
416
417 m_d->framesModel->setNodeManipulationInterface(
418 new NodeManagerInterface(m_d->canvas->viewManager()->nodeManager()));
419
420 m_d->canvasConnections.addConnection(
421 m_d->canvas->viewManager()->nodeManager(), SIGNAL(sigNodeActivated(KisNodeSP)),
422 m_d->framesModel, SLOT(slotCurrentNodeChanged(KisNodeSP)));
423
424 m_d->canvasConnections.addConnection(
425 m_d->framesModel, SIGNAL(requestCurrentNodeChanged(KisNodeSP)),
426 m_d->canvas->viewManager()->nodeManager(), SLOT(slotNonUiActivatedNode(KisNodeSP)));
427
428 m_d->framesModel->slotCurrentNodeChanged(m_d->canvas->viewManager()->activeNode());
429
430 m_d->canvasConnections.addConnection(
431 m_d->canvas->viewManager()->mainWindow(), SIGNAL(themeChanged()),
432 this, SLOT(handleThemeChange()));
433
434 m_d->canvasConnections.addConnection(
435 m_d->canvas, SIGNAL(sigCanvasEngineChanged()),
436 this, SLOT(updateFrameCache()));
437
438 m_d->titlebar->transport->setPlaying(m_d->canvas->animationState()->playbackState() == PlaybackState::PLAYING);
439
440 m_d->titlebar->volumeSlider->setValue(m_d->framesModel->audioVolume() * 100.0);
441
442 connect(m_d->canvas->image()->animationInterface(), SIGNAL(sigFramerateChanged()), SLOT(handleFrameRateChange()));
443
444 connect(m_d->titlebar->sbFrameRate, SIGNAL(valueChanged(int)), this, SLOT(setImageAnimSettings()));
445 connect(m_d->titlebar->sbStartFrame, SIGNAL(valueChanged(int)), this, SLOT(setImageAnimSettings()));
446 connect(m_d->titlebar->sbEndFrame, SIGNAL(valueChanged(int)), this, SLOT(setImageAnimSettings()));
447
448 connect(m_d->canvas->image()->animationInterface(), &KisImageAnimationInterface::sigDocumentRangeChanged, this, [this]() {
449 if (!m_d->canvas || !m_d->canvas->image()) return;
450
451 KisImageAnimationInterface *animInterface = m_d->canvas->image()->animationInterface();
452
453 int start = animInterface->documentPlaybackRange().start();
454 int end = animInterface->documentPlaybackRange().end();
455
456 m_d->titlebar->sbStartFrame->setValue(start);
457 m_d->titlebar->sbEndFrame->setValue(end);
458
459 //Auto zoom Timeline to new document playback range..
460 KisConfig cfg(true);
461 if (cfg.autoZoomTimelineToPlaybackRange()) {
462 m_d->framesView->slotFitViewToFrameRange(0, end); // TODO: fit from start to end, instead of 0 to end.
463 }
464 });
465
466 connect(m_d->canvas->animationState(), SIGNAL(sigFrameChanged()), this, SLOT(updateFrameRegister()));
467 connect(m_d->canvas->animationState(), &KisCanvasAnimationState::sigPlaybackStateChanged, this, [this](PlaybackState state){
468 m_d->titlebar->frameRegister->setDisabled(state == PlaybackState::PLAYING);
469 if (state == PlaybackState::STOPPED) {
470 updateFrameRegister();
471 }
472 });
473 connect(m_d->canvas->animationState(), &KisCanvasAnimationState::sigPlaybackStateChanged, this, [this](PlaybackState state){
474 m_d->titlebar->transport->setPlaying(state == PlaybackState::PLAYING);
475 });
476
477 connect(m_d->canvas->animationState(), &KisCanvasAnimationState::sigPlaybackStatisticsUpdated,
479
480 connect(m_d->canvas->image()->animationInterface(), SIGNAL(sigUiTimeChanged(int)), this, SLOT(updateFrameRegister()));
481
482 m_d->controlsModel.connectAnimationState(m_d->canvas->animationState());
483 }
484}
void sigPlaybackStateChanged(PlaybackState state)
KisShapeController * shapeController
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
int start() const
int end() const

References KisImage::animationInterface(), Private::canvas, KisImageAnimationInterface::currentTime(), KisImageAnimationInterface::documentPlaybackRange(), KisTimeSpan::end(), KisImageAnimationInterface::framerate(), handleFrameRateChange(), handleThemeChange(), KisImageAnimationInterface::image(), KisDummiesFacadeBase::image(), m_d, KisNodeManager::nodeDisplayModeAdapter(), KisViewManager::nodeManager(), PLAYING, setImageAnimSettings(), KisDocument::shapeController, KisImageAnimationInterface::sigDocumentRangeChanged(), KisCanvasAnimationState::sigPlaybackStateChanged(), KisTimeSpan::start(), updateFrameCache(), updateFrameRegister(), and KisCanvas2::viewManager().

◆ setImageAnimSettings

void KisAnimTimelineDocker::setImageAnimSettings ( )
slot

Definition at line 493 of file KisAnimTimelineDocker.cpp.

494{
495 if (!m_d->canvas || !m_d->canvas->image()) return;
496
498 m_d->titlebar->sbFrameRate->value(),
499 m_d->titlebar->sbStartFrame->value(),
500 m_d->titlebar->sbEndFrame->value()
501 };
502
503 KisImageAnimSettingCommand *undoCommand = new KisImageAnimSettingCommand(m_d->canvas->image()->animationInterface(), settings);
504
505 //KisProcessingApplicator::applyCommand(undoCommand);
506 QScopedPointer<KisProcessingApplicator> applicator(
509 undoCommand->text(),
510 0, undoCommand->id()));
511 applicator->applyCommand(undoCommand);
512 applicator->end();
513}
KUndo2MagicString text() const

References KisImageAnimSettingCommand::id(), m_d, KisProcessingApplicator::NONE, and KUndo2Command::text().

◆ setPlaybackEngine()

void KisAnimTimelineDocker::setPlaybackEngine ( KisPlaybackEngine * playbackEngine)

Definition at line 711 of file KisAnimTimelineDocker.cpp.

712{
713 if (!playbackEngine) return;
714
715 m_d->controlsModel.connectPlaybackEngine(playbackEngine);
716
717 m_d->playbackEngine = playbackEngine;
718
719 KisActionManager *actionManager = nullptr;
720 if (m_d->canvas && m_d->canvas->viewManager()) {
721 actionManager = m_d->canvas->viewManager()->actionManager();
722 }
723 establishPlaybackEngineConnections(m_d->playbackEngine, actionManager);
724}
A KisActionManager class keeps track of KisActions. These actions are always associated with the GUI....
void establishPlaybackEngineConnections(KisPlaybackEngine *playbackEngine, KisActionManager *actionManager=nullptr)
KisViewManager * viewManager() const
KisActionManager * actionManager() const
KisCanvas2 * canvas

References KisViewManager::actionManager(), Private::canvas, establishPlaybackEngineConnections(), m_d, and KisCanvas2::viewManager().

◆ setViewManager()

void KisAnimTimelineDocker::setViewManager ( KisViewManager * kisview)
overridevirtual

Implements KisMainwindowObserver.

Definition at line 657 of file KisAnimTimelineDocker.cpp.

658{
659 m_d->mainWindow = view->mainWindow();
660 KisActionManager *actionManager = view->actionManager();
661 m_d->framesView->setActionManager(actionManager);
662
663 KisAction *action = 0;
664
665 KisAnimTimelineDockerTitlebar* titleBar = static_cast<KisAnimTimelineDockerTitlebar*>(titleBarWidget());
666
667 action = actionManager->actionByName("add_blank_frame");
668 titleBar->btnAddKeyframe->setDefaultAction(action);
669 titleBar->btnAddKeyframe->setIconSize(QSize(22, 22));
670
671 action = actionManager->actionByName("add_duplicate_frame");
672 titleBar->btnDuplicateKeyframe->setDefaultAction(action);
673 titleBar->btnDuplicateKeyframe->setIconSize(QSize(22, 22));
674
675 action = actionManager->actionByName("remove_frames");
676 titleBar->btnRemoveKeyframe->setDefaultAction(action);
677 titleBar->btnRemoveKeyframe->setIconSize(QSize(22, 22));
678
679 // Connect playback-related actions..
680 action = actionManager->createAction("toggle_playback");
682 connect(action, SIGNAL(triggered(bool)), this, SLOT(togglePlayback()));
683
684 establishPlaybackEngineConnections(m_d->playbackEngine, actionManager);
685
686 {
687 action = actionManager->createAction("auto_key");
688 m_d->titlebar->btnAutoKey->setDefaultAction(action);
689 m_d->titlebar->btnAutoKey->setIconSize(QSize(22, 22));
690 connect(action, SIGNAL(triggered(bool)), SLOT(setAutoKey(bool)));
691
692 KisImageConfig config(true);
693 action->setChecked(config.autoKeyEnabled());
694 action->setIcon(config.autoKeyEnabled() ? KisIconUtils::loadIcon("auto-key-on") : KisIconUtils::loadIcon("auto-key-off"));
695
696 const bool autoKeyModeDuplicate = config.autoKeyModeDuplicate();
697 m_d->titlebar->autoKeyBlank->setChecked(!autoKeyModeDuplicate);
698 m_d->titlebar->autoKeyDuplicate->setChecked(autoKeyModeDuplicate);
699 }
700
701 {
702 action = actionManager->createAction("drop_frames");
703 m_d->titlebar->btnDropFrames->setDefaultAction(action);
704 m_d->titlebar->btnDropFrames->setIconSize(QSize(22, 22));
705
706 using namespace KisWidgetConnectionUtils;
707 connectControl(action, &m_d->controlsModel, "dropFramesMode");
708 }
709}
KisAction * actionByName(const QString &name) const
A customized titlebar for the Animation Timeline Docker that's packed with useful widgets and menus.

References KisActionManager::actionByName(), KisViewManager::actionManager(), KisAction::ACTIVE_IMAGE, KisImageConfig::autoKeyEnabled(), KisImageConfig::autoKeyModeDuplicate(), KisAnimTimelineDockerTitlebar::btnAddKeyframe, KisAnimTimelineDockerTitlebar::btnDuplicateKeyframe, KisAnimTimelineDockerTitlebar::btnRemoveKeyframe, KisActionManager::createAction(), establishPlaybackEngineConnections(), KisIconUtils::loadIcon(), m_d, KisViewManager::mainWindow(), KisAction::setActivationFlags(), setAutoKey(), and togglePlayback().

◆ togglePlayback

void KisAnimTimelineDocker::togglePlayback ( )
slot

Definition at line 726 of file KisAnimTimelineDocker.cpp.

727{
728 m_d->playbackEngine->playPause();
729
730 KisImageAnimationInterface *animInterface = m_d->canvas->image()->animationInterface();
731 KisCanvasAnimationState *animState = m_d->canvas->animationState();
732
733 if (!animInterface || !animState) return;
734
735 if (animState->playbackState() == PlaybackState::PAUSED) {
736 QModelIndexList selectedIndices = m_d->framesView->selectionModel()->selectedIndexes();
737 QModelIndex currentIndex = m_d->framesView->currentIndex();
738 const int pausedTime = animInterface->currentTime();
739
740 QModelIndex pauseIndex = m_d->framesModel->index(currentIndex.row(), pausedTime);
741
742 if (!pauseIndex.isValid()) return;
743
744 if (!selectedIndices.contains(pauseIndex)) {
745 m_d->framesView->setCurrentIndex(pauseIndex);
746 }
747 }
748}
The KisCanvasAnimationState class stores all of the canvas-specific animation state.

References KisImage::animationInterface(), KisImageAnimationInterface::currentTime(), KisImageAnimationInterface::image(), m_d, PAUSED, and KisCanvasAnimationState::playbackState().

◆ unsetCanvas()

void KisAnimTimelineDocker::unsetCanvas ( )
overridevirtual

Re-implement to notify the observer that its canvas is no longer among the living. The daisies, it is pushing up. This means you don't have to disconnect, it's dead.

The old canvas should be deleted already, so if you stored a pointer to it, don't touch!

Note that currently there is a bug where in certain specific circumstances unsetCanvas can be called when it shouldn't, see for example KWStatisticsDocker for a workaround for this problem.

Implements KoCanvasObserverBase.

Definition at line 652 of file KisAnimTimelineDocker.cpp.

653{
654 setCanvas(0);
655}
void setCanvas(KoCanvasBase *canvas) override

References setCanvas().

◆ updateFrameCache

void KisAnimTimelineDocker::updateFrameCache ( )
slot

Definition at line 577 of file KisAnimTimelineDocker.cpp.

578{
579 m_d->framesModel->setFrameCache(m_d->canvas->frameCache());
580}

References m_d.

◆ updateFrameRegister

void KisAnimTimelineDocker::updateFrameRegister ( )
slot

Definition at line 582 of file KisAnimTimelineDocker.cpp.

583{
584 if (!m_d->canvas && !m_d->canvas->image()) {
585 return;
586 }
587
588 const int frame = m_d->canvas->animationState()->displayProxy()->activeFrame();
589
590 QSignalBlocker blocker(m_d->titlebar->frameRegister);
591 m_d->titlebar->frameRegister->setValue(frame);
592}

References m_d.

◆ updatePlaybackStatistics

void KisAnimTimelineDocker::updatePlaybackStatistics ( )
slot

NOTE: we update stats on the action, but not on the button itself, so the stats will automatically propagate to all the buttons that use this action, including the one in the curves docker

Definition at line 594 of file KisAnimTimelineDocker.cpp.

595{
596 if (!m_d->playbackEngine) return;
597
598 QString playbackEngineClass = m_d->playbackEngine->metaObject()->className();
599
600 qreal effectiveFps = 0.0;
601 qreal realFps = 0.0;
602 qreal framesDropped = 0.0;
603 bool isPlaying = false;
604
605 {
606 KisPlaybackEngine::PlaybackStats stats = m_d->playbackEngine->playbackStatistics();
607 effectiveFps = stats.expectedFps;
608 realFps = stats.realFps;
609 framesDropped = stats.droppedFramesPortion;
610 isPlaying = effectiveFps > 0.0;
611 }
612
613 KisConfig cfg(true);
614 const bool shouldDropFrames = cfg.animationDropFrames();
615
616 QAction *action = m_d->titlebar->btnDropFrames->defaultAction();
617 const bool droppingFrames = framesDropped > 0.05;
618 action->setIcon(KisIconUtils::loadIcon(droppingFrames ? "droppedframes" : "dropframe"));
619
620 QString actionText;
621 if (!isPlaying) {
622 actionText = QString("%1 (%2)\n"
623 "%3\n"
624 "[PlaybackEngine: %4]")
626 .arg(KritaUtils::toLocalizedOnOff(shouldDropFrames))
627 .arg(i18n("Enable to preserve playback timing."))
628 .arg(playbackEngineClass);
629 } else {
630 actionText = QString("%1 (%2)\n"
631 "%3\n"
632 "%4\n"
633 "%5\n"
634 "[PlaybackEngine: %6]")
636 .arg(KritaUtils::toLocalizedOnOff(shouldDropFrames))
637 .arg(i18n("Effective FPS:\t%1", QString::number(effectiveFps, 'f', 1)))
638 .arg(i18n("Real FPS:\t%1", QString::number(realFps, 'f', 1)))
639 .arg(i18n("Frames dropped:\t%1\%", QString::number(framesDropped * 100, 'f', 1)))
640 .arg(playbackEngineClass);
641 }
642
649 action->setToolTip(actionText);
650}
const QString dropFramesActionName
QString KRITAIMAGE_EXPORT toLocalizedOnOff(bool value)

References KisConfig::animationDropFrames(), KisAnimUtils::dropFramesActionName, KisPlaybackEngine::PlaybackStats::droppedFramesPortion, KisPlaybackEngine::PlaybackStats::expectedFps, KisIconUtils::loadIcon(), m_d, KisPlaybackEngine::PlaybackStats::realFps, and KritaUtils::toLocalizedOnOff().

Member Data Documentation

◆ m_d

const QScopedPointer<Private> KisAnimTimelineDocker::m_d
private

Definition at line 122 of file KisAnimTimelineDocker.h.


The documentation for this class was generated from the following files: