mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:28:11 +00:00
LibGUI: Make GAction scoped to its CObject parent (widget or window)
Unparented GActions are still parented to the application like before, making them globally available. This makes it possible to have actions that work whenever a specific window is active, no matter which widget is currently focused. :^)
This commit is contained in:
parent
6ab9dc4ff4
commit
5b47b0d867
8 changed files with 130 additions and 109 deletions
|
@ -115,6 +115,7 @@ public:
|
||||||
void deferred_invoke(Function<void(CObject&)>);
|
void deferred_invoke(Function<void(CObject&)>);
|
||||||
|
|
||||||
bool is_widget() const { return m_widget; }
|
bool is_widget() const { return m_widget; }
|
||||||
|
virtual bool is_action() const { return false; }
|
||||||
virtual bool is_window() const { return false; }
|
virtual bool is_window() const { return false; }
|
||||||
|
|
||||||
virtual void save_to(AK::JsonObject&);
|
virtual void save_to(AK::JsonObject&);
|
||||||
|
|
|
@ -32,54 +32,54 @@
|
||||||
|
|
||||||
namespace GCommonActions {
|
namespace GCommonActions {
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_open_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_open_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Open...", { Mod_Ctrl, Key_O }, GraphicsBitmap::load_from_file("/res/icons/16x16/open.png"), move(callback), widget);
|
return GAction::create("Open...", { Mod_Ctrl, Key_O }, GraphicsBitmap::load_from_file("/res/icons/16x16/open.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_move_to_front_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_move_to_front_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Move to front", { Mod_Ctrl | Mod_Shift, Key_Up }, GraphicsBitmap::load_from_file("/res/icons/16x16/move-to-front.png"), move(callback), widget);
|
return GAction::create("Move to front", { Mod_Ctrl | Mod_Shift, Key_Up }, GraphicsBitmap::load_from_file("/res/icons/16x16/move-to-front.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_move_to_back_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_move_to_back_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Move to back", { Mod_Ctrl | Mod_Shift, Key_Down }, GraphicsBitmap::load_from_file("/res/icons/16x16/move-to-back.png"), move(callback), widget);
|
return GAction::create("Move to back", { Mod_Ctrl | Mod_Shift, Key_Down }, GraphicsBitmap::load_from_file("/res/icons/16x16/move-to-back.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_undo_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_undo_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Undo", { Mod_Ctrl, Key_Z }, GraphicsBitmap::load_from_file("/res/icons/16x16/undo.png"), move(callback), widget);
|
return GAction::create("Undo", { Mod_Ctrl, Key_Z }, GraphicsBitmap::load_from_file("/res/icons/16x16/undo.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_redo_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_redo_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Redo", { Mod_Ctrl, Key_Y }, GraphicsBitmap::load_from_file("/res/icons/16x16/redo.png"), move(callback), widget);
|
return GAction::create("Redo", { Mod_Ctrl, Key_Y }, GraphicsBitmap::load_from_file("/res/icons/16x16/redo.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_delete_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_delete_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Delete", { Mod_None, Key_Delete }, GraphicsBitmap::load_from_file("/res/icons/16x16/delete.png"), move(callback), widget);
|
return GAction::create("Delete", { Mod_None, Key_Delete }, GraphicsBitmap::load_from_file("/res/icons/16x16/delete.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_cut_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_cut_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Cut", { Mod_Ctrl, Key_X }, GraphicsBitmap::load_from_file("/res/icons/cut16.png"), move(callback), widget);
|
return GAction::create("Cut", { Mod_Ctrl, Key_X }, GraphicsBitmap::load_from_file("/res/icons/cut16.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_copy_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_copy_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Copy", { Mod_Ctrl, Key_C }, GraphicsBitmap::load_from_file("/res/icons/16x16/edit-copy.png"), move(callback), widget);
|
return GAction::create("Copy", { Mod_Ctrl, Key_C }, GraphicsBitmap::load_from_file("/res/icons/16x16/edit-copy.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_paste_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_paste_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Paste", { Mod_Ctrl, Key_V }, GraphicsBitmap::load_from_file("/res/icons/paste16.png"), move(callback), widget);
|
return GAction::create("Paste", { Mod_Ctrl, Key_V }, GraphicsBitmap::load_from_file("/res/icons/paste16.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_fullscreen_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_fullscreen_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Fullscreen", { Mod_None, Key_F11 }, move(callback), widget);
|
return GAction::create("Fullscreen", { Mod_None, Key_F11 }, move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_quit_action(Function<void(GAction&)> callback)
|
NonnullRefPtr<GAction> make_quit_action(Function<void(GAction&)> callback)
|
||||||
|
@ -87,58 +87,59 @@ NonnullRefPtr<GAction> make_quit_action(Function<void(GAction&)> callback)
|
||||||
return GAction::create("Quit", { Mod_Alt, Key_F4 }, move(callback));
|
return GAction::create("Quit", { Mod_Alt, Key_F4 }, move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_go_back_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_go_back_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Go back", { Mod_Alt, Key_Left }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-back.png"), move(callback), widget);
|
return GAction::create("Go back", { Mod_Alt, Key_Left }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-back.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_go_forward_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_go_forward_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Go forward", { Mod_Alt, Key_Right }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-forward.png"), move(callback), widget);
|
return GAction::create("Go forward", { Mod_Alt, Key_Right }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-forward.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_go_home_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_go_home_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Go home", { Mod_Alt, Key_Home }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-home.png"), move(callback), widget);
|
return GAction::create("Go home", { Mod_Alt, Key_Home }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-home.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GAction> make_reload_action(Function<void(GAction&)> callback, GWidget* widget)
|
NonnullRefPtr<GAction> make_reload_action(Function<void(GAction&)> callback, CObject* parent)
|
||||||
{
|
{
|
||||||
return GAction::create("Reload", { Mod_Ctrl, Key_R }, GraphicsBitmap::load_from_file("/res/icons/16x16/reload.png"), move(callback), widget);
|
return GAction::create("Reload", { Mod_Ctrl, Key_R }, GraphicsBitmap::load_from_file("/res/icons/16x16/reload.png"), move(callback), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const StringView& text, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const StringView& text, Function<void(GAction&)> on_activation_callback, CObject* parent)
|
||||||
: on_activation(move(on_activation_callback))
|
: CObject(parent)
|
||||||
|
, on_activation(move(on_activation_callback))
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
, m_widget(widget ? widget->make_weak_ptr() : nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const StringView& text, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const StringView& text, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> on_activation_callback, CObject* parent)
|
||||||
: on_activation(move(on_activation_callback))
|
: CObject(parent)
|
||||||
|
, on_activation(move(on_activation_callback))
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
, m_icon(move(icon))
|
, m_icon(move(icon))
|
||||||
, m_widget(widget ? widget->make_weak_ptr() : nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const StringView& text, const GShortcut& shortcut, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const StringView& text, const GShortcut& shortcut, Function<void(GAction&)> on_activation_callback, CObject* parent)
|
||||||
: GAction(text, shortcut, nullptr, move(on_activation_callback), widget)
|
: GAction(text, shortcut, nullptr, move(on_activation_callback), parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const StringView& text, const GShortcut& shortcut, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const StringView& text, const GShortcut& shortcut, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> on_activation_callback, CObject* parent)
|
||||||
: on_activation(move(on_activation_callback))
|
: CObject(parent)
|
||||||
|
, on_activation(move(on_activation_callback))
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
, m_icon(move(icon))
|
, m_icon(move(icon))
|
||||||
, m_shortcut(shortcut)
|
, m_shortcut(shortcut)
|
||||||
, m_widget(widget ? widget->make_weak_ptr() : nullptr)
|
|
||||||
{
|
{
|
||||||
if (m_widget) {
|
if (parent && is<GWidget>(*parent)) {
|
||||||
m_scope = ShortcutScope::WidgetLocal;
|
m_scope = ShortcutScope::WidgetLocal;
|
||||||
m_widget->register_local_shortcut_action({}, *this);
|
} else if (parent && is<GWindow>(*parent)) {
|
||||||
|
m_scope = ShortcutScope::WindowLocal;
|
||||||
} else {
|
} else {
|
||||||
m_scope = ShortcutScope::ApplicationGlobal;
|
m_scope = ShortcutScope::ApplicationGlobal;
|
||||||
GApplication::the().register_global_shortcut_action({}, *this);
|
GApplication::the().register_global_shortcut_action({}, *this);
|
||||||
|
@ -149,8 +150,6 @@ GAction::~GAction()
|
||||||
{
|
{
|
||||||
if (m_shortcut.is_valid() && m_scope == ShortcutScope::ApplicationGlobal)
|
if (m_shortcut.is_valid() && m_scope == ShortcutScope::ApplicationGlobal)
|
||||||
GApplication::the().unregister_global_shortcut_action({}, *this);
|
GApplication::the().unregister_global_shortcut_action({}, *this);
|
||||||
if (m_widget && m_scope == ShortcutScope::WidgetLocal)
|
|
||||||
m_widget->unregister_local_shortcut_action({}, *this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GAction::activate(CObject* activator)
|
void GAction::activate(CObject* activator)
|
||||||
|
|
|
@ -42,53 +42,51 @@ class GAction;
|
||||||
class GActionGroup;
|
class GActionGroup;
|
||||||
class GButton;
|
class GButton;
|
||||||
class GMenuItem;
|
class GMenuItem;
|
||||||
class GWidget;
|
|
||||||
|
|
||||||
namespace GCommonActions {
|
namespace GCommonActions {
|
||||||
NonnullRefPtr<GAction> make_open_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_open_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_undo_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_undo_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_redo_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_redo_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_cut_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_cut_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_copy_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_copy_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_paste_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_paste_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_delete_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_delete_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_move_to_front_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_move_to_front_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_move_to_back_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_move_to_back_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_fullscreen_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_fullscreen_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_quit_action(Function<void(GAction&)>);
|
NonnullRefPtr<GAction> make_quit_action(Function<void(GAction&)>);
|
||||||
NonnullRefPtr<GAction> make_go_back_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_go_back_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_go_forward_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_go_forward_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_go_home_action(Function<void(GAction&)> callback, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_go_home_action(Function<void(GAction&)> callback, CObject* parent = nullptr);
|
||||||
NonnullRefPtr<GAction> make_reload_action(Function<void(GAction&)>, GWidget* widget = nullptr);
|
NonnullRefPtr<GAction> make_reload_action(Function<void(GAction&)>, CObject* parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GAction : public RefCounted<GAction>
|
class GAction final : public CObject {
|
||||||
, public Weakable<GAction> {
|
C_OBJECT(GAction)
|
||||||
public:
|
public:
|
||||||
enum class ShortcutScope {
|
enum class ShortcutScope {
|
||||||
None,
|
None,
|
||||||
ApplicationGlobal,
|
|
||||||
WidgetLocal,
|
WidgetLocal,
|
||||||
|
WindowLocal,
|
||||||
|
ApplicationGlobal,
|
||||||
};
|
};
|
||||||
static NonnullRefPtr<GAction> create(const StringView& text, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
static NonnullRefPtr<GAction> create(const StringView& text, Function<void(GAction&)> callback, CObject* parent = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, move(callback), widget));
|
return adopt(*new GAction(text, move(callback), parent));
|
||||||
}
|
}
|
||||||
static NonnullRefPtr<GAction> create(const StringView& text, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
static NonnullRefPtr<GAction> create(const StringView& text, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> callback, CObject* parent = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, move(icon), move(callback), widget));
|
return adopt(*new GAction(text, move(icon), move(callback), parent));
|
||||||
}
|
}
|
||||||
static NonnullRefPtr<GAction> create(const StringView& text, const GShortcut& shortcut, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
static NonnullRefPtr<GAction> create(const StringView& text, const GShortcut& shortcut, Function<void(GAction&)> callback, CObject* parent = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, shortcut, move(callback), widget));
|
return adopt(*new GAction(text, shortcut, move(callback), parent));
|
||||||
}
|
}
|
||||||
static NonnullRefPtr<GAction> create(const StringView& text, const GShortcut& shortcut, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
static NonnullRefPtr<GAction> create(const StringView& text, const GShortcut& shortcut, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> callback, CObject* parent = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, shortcut, move(icon), move(callback), widget));
|
return adopt(*new GAction(text, shortcut, move(icon), move(callback), parent));
|
||||||
}
|
}
|
||||||
~GAction();
|
virtual ~GAction() override;
|
||||||
GWidget* widget() { return m_widget.ptr(); }
|
|
||||||
const GWidget* widget() const { return m_widget.ptr(); }
|
|
||||||
|
|
||||||
String text() const { return m_text; }
|
String text() const { return m_text; }
|
||||||
GShortcut shortcut() const { return m_shortcut; }
|
GShortcut shortcut() const { return m_shortcut; }
|
||||||
|
@ -124,10 +122,12 @@ public:
|
||||||
void set_group(Badge<GActionGroup>, GActionGroup*);
|
void set_group(Badge<GActionGroup>, GActionGroup*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GAction(const StringView& text, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
virtual bool is_action() const override { return true; }
|
||||||
GAction(const StringView& text, const GShortcut&, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
|
||||||
GAction(const StringView& text, const GShortcut&, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const StringView& text, Function<void(GAction&)> = nullptr, CObject* = nullptr);
|
||||||
GAction(const StringView& text, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const StringView& text, const GShortcut&, Function<void(GAction&)> = nullptr, CObject* = nullptr);
|
||||||
|
GAction(const StringView& text, const GShortcut&, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> = nullptr, CObject* = nullptr);
|
||||||
|
GAction(const StringView& text, RefPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> = nullptr, CObject* = nullptr);
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each_toolbar_button(Callback);
|
void for_each_toolbar_button(Callback);
|
||||||
|
@ -144,7 +144,12 @@ private:
|
||||||
|
|
||||||
HashTable<GButton*> m_buttons;
|
HashTable<GButton*> m_buttons;
|
||||||
HashTable<GMenuItem*> m_menu_items;
|
HashTable<GMenuItem*> m_menu_items;
|
||||||
WeakPtr<GWidget> m_widget;
|
|
||||||
WeakPtr<GActionGroup> m_action_group;
|
WeakPtr<GActionGroup> m_action_group;
|
||||||
WeakPtr<CObject> m_activator;
|
WeakPtr<CObject> m_activator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline bool is<GAction>(const CObject& object)
|
||||||
|
{
|
||||||
|
return object.is_action();
|
||||||
|
}
|
||||||
|
|
|
@ -626,20 +626,16 @@ bool GWidget::is_backmost() const
|
||||||
|
|
||||||
GAction* GWidget::action_for_key_event(const GKeyEvent& event)
|
GAction* GWidget::action_for_key_event(const GKeyEvent& event)
|
||||||
{
|
{
|
||||||
auto it = m_local_shortcut_actions.find(GShortcut(event.modifiers(), (KeyCode)event.key()));
|
GShortcut shortcut(event.modifiers(), (KeyCode)event.key());
|
||||||
if (it == m_local_shortcut_actions.end())
|
GAction* found_action = nullptr;
|
||||||
return nullptr;
|
for_each_child_of_type<GAction>([&] (auto& action) {
|
||||||
return (*it).value;
|
if (action.shortcut() == shortcut) {
|
||||||
}
|
found_action = &action;
|
||||||
|
return IterationDecision::Break;
|
||||||
void GWidget::register_local_shortcut_action(Badge<GAction>, GAction& action)
|
}
|
||||||
{
|
return IterationDecision::Continue;
|
||||||
m_local_shortcut_actions.set(action.shortcut(), &action);
|
});
|
||||||
}
|
return found_action;
|
||||||
|
|
||||||
void GWidget::unregister_local_shortcut_action(Badge<GAction>, GAction& action)
|
|
||||||
{
|
|
||||||
m_local_shortcut_actions.remove(action.shortcut());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GWidget::set_updates_enabled(bool enabled)
|
void GWidget::set_updates_enabled(bool enabled)
|
||||||
|
|
|
@ -241,9 +241,6 @@ public:
|
||||||
|
|
||||||
GAction* action_for_key_event(const GKeyEvent&);
|
GAction* action_for_key_event(const GKeyEvent&);
|
||||||
|
|
||||||
void register_local_shortcut_action(Badge<GAction>, GAction&);
|
|
||||||
void unregister_local_shortcut_action(Badge<GAction>, GAction&);
|
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each_child_widget(Callback callback)
|
void for_each_child_widget(Callback callback)
|
||||||
{
|
{
|
||||||
|
@ -325,8 +322,6 @@ private:
|
||||||
bool m_layout_dirty { false };
|
bool m_layout_dirty { false };
|
||||||
bool m_updates_enabled { true };
|
bool m_updates_enabled { true };
|
||||||
|
|
||||||
HashMap<GShortcut, GAction*> m_local_shortcut_actions;
|
|
||||||
|
|
||||||
NonnullRefPtr<PaletteImpl> m_palette;
|
NonnullRefPtr<PaletteImpl> m_palette;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <LibC/stdlib.h>
|
#include <LibC/stdlib.h>
|
||||||
#include <LibC/unistd.h>
|
#include <LibC/unistd.h>
|
||||||
#include <LibDraw/GraphicsBitmap.h>
|
#include <LibDraw/GraphicsBitmap.h>
|
||||||
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GEvent.h>
|
#include <LibGUI/GEvent.h>
|
||||||
#include <LibGUI/GPainter.h>
|
#include <LibGUI/GPainter.h>
|
||||||
|
@ -633,3 +634,17 @@ void GWindow::notify_state_changed(Badge<GWindowServerConnection>, bool minimize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAction* GWindow::action_for_key_event(const GKeyEvent& event)
|
||||||
|
{
|
||||||
|
GShortcut shortcut(event.modifiers(), (KeyCode)event.key());
|
||||||
|
GAction* found_action = nullptr;
|
||||||
|
for_each_child_of_type<GAction>([&](auto& action) {
|
||||||
|
if (action.shortcut() == shortcut) {
|
||||||
|
found_action = &action;
|
||||||
|
return IterationDecision::Break;
|
||||||
|
}
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
return found_action;
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include <LibDraw/Rect.h>
|
#include <LibDraw/Rect.h>
|
||||||
#include <LibGUI/GWindowType.h>
|
#include <LibGUI/GWindowType.h>
|
||||||
|
|
||||||
|
class GAction;
|
||||||
|
class GKeyEvent;
|
||||||
class GWMEvent;
|
class GWMEvent;
|
||||||
class GWidget;
|
class GWidget;
|
||||||
class GWindowServerConnection;
|
class GWindowServerConnection;
|
||||||
|
@ -170,6 +172,8 @@ public:
|
||||||
|
|
||||||
virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; }
|
virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; }
|
||||||
|
|
||||||
|
GAction* action_for_key_event(const GKeyEvent&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GWindow(CObject* parent = nullptr);
|
GWindow(CObject* parent = nullptr);
|
||||||
virtual void wm_event(GWMEvent&);
|
virtual void wm_event(GWMEvent&);
|
||||||
|
@ -210,3 +214,9 @@ private:
|
||||||
bool m_layout_pending { false };
|
bool m_layout_pending { false };
|
||||||
bool m_visible_for_timer_purposes { true };
|
bool m_visible_for_timer_purposes { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline bool is<GWindow>(const CObject& object)
|
||||||
|
{
|
||||||
|
return object.is_window();
|
||||||
|
}
|
||||||
|
|
|
@ -136,20 +136,20 @@ void GWindowServerConnection::handle(const WindowClient::KeyDown& message)
|
||||||
key_event->m_text = String(&ch, 1);
|
key_event->m_text = String(&ch, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* focused_widget = window->focused_widget()) {
|
GAction* action = nullptr;
|
||||||
if (auto* action = focused_widget->action_for_key_event(*key_event)) {
|
|
||||||
if (action->is_enabled()) {
|
|
||||||
action->activate();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto* action = GApplication::the().action_for_key_event(*key_event)) {
|
if (auto* focused_widget = window->focused_widget())
|
||||||
if (action->is_enabled()) {
|
action = focused_widget->action_for_key_event(*key_event);
|
||||||
action->activate();
|
|
||||||
return;
|
if (!action)
|
||||||
}
|
action = window->action_for_key_event(*key_event);
|
||||||
|
|
||||||
|
if (!action)
|
||||||
|
action = GApplication::the().action_for_key_event(*key_event);
|
||||||
|
|
||||||
|
if (action && action->is_enabled()) {
|
||||||
|
action->activate();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
CEventLoop::current().post_event(*window, move(key_event));
|
CEventLoop::current().post_event(*window, move(key_event));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue