diff --git a/libelemental.vcxproj b/libelemental.vcxproj index 5a57a3a..a36155b 100644 --- a/libelemental.vcxproj +++ b/libelemental.vcxproj @@ -42,6 +42,7 @@ + @@ -143,6 +144,7 @@ + @@ -391,4 +393,4 @@ - \ No newline at end of file + diff --git a/libelemental.vcxproj.filters b/libelemental.vcxproj.filters index ded84b8..e8bca73 100644 --- a/libelemental.vcxproj.filters +++ b/libelemental.vcxproj.filters @@ -229,6 +229,9 @@ src\el\elements + + src\el\elements + src\el\elements @@ -560,6 +563,9 @@ src\el\elements + + src\el\elements + src\el\elements @@ -702,4 +708,4 @@ - \ No newline at end of file + diff --git a/src/el/elements.h b/src/el/elements.h index 1be3b5c..9533fc8 100644 --- a/src/el/elements.h +++ b/src/el/elements.h @@ -26,6 +26,7 @@ #include "el/elements/list_box.h" #include "el/elements/menu_window.h" #include "el/elements/message_window.h" +#include "el/elements/modal_window.h" #include "el/elements/mover.h" #include "el/elements/popup_window.h" #include "el/elements/progress_spinner.h" diff --git a/src/el/elements/modal_window.cc b/src/el/elements/modal_window.cc new file mode 100644 index 0000000..4f4f3bf --- /dev/null +++ b/src/el/elements/modal_window.cc @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * Elemental Forms : a lightweight user interface framework * + ****************************************************************************** + * ©2015 Ben Vanik. All rights reserved. Released under the BSD license. * + * Portions ©2011-2015 Emil Segerås: https://github.com/fruxo/turbobadger * + ****************************************************************************** + */ + +#include + +#include "el/animation_manager.h" +#include "el/element_animation.h" +#include "el/elements/dimmer.h" +#include "el/elements/modal_window.h" + +namespace el { +namespace elements { + +int ModalWindow::visible_count_ = 0; + +ModalWindow::ModalWindow(std::function on_close_callback) + : on_close_callback_(on_close_callback) { + ++visible_count_; + set_settings(el::WindowSettings::kTitleBar | + el::WindowSettings::kCloseButton | + el::WindowSettings::kCanActivate); + el::ElementListener::AddGlobalListener(this); +} + +ModalWindow::~ModalWindow() { + --visible_count_; + el::ElementListener::RemoveGlobalListener(this); + if (auto dimmer = dimmer_.get()) { + dimmer->RemoveFromParent(); + delete dimmer; + } +} + +void ModalWindow::Show(el::Element* root_element) { + auto dimmer = new Dimmer(); + root_element->AddChild(dimmer); + dimmer_.reset(dimmer); + + BuildUI(); + + root_element->AddChild(this); + ResizeToFitContent(); + CenterInParent(); +} + +bool ModalWindow::OnEvent(const el::Event& ev) { + if (ev.target->id() == TBIDC("exit_button") && + ev.type == el::EventType::kClick) { + Die(); + return true; + } else if (ev.type == el::EventType::kKeyDown && + ev.special_key == el::SpecialKey::kEsc) { + Die(); + return true; + } + return el::Window::OnEvent(ev); +} + +void ModalWindow::OnDie() { + if (auto dimmer = dimmer_.get()) { + dimmer->Die(); + } + Window::OnDie(); +} + +void ModalWindow::OnRemove() { on_close_callback_(); } + +void ModalWindow::OnElementAdded(Element* parent, Element* element) { + if (element == this) { + // Move in. + auto anim = new RectElementAnimation(this, Rect(0, -50, 0, 0), + RectElementAnimation::Mode::kDeltaOut); + AnimationManager::StartAnimation(anim); + } +} + +bool ModalWindow::OnElementDying(Element* element) { + if (element == this) { + // Move out. + auto anim = new RectElementAnimation(this, Rect(0, 50, 0, 0), + RectElementAnimation::Mode::kDeltaIn); + AnimationManager::StartAnimation(anim, AnimationCurve::kSpeedUp); + return true; + } + return false; +} + +} // namespace elements +} // namespace el diff --git a/src/el/elements/modal_window.h b/src/el/elements/modal_window.h new file mode 100644 index 0000000..75aef1c --- /dev/null +++ b/src/el/elements/modal_window.h @@ -0,0 +1,57 @@ +/** + ****************************************************************************** + * Elemental Forms : a lightweight user interface framework * + ****************************************************************************** + * ©2015 Ben Vanik. All rights reserved. Released under the BSD license. * + * Portions ©2011-2015 Emil Segerås: https://github.com/fruxo/turbobadger * + ****************************************************************************** + */ + +#ifndef EL_ELEMENTS_MODAL_WINDOW_H_ +#define EL_ELEMENTS_MODAL_WINDOW_H_ + +#include + +#include "el/element_listener.h" +#include "el/window.h" + +namespace el { +namespace elements { + +// A window for showing modal messages. +// Events invoked in this window will travel up through the target element. +// When the user click any of its buttons, it will invoke a click event +// (with the window ID), with the clicked buttons id as ref_id. +// Then it will delete itself. +// If the target element is deleted while this window is alive, the window will +// delete itself. +class ModalWindow : public Window, private ElementListener { + public: + TBOBJECT_SUBCLASS(ModalWindow, Window); + + ModalWindow(std::function on_close_callback); + ~ModalWindow() override; + + void Show(el::Element* root_element); + + static bool is_any_visible() { return visible_count_ > 0; } + + protected: + static int visible_count_; + + virtual void BuildUI() = 0; + + bool OnEvent(const el::Event& ev) override; + void OnDie() override; + void OnRemove() override; + void OnElementAdded(Element* parent, Element* element); + bool OnElementDying(Element* element) override; + + std::function on_close_callback_; + WeakElementPointer dimmer_; +}; + +} // namespace elements +} // namespace el + +#endif // EL_ELEMENTS_MODAL_WINDOW_H_