diff options
Diffstat (limited to 'CruUI/ui')
-rw-r--r-- | CruUI/ui/animations/animation.cpp | 227 | ||||
-rw-r--r-- | CruUI/ui/animations/animation.h | 176 | ||||
-rw-r--r-- | CruUI/ui/control.cpp | 8 | ||||
-rw-r--r-- | CruUI/ui/control.h | 6 | ||||
-rw-r--r-- | CruUI/ui/controls/text_block.cpp | 15 | ||||
-rw-r--r-- | CruUI/ui/controls/text_block.h | 17 | ||||
-rw-r--r-- | CruUI/ui/controls/toggle_button.cpp | 13 | ||||
-rw-r--r-- | CruUI/ui/window.h | 1 |
8 files changed, 266 insertions, 197 deletions
diff --git a/CruUI/ui/animations/animation.cpp b/CruUI/ui/animations/animation.cpp index 26b7d5fc..9d05860a 100644 --- a/CruUI/ui/animations/animation.cpp +++ b/CruUI/ui/animations/animation.cpp @@ -5,99 +5,186 @@ namespace cru::ui::animations { - constexpr int frame_rate = 60; - constexpr double frame_step_time = 1.0 / frame_rate; - - AnimationManager::AnimationManager() - : timer_action_(new Action<>([this]() + namespace details { - for (auto& animation : animations_) + class AnimationDelegateImpl; + constexpr double frame_rate = 60; + constexpr AnimationTimeUnit frame_step_time = AnimationTimeUnit(1) / frame_rate; + + + class AnimationDelegateImpl : public virtual IAnimationDelegate { - if (animation.second->Step(frame_step_time)) - InvokeLater([=] + public: + explicit AnimationDelegateImpl(String tag) + : tag_(std::move(tag)) + { + + } + AnimationDelegateImpl(const AnimationDelegateImpl& other) = delete; + AnimationDelegateImpl(AnimationDelegateImpl&& other) = delete; + AnimationDelegateImpl& operator=(const AnimationDelegateImpl& other) = delete; + AnimationDelegateImpl& operator=(AnimationDelegateImpl&& other) = delete; + ~AnimationDelegateImpl() override = default; + + void Cancel() override + { + AnimationManager::GetInstance()->RemoveAnimation(tag_); + } + + private: + String tag_; + }; + + + class Animation : public Object + { + public: + Animation( + String tag, + AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, + Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, + Vector<ActionPtr> cancel_handlers, + AnimationDelegatePtr delegate + ); + Animation(const Animation& other) = delete; + Animation(Animation&& other) = delete; + Animation& operator=(const Animation& other) = delete; + Animation& operator=(Animation&& other) = delete; + ~Animation() override; + + + // If finish or invalid, return false. + bool Step(AnimationTimeUnit time); + + String GetTag() const { - RemoveAnimation(animation.second); //TODO!!! - }); + return tag_; + } + + private: + const String tag_; + const AnimationTimeUnit duration_; + Vector<AnimationStepHandlerPtr> step_handlers_; + Vector<AnimationStartHandlerPtr> start_handlers_; + Vector<ActionPtr> finish_handlers_; + Vector<ActionPtr> cancel_handlers_; + AnimationDelegatePtr delegate_; + + AnimationTimeUnit current_time_ = AnimationTimeUnit::zero(); + }; + + AnimationManager::AnimationManager() + : timer_action_(CreateActionPtr([this]() + { + auto i = animations_.cbegin(); + while (i != animations_.cend()) + { + auto current_i = i++; + if (current_i->second->Step(frame_step_time)) + animations_.erase(current_i); + } + + if (animations_.empty()) + KillTimer(); + })) + { + } - })) - { - } + AnimationManager::~AnimationManager() + { + KillTimer(); + } - AnimationManager::~AnimationManager() - { - for (auto& animation : animations_) - delete animation.second; + AnimationDelegatePtr AnimationManager::CreateAnimation(String tag, AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, Vector<ActionPtr> cancel_handlers) + { + if (animations_.empty()) + SetTimer(); - if (timer_) - timer_->Cancel(); - } + auto delegate = std::make_shared<AnimationDelegateImpl>(tag); - void AnimationManager::AddAnimation(Animation* animation) - { - if (animations_.empty()) - timer_ = SetInterval(frame_step_time, timer_action_); + animations_[tag] = std::make_unique<Animation>(tag, duration, std::move(step_handlers), std::move(start_handlers), std::move(finish_handlers), std::move(cancel_handlers), delegate); - const auto find_result = animations_.find(animation->GetTag()); - if (find_result != animations_.cend()) - find_result->second->Cancel(); - animations_.insert_or_assign(animation->GetTag(), animation); - } + return delegate; + } - void AnimationManager::RemoveAnimation(Animation* animation) - { - const auto find_result = animations_.find(animation->GetTag()); - if (find_result != animations_.cend()) + void AnimationManager::RemoveAnimation(const String& tag) { - delete find_result->second; - animations_.erase(find_result); + const auto find_result = animations_.find(tag); + if (find_result != animations_.cend()) + animations_.erase(find_result); + + if (animations_.empty()) + KillTimer(); } - if (animations_.empty()) + void AnimationManager::SetTimer() { - assert(timer_); - timer_->Cancel(); - timer_ = nullptr; + if (timer_ == nullptr) + timer_ = SetInterval(std::chrono::duration_cast<std::chrono::milliseconds>(frame_step_time), timer_action_); } - } - Animation::Animation(String tag, const double duration, - const Vector<std::shared_ptr<Action<Animation*, double>>>& step_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& start_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& finish_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& cancel_handlers - ) : tag_(std::move(tag)), duration_(duration), step_handlers_(step_handlers), - start_handlers_(start_handlers), finish_handlers_(finish_handlers), cancel_handlers_(cancel_handlers) - { - AnimationManager::GetInstance()->AddAnimation(this); - } + void AnimationManager::KillTimer() + { + if (timer_ != nullptr) + { + timer_->Cancel(); + timer_ = nullptr; + } + } - bool Animation::Step(const double time) - { - current_time_ += time; - if (current_time_ > duration_) + Animation::Animation( + String tag, + AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, + Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, + Vector<ActionPtr> cancel_handlers, + AnimationDelegatePtr delegate + ) : tag_(std::move(tag)), duration_(duration), + step_handlers_(std::move(step_handlers)), + start_handlers_(std::move(start_handlers)), + finish_handlers_(std::move(finish_handlers)), + cancel_handlers_(std::move(cancel_handlers)), + delegate_(std::move(delegate)) + { + + } + + Animation::~Animation() { - for (auto& handler : step_handlers_) - (*handler)(this, 1); - for (auto& handler : finish_handlers_) - (*handler)(this); - return true; + if (current_time_ < duration_) + for (auto& handler : cancel_handlers_) + (*handler)(); } - else + + bool Animation::Step(const AnimationTimeUnit time) { - for (auto& handler : step_handlers_) - (*handler)(this, current_time_ / duration_); - return false; + current_time_ += time; + if (current_time_ > duration_) + { + for (auto& handler : step_handlers_) + (*handler)(delegate_, 1); + for (auto& handler : finish_handlers_) + (*handler)(); + return true; + } + else + { + for (auto& handler : step_handlers_) + (*handler)(delegate_, current_time_ / duration_); + return false; + } } + } - void Animation::Cancel() + AnimationDelegatePtr AnimationBuilder::Start() const { - for (auto& handler : cancel_handlers_) - (*handler)(this); - InvokeLater([this] - { - AnimationManager::GetInstance()->RemoveAnimation(this); //TODO!!! - }); + return details::AnimationManager::GetInstance()->CreateAnimation(tag, duration, step_handlers_, start_handlers_, finish_handlers_, cancel_handlers_); } } diff --git a/CruUI/ui/animations/animation.h b/CruUI/ui/animations/animation.h index fb6ba93e..69b08b0c 100644 --- a/CruUI/ui/animations/animation.h +++ b/CruUI/ui/animations/animation.h @@ -1,131 +1,107 @@ #pragma once -#include <map> +#include <unordered_map> #include "base.h" #include "application.h" #include "timer.h" -#include "builder.h" namespace cru::ui::animations { - class Animation; + using AnimationTimeUnit = FloatSecond; + + using IAnimationDelegate = ICancelable; + using AnimationDelegatePtr = CancelablePtr; - class AnimationManager : public Object - { - public: - static AnimationManager* GetInstance() - { - return Application::GetInstance()->GetAnimationManager(); - } - - public: - AnimationManager(); - AnimationManager(const AnimationManager& other) = delete; - AnimationManager(AnimationManager&& other) = delete; - AnimationManager& operator=(const AnimationManager& other) = delete; - AnimationManager& operator=(AnimationManager&& other) = delete; - ~AnimationManager() override; + using AnimationStepHandlerPtr = FunctionPtr<void(AnimationDelegatePtr, double)>; + using AnimationStartHandlerPtr = FunctionPtr<void(AnimationDelegatePtr)>; - void AddAnimation(Animation* animation); - void RemoveAnimation(Animation* animation); - private: - std::map<String, Animation*> animations_; - std::shared_ptr<ITimerTask> timer_; - std::shared_ptr<Action<>> timer_action_; - }; - - class Animation : public Object + namespace details { - friend class AnimationManager; - protected: - Animation( - String tag, - double duration, - const Vector<std::shared_ptr<Action<Animation*, double>>>& step_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& start_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& finish_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& cancel_handlers - ); + class Animation; + using AnimationPtr = std::unique_ptr<Animation>; - public: - Animation(const Animation& other) = delete; - Animation(Animation&& other) = delete; - Animation& operator=(const Animation& other) = delete; - Animation& operator=(Animation&& other) = delete; - ~Animation() override = default; // The animation will never destroy by users. - - bool Step(double time); - void Cancel(); - String GetTag() const + class AnimationManager : public Object { - return tag_; - } + public: + static AnimationManager* GetInstance() + { + return Application::GetInstance()->GetAnimationManager(); + } - private: - const String tag_; - const double duration_; - Vector<std::shared_ptr<Action<Animation*, double>>> step_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> start_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> finish_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> cancel_handlers_; + public: + AnimationManager(); + AnimationManager(const AnimationManager& other) = delete; + AnimationManager(AnimationManager&& other) = delete; + AnimationManager& operator=(const AnimationManager& other) = delete; + AnimationManager& operator=(AnimationManager&& other) = delete; + ~AnimationManager() override; + + AnimationDelegatePtr CreateAnimation( + String tag, + AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, + Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, + Vector<ActionPtr> cancel_handlers + ); + void RemoveAnimation(const String& tag); - double current_time_ = 0; + private: + void SetTimer(); + void KillTimer(); + private: + std::unordered_map<String, AnimationPtr> animations_; + std::shared_ptr<ICancelable> timer_; + ActionPtr timer_action_; + }; + } + + class AnimationBuilder : public Object + { public: - class Builder : public OneTimeBuilder<Animation> + AnimationBuilder(String tag, const AnimationTimeUnit duration) + : tag(std::move(tag)), duration(duration) { - public: - Builder(String tag, const double duration) - : tag(std::move(tag)), duration(duration) - { - } + } - String tag; - double duration; + String tag; + AnimationTimeUnit duration; - Builder& AddStepHandler(Action<Animation*, double>&& handler) - { - if (IsValid()) - step_handlers_.push_back(std::make_shared<Action<Animation*, double>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddStepHandler(AnimationStepHandlerPtr handler) + { + step_handlers_.push_back(std::move(handler)); + return *this; + } - Builder& AddStartHandler(Action<Animation*>&& handler) - { - if (IsValid()) - start_handlers_.push_back(std::make_shared<Action<Animation*>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddStartHandler(AnimationStartHandlerPtr handler) + { + start_handlers_.push_back(std::move(handler)); + return *this; + } - Builder& AddFinishHandler(Action<Animation*>&& handler) - { - if (IsValid()) - finish_handlers_.push_back(std::make_shared<Action<Animation*>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddFinishHandler(ActionPtr handler) + { + finish_handlers_.push_back(std::move(handler)); + return *this; + } - Builder& AddCancelHandler(Action<Animation*>&& handler) - { - if (IsValid()) - cancel_handlers_.push_back(std::make_shared<Action<Animation*>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddCancelHandler(ActionPtr handler) + { + cancel_handlers_.push_back(std::move(handler)); + return *this; + } - protected: - Animation* OnCreate() override - { - return new Animation(std::move(tag), duration, step_handlers_, start_handlers_, finish_handlers_, cancel_handlers_); - } + AnimationDelegatePtr Start() const; - private: - Vector<std::shared_ptr<Action<Animation*, double>>> step_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> start_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> finish_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> cancel_handlers_; - }; + private: + Vector<AnimationStepHandlerPtr> step_handlers_; + Vector<AnimationStartHandlerPtr> start_handlers_; + Vector<ActionPtr> finish_handlers_; + Vector<ActionPtr> cancel_handlers_; }; } diff --git a/CruUI/ui/control.cpp b/CruUI/ui/control.cpp index d2864fce..1fa7a08d 100644 --- a/CruUI/ui/control.cpp +++ b/CruUI/ui/control.cpp @@ -46,14 +46,14 @@ namespace cru { }); } - void Control::ForeachChild(Action<Control*>&& predicate) const + void Control::ForeachChild(Function<void(Control*)>&& predicate) const { if (is_container_) for (const auto child : children_) predicate(child); } - void Control::ForeachChild(FlowControlAction<Control*>&& predicate) const + void Control::ForeachChild(Function<FlowControl(Control*)>&& predicate) const { if (is_container_) for (const auto child : children_) @@ -141,7 +141,7 @@ namespace cru { return ancestor; } - void TraverseDescendantsInternal(Control* control, Action<Control*>& predicate) + void TraverseDescendantsInternal(Control* control, Function<void(Control*)>& predicate) { predicate(control); control->ForeachChild([&predicate](Control* c) { @@ -149,7 +149,7 @@ namespace cru { }); } - void Control::TraverseDescendants(Action<Control*>&& predicate) + void Control::TraverseDescendants(Function<void(Control*)>&& predicate) { if (is_container_) TraverseDescendantsInternal(this, predicate); diff --git a/CruUI/ui/control.h b/CruUI/ui/control.h index ca2dfb84..daae1787 100644 --- a/CruUI/ui/control.h +++ b/CruUI/ui/control.h @@ -60,8 +60,8 @@ namespace cru } //Traverse the children - void ForeachChild(Action<Control*>&& predicate) const; - void ForeachChild(FlowControlAction<Control*>&& predicate) const; + void ForeachChild(Function<void(Control*)>&& predicate) const; + void ForeachChild(Function<FlowControl(Control*)>&& predicate) const; //Return a vector of all children. This function will create a //temporary copy of vector of children. If you just want to @@ -93,7 +93,7 @@ namespace cru } //Traverse the tree rooted the control including itself. - void TraverseDescendants(Action<Control*>&& predicate); + void TraverseDescendants(Function<void(Control*)>&& predicate); //*************** region: position and size *************** // Position and size part must be isolated from layout part. diff --git a/CruUI/ui/controls/text_block.cpp b/CruUI/ui/controls/text_block.cpp index beb799d3..294c456b 100644 --- a/CruUI/ui/controls/text_block.cpp +++ b/CruUI/ui/controls/text_block.cpp @@ -53,6 +53,19 @@ namespace cru Repaint(); } + void TextBlock::AddTextLayoutHandler(TextLayoutHandlerPtr handler) + { + text_layout_handlers_.push_back(std::move(handler)); + } + + void TextBlock::RemoveTextLayoutHandler(const TextLayoutHandlerPtr& handler) + { + const auto find_result = std::find(text_layout_handlers_.cbegin(), text_layout_handlers_.cend(), + handler); + if (find_result != text_layout_handlers_.cend()) + text_layout_handlers_.erase(find_result); + } + void TextBlock::OnSizeChangedCore(events::SizeChangedEventArgs& args) { Control::OnSizeChangedCore(args); @@ -263,7 +276,7 @@ namespace cru &text_layout_ )); - std::for_each(text_layout_handlers_.cbegin(), text_layout_handlers_.cend(), [this](const std::shared_ptr<TextLayoutHandler>& handler) + std::for_each(text_layout_handlers_.cbegin(), text_layout_handlers_.cend(), [this](const TextLayoutHandlerPtr& handler) { (*handler)(text_layout_); }); diff --git a/CruUI/ui/controls/text_block.h b/CruUI/ui/controls/text_block.h index db22e3c7..3fed2283 100644 --- a/CruUI/ui/controls/text_block.h +++ b/CruUI/ui/controls/text_block.h @@ -39,7 +39,7 @@ namespace cru class TextBlock : public Control { public: - using TextLayoutHandler = Action<Microsoft::WRL::ComPtr<IDWriteTextLayout>>; + using TextLayoutHandlerPtr = FunctionPtr<void(Microsoft::WRL::ComPtr<IDWriteTextLayout>)>; static TextBlock* Create( const String& text = L"", @@ -85,16 +85,9 @@ namespace cru void SetTextFormat(const Microsoft::WRL::ComPtr<IDWriteTextFormat>& text_format); - void AddTextLayoutHandler(std::shared_ptr<TextLayoutHandler> handler) - { - text_layout_handlers_.push_back(std::move(handler)); - } - void RemoveTextLayoutHandler(const std::shared_ptr<TextLayoutHandler>& handler) - { - const auto find_result = std::find(text_layout_handlers_.cbegin(), text_layout_handlers_.cend(), handler); - if (find_result != text_layout_handlers_.cend()) - text_layout_handlers_.erase(find_result); - } + void AddTextLayoutHandler(TextLayoutHandlerPtr handler); + + void RemoveTextLayoutHandler(const TextLayoutHandlerPtr& handler); protected: void OnSizeChangedCore(events::SizeChangedEventArgs& args) override final; @@ -122,7 +115,7 @@ namespace cru Microsoft::WRL::ComPtr<IDWriteTextFormat> text_format_; Microsoft::WRL::ComPtr<IDWriteTextLayout> text_layout_; - Vector<std::shared_ptr<TextLayoutHandler>> text_layout_handlers_; + Vector<TextLayoutHandlerPtr> text_layout_handlers_; bool is_selecting_ = false; unsigned mouse_down_position_ = 0; diff --git a/CruUI/ui/controls/toggle_button.cpp b/CruUI/ui/controls/toggle_button.cpp index a22cfda8..033fa9fc 100644 --- a/CruUI/ui/controls/toggle_button.cpp +++ b/CruUI/ui/controls/toggle_button.cpp @@ -8,7 +8,7 @@ namespace cru::ui::controls { using graph::CreateSolidBrush; - using animations::Animation; + using animations::AnimationBuilder; // ui length parameters of toggle button. constexpr float half_height = 15; @@ -56,15 +56,16 @@ namespace cru::ui::controls const auto previous_position = current_circle_position_; const auto delta = destination_x - current_circle_position_; - constexpr double total_time = 0.5; + constexpr auto total_time = FloatSecond(0.2); - const auto time = total_time * std::abs(delta) / (inner_circle_x * 2); + const auto time = total_time * (std::abs(delta) / (inner_circle_x * 2)); - Animation::Builder(fmt::format(L"ToggleButton {}", reinterpret_cast<size_t>(this)), time).AddStepHandler([=](Animation*, const float percentage) + AnimationBuilder(fmt::format(L"ToggleButton {}", reinterpret_cast<size_t>(this)), time) + .AddStepHandler(CreatePtr<animations::AnimationStepHandlerPtr>([=](animations::AnimationDelegatePtr, const double percentage) { - current_circle_position_ = previous_position + delta * percentage; + current_circle_position_ = static_cast<float>(previous_position + delta * percentage); Repaint(); - }).Create(); + })).Start(); OnToggleInternal(state); Repaint(); diff --git a/CruUI/ui/window.h b/CruUI/ui/window.h index 790e3c32..5addf963 100644 --- a/CruUI/ui/window.h +++ b/CruUI/ui/window.h @@ -1,7 +1,6 @@ #pragma once #include "system_headers.h" -#include <set> #include <map> #include <list> #include <memory> |