diff options
Diffstat (limited to 'src/ui/host/RoutedEventDispatch.h')
| -rw-r--r-- | src/ui/host/RoutedEventDispatch.h | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/src/ui/host/RoutedEventDispatch.h b/src/ui/host/RoutedEventDispatch.h deleted file mode 100644 index 0729d176..00000000 --- a/src/ui/host/RoutedEventDispatch.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once -#include "cru/base/SelfResolvable.h" -#include "cru/base/log/Logger.h" -#include "cru/ui/DebugFlags.h" -#include "cru/ui/controls/Control.h" -#include "cru/ui/host/WindowHost.h" - -#include <vector> - -namespace cru::ui::host { -// Dispatch the event. -// -// This will raise routed event of the control and its parent and parent's -// parent ... (until "last_receiver" if it's not nullptr) with appropriate args. -// -// First tunnel from top to bottom possibly stopped by "handled" flag in -// EventArgs. Second bubble from bottom to top possibly stopped by "handled" -// flag in EventArgs. Last direct to each control. -// -// Args is of type "EventArgs". The first init argument is "sender", which is -// automatically bound to each receiving control. The second init argument is -// "original_sender", which is unchanged. And "args" will be perfectly forwarded -// as the rest arguments. -template <typename EventArgs, typename... Args> -void DispatchEvent( - const std::string& event_name, controls::Control* const original_sender, - events::RoutedEvent<EventArgs>* (controls::Control::*event_ptr)(), - controls::Control* const last_receiver, Args&&... args) { - constexpr auto kLogTag = "DispatchEvent"; - - if (original_sender == nullptr) return; - - CRU_UNUSED(event_name) - - if (original_sender == last_receiver) { - if constexpr (debug_flags::routed_event) - CRU_LOG_TAG_DEBUG( - "Routed event {} no need to dispatch (original_sender == " - "last_receiver). Original sender is {}.", - event_name, original_sender->GetControlType()); - return; - } - - WindowHost::EnterEventHandling(); - - std::vector<ObjectResolver<controls::Control>> receive_list; - - auto parent = original_sender; - while (parent != last_receiver) { - receive_list.push_back(parent->CreateResolver()); - auto p = parent->GetParent(); - assert(!(p == nullptr && last_receiver != nullptr)); - parent = p; - } - - if constexpr (debug_flags::routed_event) { - std::string log = "Dispatch routed event "; - log += event_name; - log += ". Path (parent first): "; - auto i = receive_list.crbegin(); - const auto end = --receive_list.crend(); - for (; i != end; ++i) { - log += i->Resolve()->GetControlType(); - log += " -> "; - } - log += i->Resolve()->GetControlType(); - CRU_LOG_TAG_DEBUG("{}", log); - } - - auto handled = false; - - int count = 0; - - // tunnel - for (auto i = receive_list.crbegin(); i != receive_list.crend(); ++i) { - count++; - auto control = i->Resolve(); - if (!control) continue; - EventArgs event_args(control, original_sender, std::forward<Args>(args)...); - static_cast<Event<EventArgs&>*>((control->*event_ptr)()->Tunnel()) - ->Raise(event_args); - if (event_args.IsHandled()) { - handled = true; - if constexpr (debug_flags::routed_event) - CRU_LOG_TAG_DEBUG( - "Routed event is short-circuit in TUNNEL at {}-st control (count " - "from parent).", - count); - break; - } - } - - // bubble - if (!handled) { - for (const auto& resolver : receive_list) { - count--; - auto control = resolver.Resolve(); - if (!control) continue; - EventArgs event_args(control, original_sender, - std::forward<Args>(args)...); - static_cast<Event<EventArgs&>*>((control->*event_ptr)()->Bubble()) - ->Raise(event_args); - if (event_args.IsHandled()) { - if constexpr (debug_flags::routed_event) - CRU_LOG_TAG_DEBUG( - "Routed event is short-circuit in BUBBLE at {}-st control " - "(count from parent).", - count); - break; - } - } - } - - // direct - for (auto resolver : receive_list) { - auto control = resolver.Resolve(); - if (!control) continue; - EventArgs event_args(control, original_sender, std::forward<Args>(args)...); - static_cast<Event<EventArgs&>*>((control->*event_ptr)()->Direct()) - ->Raise(event_args); - } - - if constexpr (debug_flags::routed_event) - CRU_LOG_TAG_DEBUG("Routed event dispatch finished."); - - WindowHost::LeaveEventHandling(); -} -} // namespace cru::ui::host |
