64 setFocusPolicy(Qt::ClickFocus);
92 sbSpeed->setPrefix(i18nc(
"preview playback speed percentage prefix",
"Speed: "));
94 sbSpeed->setToolTip(i18n(
"Preview playback speed"));
102 QWidget *widget =
new QWidget(
this);
103 QHBoxLayout *layout =
new QHBoxLayout(widget);
104 layout->setSpacing(0);
105 layout->setContentsMargins(0,0,0,0);
125 QWidget *widget =
new QWidget(
this);
127 QHBoxLayout *layout =
new QHBoxLayout(widget);
128 layout->setSpacing(0);
140 QMenu *audioMenu =
new QMenu(
this);
142 strImportAudio = QString(i18nc(
"@item:inmenu Load audio file into Krita from disk.",
"Import Audio..."));
144 removeAudioAction =
new QAction(i18nc(
"@item:inmenu",
"Remove audio"), audioMenu);
146 muteAudioAction =
new QAction(i18nc(
"@item:inmenu Mute audio playback.",
"Mute"), audioMenu);
153 i18nc(
"@item:inmenu Volume slider; {n} is the number value, % is the percent sign",
"Volume: {n}%"));
156 volumeSlider->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
158 QWidgetAction *volumeAction =
new QWidgetAction(audioMenu);
161 audioMenu->addSeparator();
166 audioMenu->addSeparator();
168 audioMenu->addAction(volumeAction);
191 QWidget *settingsMenuWidget =
new QWidget(
this);
192 QHBoxLayout *settingsMenuLayout =
new QHBoxLayout(settingsMenuWidget);
194 QWidget *fields =
new QWidget(settingsMenuWidget);
195 QFormLayout *fieldsLayout =
new QFormLayout(fields);
199 fieldsLayout->addRow(i18n(
"Clip Start: "),
sbStartFrame);
203 fieldsLayout->addRow(i18n(
"Clip End: "),
sbEndFrame);
208 fieldsLayout->addRow(i18n(
"Frame Rate: "),
sbFrameRate);
210 QWidget *
buttons =
new QWidget(settingsMenuWidget);
211 QVBoxLayout *buttonsLayout =
new QVBoxLayout(
buttons);
212 buttonsLayout->setAlignment(Qt::AlignTop);
216 autoKeyBlank =
new QAction(i18n(
"AutoKey Blank"),
this);
220 QActionGroup *autoKeyModes =
new QActionGroup(
this);
223 autoKeyModes->setExclusive(
true);
225 connect(autoKeyModes, &QActionGroup::triggered,
this, [
this](QAction* modeAction){
226 if (!modeAction)
return;
239 QMenu *autoKeyModeMenu =
new QMenu(settingsMenuWidget);
240 autoKeyModeMenu->addActions(autoKeyModes->actions());
243 btnAutoKey =
new QToolButton(settingsMenuWidget);
245 btnAutoKey->setPopupMode(QToolButton::MenuButtonPopup);
249 settingsMenuLayout->addWidget(fields);
250 settingsMenuLayout->addWidget(
buttons);
254 QMenu *settingsPopMenu =
new QMenu(
this);
255 QWidgetAction *settingsMenuAction =
new QWidgetAction(
this);
256 settingsMenuAction->setDefaultWidget(settingsMenuWidget);
257 settingsPopMenu->addAction(settingsMenuAction);
357 if (
m_d->canvas == canvas)
return;
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);
370 m_d->canvas->disconnectCanvasObserver(
this);
371 m_d->canvas->animationState()->disconnect(
this);
372 m_d->titlebar->transport->setPlaying(
false);
374 m_d->titlebar->btnAudioMenu->setEnabled(
false);
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());
385 setEnabled(
m_d->canvas != 0);
386 m_d->framesView->slotCanvasUpdate(
m_d->canvas);
392 m_d->framesModel->setDummiesFacade(kritaShapeController,
396 m_d->framesModel->setDocument(doc);
402 m_d->titlebar->sbEndFrame,
403 m_d->titlebar->sbFrameRate,
404 m_d->titlebar->frameRegister);
409 m_d->titlebar->sbFrameRate->setValue(animinterface->
framerate());
410 m_d->titlebar->frameRegister->setValue(animinterface->
currentTime());
412 m_d->titlebar->btnAudioMenu->setEnabled(
true);
415 m_d->framesModel->setAnimationPlayer(
m_d->canvas->animationState());
417 m_d->framesModel->setNodeManipulationInterface(
420 m_d->canvasConnections.addConnection(
421 m_d->canvas->viewManager()->nodeManager(), SIGNAL(sigNodeActivated(
KisNodeSP)),
422 m_d->framesModel, SLOT(slotCurrentNodeChanged(
KisNodeSP)));
424 m_d->canvasConnections.addConnection(
425 m_d->framesModel, SIGNAL(requestCurrentNodeChanged(
KisNodeSP)),
426 m_d->canvas->viewManager()->nodeManager(), SLOT(slotNonUiActivatedNode(
KisNodeSP)));
428 m_d->framesModel->slotCurrentNodeChanged(
m_d->canvas->viewManager()->activeNode());
430 m_d->canvasConnections.addConnection(
431 m_d->canvas->viewManager()->mainWindow(), SIGNAL(themeChanged()),
434 m_d->canvasConnections.addConnection(
435 m_d->canvas, SIGNAL(sigCanvasEngineChanged()),
440 m_d->titlebar->volumeSlider->setValue(
m_d->framesModel->audioVolume() * 100.0);
449 if (!m_d->canvas || !m_d->canvas->image()) return;
451 KisImageAnimationInterface *animInterface = m_d->canvas->image()->animationInterface();
453 int start = animInterface->documentPlaybackRange().start();
454 int end = animInterface->documentPlaybackRange().end();
456 m_d->titlebar->sbStartFrame->setValue(start);
457 m_d->titlebar->sbEndFrame->setValue(end);
461 if (cfg.autoZoomTimelineToPlaybackRange()) {
462 m_d->framesView->slotFitViewToFrameRange(0, end);
468 m_d->titlebar->frameRegister->setDisabled(state == PlaybackState::PLAYING);
469 if (state == PlaybackState::STOPPED) {
470 updateFrameRegister();
474 m_d->titlebar->transport->setPlaying(state == PlaybackState::PLAYING);
480 connect(m_d->canvas->image()->animationInterface(), SIGNAL(sigUiTimeChanged(
int)),
this, SLOT(updateFrameRegister()));
482 m_d->controlsModel.connectAnimationState(m_d->canvas->animationState());
534 if (!
m_d->playbackEngine)
return;
536 QString playbackEngineClass =
m_d->playbackEngine->metaObject()->className();
538 qreal effectiveFps = 0.0;
540 qreal framesDropped = 0.0;
541 bool isPlaying =
false;
548 isPlaying = effectiveFps > 0.0;
554 QAction *action =
m_d->titlebar->btnDropFrames->defaultAction();
555 const bool droppingFrames = framesDropped > 0.05;
560 actionText = QString(
"%1 (%2)\n"
562 "[PlaybackEngine: %4]")
565 .arg(i18n(
"Enable to preserve playback timing."))
566 .arg(playbackEngineClass);
568 actionText = QString(
"%1 (%2)\n"
572 "[PlaybackEngine: %6]")
575 .arg(i18n(
"Effective FPS:\t%1", QString::number(effectiveFps,
'f', 1)))
576 .arg(i18n(
"Real FPS:\t%1", QString::number(realFps,
'f', 1)))
577 .arg(i18n(
"Frames dropped:\t%1\%", QString::number(framesDropped * 100,
'f', 1)))
578 .arg(playbackEngineClass);
587 action->setToolTip(actionText);
599 m_d->framesView->setActionManager(actionManager);
605 action = actionManager->
actionByName(
"add_blank_frame");
609 action = actionManager->
actionByName(
"add_duplicate_frame");
618 action = actionManager->
createAction(
"toggle_playback");
624 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(stop()));
628 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(previousFrame()));
632 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(nextFrame()));
634 action = actionManager->
createAction(
"previous_keyframe");
636 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(previousKeyframe()));
640 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(nextKeyframe()));
642 action = actionManager->
createAction(
"previous_matching_keyframe");
644 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(previousMatchingKeyframe()));
646 action = actionManager->
createAction(
"next_matching_keyframe");
648 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(nextMatchingKeyframe()));
650 action = actionManager->
createAction(
"previous_unfiltered_keyframe");
652 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(previousUnfilteredKeyframe()));
654 action = actionManager->
createAction(
"next_unfiltered_keyframe");
656 connect(action, SIGNAL(triggered(
bool)),
m_d->playbackEngine, SLOT(nextUnfilteredKeyframe()));
660 connect(action, &KisAction::triggered,
this, [
this](
bool){
662 m_d->playbackEngine->firstFrame();
668 connect(action, &KisAction::triggered,
this, [
this](
bool){
670 m_d->playbackEngine->lastFrame();
676 m_d->titlebar->btnAutoKey->setDefaultAction(action);
677 m_d->titlebar->btnAutoKey->setIconSize(QSize(22, 22));
685 m_d->titlebar->autoKeyBlank->setChecked(!autoKeyModeDuplicate);
686 m_d->titlebar->autoKeyDuplicate->setChecked(autoKeyModeDuplicate);
691 m_d->titlebar->btnDropFrames->setDefaultAction(action);
692 m_d->titlebar->btnDropFrames->setIconSize(QSize(22, 22));
695 connectControl(action, &
m_d->controlsModel,
"dropFramesMode");
701 if (!playbackEngine)
return;
704 connect(
m_d->titlebar->transport, SIGNAL(skipBack()), playbackEngine, SLOT(previousKeyframe()), Qt::UniqueConnection);
705 connect(
m_d->titlebar->transport, SIGNAL(back()), playbackEngine, SLOT(previousFrame()), Qt::UniqueConnection);
706 connect(
m_d->titlebar->transport, SIGNAL(stop()), playbackEngine, SLOT(stop()), Qt::UniqueConnection);
708 connect(
m_d->titlebar->transport, SIGNAL(forward()), playbackEngine, SLOT(nextFrame()), Qt::UniqueConnection);
709 connect(
m_d->titlebar->transport, SIGNAL(skipForward()), playbackEngine, SLOT(nextKeyframe()), Qt::UniqueConnection);
711 connect(
m_d->titlebar->frameRegister, SIGNAL(valueChanged(
int)), playbackEngine, SLOT(seek(
int)), Qt::UniqueConnection);
713 m_d->controlsModel.connectPlaybackEngine(playbackEngine);
715 m_d->playbackEngine = playbackEngine;