diff --git a/krita/krita.action b/krita/krita.action --- a/krita/krita.action +++ b/krita/krita.action @@ -2024,6 +2024,21 @@ false + + + Stop animation + + Stop animation + Stop animation + 1 + 0 + + false + + + + + addblankframe Create Blank Frame diff --git a/krita/pics/svg/dark_animation_pause.svg b/krita/pics/svg/dark_animation_pause.svg new file mode 100644 --- /dev/null +++ b/krita/pics/svg/dark_animation_pause.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + image/svg+xml + + + 2015 + + + Timothée Giet + + + + + + + + + + + + + + + + + + diff --git a/krita/pics/svg/light_animation_pause.svg b/krita/pics/svg/light_animation_pause.svg new file mode 100644 --- /dev/null +++ b/krita/pics/svg/light_animation_pause.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + image/svg+xml + + + 2015 + + + Timothée Giet + + + + + + + + + + + + + + + + + + diff --git a/krita/pics/svg/svg-icons.qrc b/krita/pics/svg/svg-icons.qrc --- a/krita/pics/svg/svg-icons.qrc +++ b/krita/pics/svg/svg-icons.qrc @@ -92,34 +92,30 @@ dark_color-to-alpha.svg light_preset-switcher.svg dark_preset-switcher.svg - dark_animation_play.svg + dark_animation_pause.svg dark_animation_stop.svg dark_dropframe.svg dark_droppedframes.svg - light_animation_play.svg + light_animation_pause.svg light_animation_stop.svg light_dropframe.svg light_droppedframes.svg - dark_landscape.svg dark_portrait.svg light_landscape.svg light_portrait.svg - dark_interpolation_constant.svg dark_interpolation_linear.svg dark_interpolation_bezier.svg dark_interpolation_sharp.svg dark_interpolation_smooth.svg - light_interpolation_bezier.svg light_interpolation_constant.svg light_interpolation_linear.svg light_interpolation_sharp.svg light_interpolation_smooth.svg - dark_audio-none.svg dark_audio-volume-high.svg dark_audio-volume-mute.svg @@ -136,7 +132,6 @@ light_zoom-fit.svg light_zoom-horizontal.svg light_zoom-vertical.svg - dark_showColoring.svg dark_showMarks.svg dark_showColoringOff.svg @@ -147,6 +142,5 @@ light_showColoringOff.svg light_showMarksOff.svg light_updateColorize.svg - diff --git a/libs/image/kis_image_animation_interface.cpp b/libs/image/kis_image_animation_interface.cpp --- a/libs/image/kis_image_animation_interface.cpp +++ b/libs/image/kis_image_animation_interface.cpp @@ -68,6 +68,7 @@ KisTimeRange fullClipRange; KisTimeRange playbackRange; + int framerate; int cachedLastFrameValue; QString audioChannelFileName; diff --git a/libs/ui/canvas/kis_animation_player.h b/libs/ui/canvas/kis_animation_player.h --- a/libs/ui/canvas/kis_animation_player.h +++ b/libs/ui/canvas/kis_animation_player.h @@ -37,6 +37,7 @@ void play(); void stop(); + void pause(); void displayFrame(int time); bool isPlaying(); diff --git a/libs/ui/canvas/kis_animation_player.cpp b/libs/ui/canvas/kis_animation_player.cpp --- a/libs/ui/canvas/kis_animation_player.cpp +++ b/libs/ui/canvas/kis_animation_player.cpp @@ -75,6 +75,7 @@ bool useFastFrameUpload; bool playing; + bool isPaused; QTimer *timer; @@ -373,8 +374,18 @@ m_d->playing = true; + KisImageAnimationInterface *animation = m_d->canvas->image()->animationInterface(); + slotUpdatePlaybackTimer(); - m_d->expectedFrame = m_d->firstFrame; + + + if (m_d->isPaused) { + m_d->expectedFrame = animation->currentUITime(); + } else { + m_d->expectedFrame = animation->playbackRange().start(); + } + + m_d->lastPaintedFrame = -1; connectCancelSignals(); @@ -404,7 +415,30 @@ if (animation->currentUITime() == initialFrame) { canvas->refetchDataFromImage(); } else { - animation->switchCurrentTimeAsync(initialFrame); + + // if there is no playback range... + // pause will move the current time to the current UIPosition + // stop will move the current time to the initial frame (last starting frame) + bool hasNoFrameRangeSelected = animation->playbackRange().start() == animation->fullClipRange().start() && + animation->playbackRange().end() == animation->fullClipRange().end(); + + + if (hasNoFrameRangeSelected) { + // if we don't have a special frame selection, pausing and stopping updates the current position + if (!isPaused) { + animation->switchCurrentTimeAsync(animation->fullClipRange().start()); + } else { + animation->switchCurrentTimeAsync(animation->currentUITime()); + } + + } else { + // we have a frame selection, so we need to stay in the selection + if (!isPaused) { // stop at the playback end. using start() messes up selection, so don't use + animation->switchCurrentTimeAsync(animation->playbackRange().end()); + } + } + + } } @@ -413,11 +447,19 @@ void KisAnimationPlayer::stop() { + m_d->isPaused = false; + m_d->stopImpl(true); +} + +void KisAnimationPlayer::pause() +{ + m_d->isPaused = true; m_d->stopImpl(true); } void KisAnimationPlayer::forcedStopOnExit() { + m_d->isPaused = false; m_d->stopImpl(false); } diff --git a/plugins/dockers/animation/animation_docker.h b/plugins/dockers/animation/animation_docker.h --- a/plugins/dockers/animation/animation_docker.h +++ b/plugins/dockers/animation/animation_docker.h @@ -53,6 +53,8 @@ void slotPlayPause(); + void slotStop(); + void slotAddOpacityKeyframe(); void slotDeleteOpacityKeyframe(); @@ -96,6 +98,7 @@ KisAction *m_lastFrameAction; KisAction *m_playPauseAction; + KisAction *m_stopAction; KisAction *m_lazyFrameAction; KisAction *m_dropFramesAction; diff --git a/plugins/dockers/animation/animation_docker.cpp b/plugins/dockers/animation/animation_docker.cpp --- a/plugins/dockers/animation/animation_docker.cpp +++ b/plugins/dockers/animation/animation_docker.cpp @@ -330,12 +330,14 @@ } + + void AnimationDocker::slotPlayPause() { if (!m_canvas) return; if (m_canvas->animationPlayer()->isPlaying()) { - m_canvas->animationPlayer()->stop(); + m_canvas->animationPlayer()->pause(); } else { m_canvas->animationPlayer()->play(); } @@ -343,12 +345,20 @@ updatePlayPauseIcon(); } + +void AnimationDocker::slotStop() +{ + if (!m_canvas) return; + m_canvas->animationPlayer()->stop(); +} + + void AnimationDocker::updatePlayPauseIcon() { bool isPlaying = m_canvas && m_canvas->animationPlayer() && m_canvas->animationPlayer()->isPlaying(); m_playPauseAction->setIcon(isPlaying ? - KisIconUtils::loadIcon("animation_stop") : + KisIconUtils::loadIcon("animation_pause") : KisIconUtils::loadIcon("animation_play")); } @@ -425,6 +435,8 @@ m_firstFrameAction->setIcon(KisIconUtils::loadIcon("firstframe")); m_lastFrameAction->setIcon(KisIconUtils::loadIcon("lastframe")); + m_stopAction->setIcon(KisIconUtils::loadIcon("animation_stop")); + updatePlayPauseIcon(); updateLazyFrameIcon(); updateDropFramesIcon(); @@ -440,6 +452,7 @@ m_animationWidget->btnPreviousFrame->setIconSize(QSize(22, 22)); m_animationWidget->btnPlay->setIconSize(QSize(22, 22)); + m_animationWidget->btnStop->setIconSize(QSize(22, 22)); m_animationWidget->btnNextFrame->setIconSize(QSize(22, 22)); m_animationWidget->btnAddKeyframe->setIconSize(QSize(22, 22)); m_animationWidget->btnAddDuplicateFrame->setIconSize(QSize(22, 22)); @@ -560,10 +573,16 @@ m_animationWidget->btnLastFrame->setDefaultAction(m_lastFrameAction); - m_playPauseAction = new KisAction(i18n("Play / Stop"), m_animationWidget->btnPlay); + m_playPauseAction = new KisAction(i18n("Play / Pause"), m_animationWidget->btnPlay); m_playPauseAction->setActivationFlags(KisAction::ACTIVE_IMAGE); m_animationWidget->btnPlay->setDefaultAction(m_playPauseAction); + + m_stopAction = new KisAction(i18n("Stop"), m_animationWidget->btnStop); + m_stopAction->setActivationFlags(KisAction::ACTIVE_IMAGE); + m_animationWidget->btnStop->setDefaultAction(m_stopAction); + + KisAction *action = 0; action = m_actionManager->createAction("add_blank_frame"); @@ -624,6 +643,7 @@ m_actionManager->addAction("drop_frames", m_dropFramesAction); m_actionManager->addAction("toggle_playback", m_playPauseAction); + m_actionManager->addAction("stop_playback", m_stopAction); QFont font; font.setPointSize(1.7 * font.pointSize()); @@ -641,6 +661,8 @@ connect(m_playPauseAction, SIGNAL(triggered()), this, SLOT(slotPlayPause())); + connect(m_stopAction, SIGNAL(triggered()), this, SLOT(slotStop())); + connect(m_lazyFrameAction, SIGNAL(toggled(bool)), this, SLOT(slotLazyFrameChanged(bool))); connect(m_dropFramesAction, SIGNAL(toggled(bool)), this, SLOT(slotDropFramesChanged(bool))); diff --git a/plugins/dockers/animation/wdg_animation.ui b/plugins/dockers/animation/wdg_animation.ui --- a/plugins/dockers/animation/wdg_animation.ui +++ b/plugins/dockers/animation/wdg_animation.ui @@ -6,26 +6,11 @@ 0 0 - 280 - 160 + 279 + 221 - - 1 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -290,6 +275,22 @@ + + + + 0 + 0 + + + + ... + + + true + + + +