/* * Copyright (c) 2018-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include namespace GUI { NonnullRefPtr Action::create(DeprecatedString text, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), move(callback), parent)); } NonnullRefPtr Action::create(DeprecatedString text, RefPtr icon, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), move(icon), move(callback), parent)); } NonnullRefPtr Action::create(DeprecatedString text, Shortcut const& shortcut, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), shortcut, move(callback), parent)); } NonnullRefPtr Action::create(DeprecatedString text, Shortcut const& shortcut, Shortcut const& alternate_shortcut, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), shortcut, alternate_shortcut, move(callback), parent)); } NonnullRefPtr Action::create(DeprecatedString text, Shortcut const& shortcut, RefPtr icon, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), shortcut, Shortcut {}, move(icon), move(callback), parent)); } NonnullRefPtr Action::create(DeprecatedString text, Shortcut const& shortcut, Shortcut const& alternate_shortcut, RefPtr icon, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), shortcut, alternate_shortcut, move(icon), move(callback), parent)); } NonnullRefPtr Action::create_checkable(DeprecatedString text, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), move(callback), parent, true)); } NonnullRefPtr Action::create_checkable(DeprecatedString text, RefPtr icon, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), move(icon), move(callback), parent, true)); } NonnullRefPtr Action::create_checkable(DeprecatedString text, Shortcut const& shortcut, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), shortcut, move(callback), parent, true)); } NonnullRefPtr Action::create_checkable(DeprecatedString text, Shortcut const& shortcut, RefPtr icon, Function callback, Core::Object* parent) { return adopt_ref(*new Action(move(text), shortcut, Shortcut {}, move(icon), move(callback), parent, true)); } ErrorOr> Action::try_create_checkable(DeprecatedString text, Shortcut const& shortcut, Function callback, Core::Object* parent) { return adopt_nonnull_ref_or_enomem(new (nothrow) Action(move(text), shortcut, Shortcut {}, move(callback), parent, true)); } RefPtr Action::find_action_for_shortcut(Core::Object& object, Shortcut const& shortcut) { RefPtr found_action = nullptr; object.for_each_child_of_type([&](auto& action) { if (action.shortcut() == shortcut || action.alternate_shortcut() == shortcut) { found_action = &action; return IterationDecision::Break; } return IterationDecision::Continue; }); return found_action; } Action::Action(DeprecatedString text, Function on_activation_callback, Core::Object* parent, bool checkable) : Action(move(text), Shortcut {}, Shortcut {}, nullptr, move(on_activation_callback), parent, checkable) { } Action::Action(DeprecatedString text, RefPtr icon, Function on_activation_callback, Core::Object* parent, bool checkable) : Action(move(text), Shortcut {}, Shortcut {}, move(icon), move(on_activation_callback), parent, checkable) { } Action::Action(DeprecatedString text, Shortcut const& shortcut, Function on_activation_callback, Core::Object* parent, bool checkable) : Action(move(text), shortcut, Shortcut {}, nullptr, move(on_activation_callback), parent, checkable) { } Action::Action(DeprecatedString text, Shortcut const& shortcut, Shortcut const& alternate_shortcut, Function on_activation_callback, Core::Object* parent, bool checkable) : Action(move(text), shortcut, alternate_shortcut, nullptr, move(on_activation_callback), parent, checkable) { } Action::Action(DeprecatedString text, Shortcut const& shortcut, Shortcut const& alternate_shortcut, RefPtr icon, Function on_activation_callback, Core::Object* parent, bool checkable) : Core::Object(parent) , on_activation(move(on_activation_callback)) , m_text(move(text)) , m_icon(move(icon)) , m_shortcut(shortcut) , m_alternate_shortcut(alternate_shortcut) , m_checkable(checkable) { if (parent && is(*parent)) { m_scope = ShortcutScope::WidgetLocal; } else if (parent && is(*parent)) { m_scope = ShortcutScope::WindowLocal; } else { m_scope = ShortcutScope::ApplicationGlobal; if (auto* app = Application::the()) { app->register_global_shortcut_action({}, *this); } } } Action::~Action() { if (m_scope == ShortcutScope::ApplicationGlobal) { if (auto* app = Application::the()) app->unregister_global_shortcut_action({}, *this); } } void Action::process_event(Window& window, Event& event) { if (is_enabled() && is_visible() && !is_activating()) { flash_menubar_menu(window); activate(); event.accept(); return; } if (swallow_key_event_when_disabled()) { event.accept(); return; } event.ignore(); } void Action::activate(Core::Object* activator) { if (is_activating()) return; TemporaryChange change { m_activating, true }; if (!on_activation) return; if (activator) m_activator = activator->make_weak_ptr(); if (is_checkable()) { if (m_action_group) { if (m_action_group->is_unchecking_allowed()) set_checked(!is_checked()); else set_checked(true); } else { set_checked(!is_checked()); } } if (activator == nullptr) { for_each_toolbar_button([](auto& button) { button.mimic_pressed(); }); } on_activation(*this); m_activator = nullptr; } void Action::flash_menubar_menu(GUI::Window& window) { for (auto& menu_item : m_menu_items) window.flash_menubar_menu_for(*menu_item); } void Action::register_button(Badge