From ba1de683fae11b8f65e6c63f63b8d5363c7ef6a6 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 27 May 2023 01:17:19 -0500 Subject: [PATCH] Timeline pause --- scwx-qt/source/scwx/qt/main/main_window.cpp | 11 ++-- .../scwx/qt/manager/timeline_manager.cpp | 52 +++++++++++++++---- .../scwx/qt/manager/timeline_manager.hpp | 4 +- scwx-qt/source/scwx/qt/types/map_types.hpp | 6 +++ .../scwx/qt/ui/animation_dock_widget.cpp | 38 +++++++------- .../scwx/qt/ui/animation_dock_widget.hpp | 4 +- 6 files changed, 79 insertions(+), 36 deletions(-) diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index 1791e15e..43ef66af 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -682,11 +682,7 @@ void MainWindowImpl::ConnectAnimationSignals() connect(animationDockWidget_, &ui::AnimationDockWidget::AnimationPlaySelected, timelineManager_.get(), - &manager::TimelineManager::AnimationPlay); - connect(animationDockWidget_, - &ui::AnimationDockWidget::AnimationPauseSelected, - timelineManager_.get(), - &manager::TimelineManager::AnimationPause); + &manager::TimelineManager::AnimationPlayPause); connect(animationDockWidget_, &ui::AnimationDockWidget::AnimationStepNextSelected, timelineManager_.get(), @@ -705,6 +701,11 @@ void MainWindowImpl::ConnectAnimationSignals() map->SelectTime(dateTime); } }); + + connect(timelineManager_.get(), + &manager::TimelineManager::AnimationStateUpdated, + animationDockWidget_, + &ui::AnimationDockWidget::UpdateAnimationState); } void MainWindowImpl::ConnectOtherSignals() diff --git a/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp b/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp index 534daed7..d2955f33 100644 --- a/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp @@ -42,6 +42,7 @@ public: TimelineManager* self_; + void Pause(); void Play(); void SelectTime(std::chrono::system_clock::time_point selectedTime = {}); void Step(Direction direction); @@ -55,6 +56,7 @@ public: std::chrono::minutes loopTime_ {30}; double loopSpeed_ {1.0}; + types::AnimationState animationState_ {types::AnimationState::Pause}; boost::asio::steady_timer animationTimer_ {scwx::util::io_context()}; std::mutex animationTimerMutex_ {}; @@ -145,6 +147,8 @@ void TimelineManager::AnimationStepBegin() { logger_->debug("AnimationStepBegin"); + p->Pause(); + if (p->viewType_ == types::MapTime::Live || p->pinnedTime_ == std::chrono::system_clock::time_point {}) { @@ -162,25 +166,29 @@ void TimelineManager::AnimationStepBack() { logger_->debug("AnimationStepBack"); + p->Pause(); p->Step(Direction::Back); } -void TimelineManager::AnimationPlay() +void TimelineManager::AnimationPlayPause() { - logger_->debug("AnimationPlay"); - - p->Play(); -} - -void TimelineManager::AnimationPause() -{ - logger_->debug("AnimationPause"); + if (p->animationState_ == types::AnimationState::Pause) + { + logger_->debug("AnimationPlay"); + p->Play(); + } + else + { + logger_->debug("AnimationPause"); + p->Pause(); + } } void TimelineManager::AnimationStepNext() { logger_->debug("AnimationStepNext"); + p->Pause(); p->Step(Direction::Next); } @@ -188,6 +196,8 @@ void TimelineManager::AnimationStepEnd() { logger_->debug("AnimationStepEnd"); + p->Pause(); + if (p->viewType_ == types::MapTime::Live) { // If the selected view type is live, select the current products @@ -200,10 +210,29 @@ void TimelineManager::AnimationStepEnd() } } +void TimelineManager::Impl::Pause() +{ + // Cancel animation + std::unique_lock animationTimerLock {animationTimerMutex_}; + animationTimer_.cancel(); + + if (animationState_ != types::AnimationState::Pause) + { + animationState_ = types::AnimationState::Pause; + emit self_->AnimationStateUpdated(animationState_); + } +} + void TimelineManager::Impl::Play() { using namespace std::chrono_literals; + if (animationState_ != types::AnimationState::Play) + { + animationState_ = types::AnimationState::Play; + emit self_->AnimationStateUpdated(animationState_); + } + { std::unique_lock animationTimerLock {animationTimerMutex_}; animationTimer_.cancel(); @@ -260,7 +289,10 @@ void TimelineManager::Impl::Play() { if (e == boost::system::errc::success) { - Play(); + if (animationState_ == types::AnimationState::Play) + { + Play(); + } } else if (e == boost::asio::error::operation_aborted) { diff --git a/scwx-qt/source/scwx/qt/manager/timeline_manager.hpp b/scwx-qt/source/scwx/qt/manager/timeline_manager.hpp index 3d6e0cc9..2f3a3fd9 100644 --- a/scwx-qt/source/scwx/qt/manager/timeline_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/timeline_manager.hpp @@ -35,8 +35,7 @@ public slots: void AnimationStepBegin(); void AnimationStepBack(); - void AnimationPlay(); - void AnimationPause(); + void AnimationPlayPause(); void AnimationStepNext(); void AnimationStepEnd(); @@ -44,6 +43,7 @@ signals: void SelectedTimeUpdated(std::chrono::system_clock::time_point dateTime); void VolumeTimeUpdated(std::chrono::system_clock::time_point dateTime); + void AnimationStateUpdated(types::AnimationState state); void ViewTypeUpdated(types::MapTime viewType); private: diff --git a/scwx-qt/source/scwx/qt/types/map_types.hpp b/scwx-qt/source/scwx/qt/types/map_types.hpp index a23932ee..d2c804a2 100644 --- a/scwx-qt/source/scwx/qt/types/map_types.hpp +++ b/scwx-qt/source/scwx/qt/types/map_types.hpp @@ -9,6 +9,12 @@ namespace qt namespace types { +enum class AnimationState +{ + Play, + Pause +}; + enum class MapTime { Live, diff --git a/scwx-qt/source/scwx/qt/ui/animation_dock_widget.cpp b/scwx-qt/source/scwx/qt/ui/animation_dock_widget.cpp index f9bcbd58..49035d12 100644 --- a/scwx-qt/source/scwx/qt/ui/animation_dock_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/animation_dock_widget.cpp @@ -16,21 +16,18 @@ namespace ui static const std::string logPrefix_ = "scwx::qt::ui::animation_dock_widget"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); -enum class AnimationState -{ - Play, - Pause -}; - class AnimationDockWidgetImpl { public: explicit AnimationDockWidgetImpl(AnimationDockWidget* self) : self_ {self} {} ~AnimationDockWidgetImpl() = default; + const QIcon kPauseIcon_ {":/res/icons/font-awesome-6/pause-solid.svg"}; + const QIcon kPlayIcon_ {":/res/icons/font-awesome-6/play-solid.svg"}; + AnimationDockWidget* self_; - AnimationState animationState_ {AnimationState::Pause}; + types::AnimationState animationState_ {types::AnimationState::Pause}; std::chrono::sys_days selectedDate_ {}; std::chrono::seconds selectedTime_ {}; @@ -171,17 +168,7 @@ void AnimationDockWidgetImpl::ConnectSignals() QObject::connect(self_->ui->playButton, &QAbstractButton::clicked, self_, - [this]() - { - if (animationState_ == AnimationState::Pause) - { - emit self_->AnimationPlaySelected(); - } - else - { - emit self_->AnimationPauseSelected(); - } - }); + [this]() { emit self_->AnimationPlaySelected(); }); QObject::connect(self_->ui->stepNextButton, &QAbstractButton::clicked, self_, @@ -192,6 +179,21 @@ void AnimationDockWidgetImpl::ConnectSignals() [this]() { emit self_->AnimationStepEndSelected(); }); } +void AnimationDockWidget::UpdateAnimationState(types::AnimationState state) +{ + // Update icon to opposite of state + switch (state) + { + case types::AnimationState::Pause: + ui->playButton->setIcon(p->kPlayIcon_); + break; + + case types::AnimationState::Play: + ui->playButton->setIcon(p->kPauseIcon_); + break; + } +} + } // namespace ui } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/animation_dock_widget.hpp b/scwx-qt/source/scwx/qt/ui/animation_dock_widget.hpp index a054e592..a80d8912 100644 --- a/scwx-qt/source/scwx/qt/ui/animation_dock_widget.hpp +++ b/scwx-qt/source/scwx/qt/ui/animation_dock_widget.hpp @@ -28,6 +28,9 @@ public: explicit AnimationDockWidget(QWidget* parent = nullptr); ~AnimationDockWidget(); +public slots: + void UpdateAnimationState(types::AnimationState state); + signals: void ViewTypeChanged(types::MapTime viewType); void DateTimeChanged(std::chrono::system_clock::time_point dateTime); @@ -37,7 +40,6 @@ signals: void AnimationStepBeginSelected(); void AnimationStepBackSelected(); - void AnimationPauseSelected(); void AnimationPlaySelected(); void AnimationStepNextSelected(); void AnimationStepEndSelected();