Skip to content

Commit 3085e40

Browse files
committed
LibGUI: Add GAction class and make GMenu deal in actions rather than strings.
1 parent a5a7ea3 commit 3085e40

File tree

9 files changed

+103
-43
lines changed

9 files changed

+103
-43
lines changed

Applications/Terminal/main.cpp

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <LibGUI/GWidget.h>
1515
#include <LibGUI/GWindow.h>
1616
#include <LibGUI/GMenuBar.h>
17+
#include <LibGUI/GAction.h>
1718

1819
static void make_shell(int ptm_fd)
1920
{
@@ -95,38 +96,28 @@ int main(int argc, char** argv)
9596
auto menubar = make<GMenuBar>();
9697

9798
auto app_menu = make<GMenu>("Terminal");
98-
app_menu->add_item(0, "Quit");
99-
app_menu->on_item_activation = [] (unsigned identifier) {
100-
if (identifier == 0) {
101-
dbgprintf("Terminal: Quit menu activated!\n");
102-
GApplication::the().exit(0);
103-
return;
104-
}
105-
};
99+
app_menu->add_action(make<GAction>("Quit", String(), [] (const GAction&) {
100+
dbgprintf("Terminal: Quit menu activated!\n");
101+
GApplication::the().exit(0);
102+
return;
103+
}));
106104
menubar->add_menu(move(app_menu));
107105

108106
auto font_menu = make<GMenu>("Font");
109-
font_menu->add_item(0, "Liza Thin");
110-
font_menu->add_item(1, "Liza Regular");
111-
font_menu->add_item(2, "Liza Bold");
112-
font_menu->on_item_activation = [&terminal] (unsigned identifier) {
113-
switch (identifier) {
114-
case 0:
115-
terminal.set_font(Font::load_from_file("/res/fonts/LizaThin8x10.font"));
116-
break;
117-
case 1:
118-
terminal.set_font(Font::load_from_file("/res/fonts/LizaRegular8x10.font"));
119-
break;
120-
case 2:
121-
terminal.set_font(Font::load_from_file("/res/fonts/LizaBold8x10.font"));
122-
break;
123-
}
107+
auto handle_font_selection = [&terminal] (const GAction& action) {
108+
terminal.set_font(Font::load_from_file(action.custom_data()));
124109
terminal.force_repaint();
125110
};
111+
font_menu->add_action(make<GAction>("Liza Thin", "/res/fonts/LizaThin8x10.font", move(handle_font_selection)));
112+
font_menu->add_action(make<GAction>("Liza Regular", "/res/fonts/LizaRegular8x10.font", move(handle_font_selection)));
113+
font_menu->add_action(make<GAction>("Liza Bold", "/res/fonts/LizaBold8x10.font", move(handle_font_selection)));
114+
126115
menubar->add_menu(move(font_menu));
127116

128117
auto help_menu = make<GMenu>("Help");
129-
help_menu->add_item(0, "About");
118+
help_menu->add_action(make<GAction>("About", [] (const GAction&) {
119+
dbgprintf("FIXME: Implement Help/About\n");
120+
}));
130121
menubar->add_menu(move(help_menu));
131122

132123
app.set_menubar(move(menubar));

LibGUI/GAction.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <LibGUI/GAction.h>
2+
3+
GAction::GAction(const String& text, const String& custom_data, Function<void(const GAction&)> on_activation_callback)
4+
: m_text(text)
5+
, on_activation(move(on_activation_callback))
6+
, m_custom_data(custom_data)
7+
{
8+
}
9+
10+
GAction::GAction(const String& text, Function<void(const GAction&)> on_activation_callback)
11+
: GAction(text, String(), move(on_activation_callback))
12+
{
13+
}
14+
15+
GAction::~GAction()
16+
{
17+
}
18+
19+
void GAction::activate()
20+
{
21+
if (on_activation)
22+
on_activation(*this);
23+
}

LibGUI/GAction.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <AK/AKString.h>
4+
#include <AK/Function.h>
5+
6+
class GAction {
7+
public:
8+
GAction(const String& text, Function<void(const GAction&)> = nullptr);
9+
GAction(const String& text, const String& custom_data = String(), Function<void(const GAction&)> = nullptr);
10+
~GAction();
11+
12+
String text() const { return m_text; }
13+
String custom_data() const { return m_custom_data; }
14+
15+
Function<void(GAction&)> on_activation;
16+
17+
void activate();
18+
19+
private:
20+
String m_text;
21+
String m_custom_data;
22+
};
23+

LibGUI/GEventLoop.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "GEvent.h"
33
#include "GObject.h"
44
#include "GWindow.h"
5+
#include <LibGUI/GAction.h>
56
#include <LibGUI/GNotifier.h>
67
#include <LibGUI/GMenu.h>
78
#include <LibC/unistd.h>
@@ -156,8 +157,8 @@ void GEventLoop::handle_menu_event(const GUI_Event& event)
156157
dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id);
157158
return;
158159
}
159-
if (menu->on_item_activation)
160-
menu->on_item_activation(event.menu.identifier);
160+
if (auto* action = menu->action_at(event.menu.identifier))
161+
action->activate();
161162
return;
162163
}
163164
ASSERT_NOT_REACHED();

LibGUI/GMenu.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <LibGUI/GAction.h>
12
#include <LibGUI/GMenu.h>
23
#include <LibC/gui.h>
34
#include <AK/HashMap.h>
@@ -32,26 +33,38 @@ GMenu::~GMenu()
3233
}
3334
}
3435

35-
void GMenu::add_item(unsigned identifier, const String& text)
36+
void GMenu::add_action(OwnPtr<GAction>&& action)
3637
{
37-
m_items.append({ identifier, text });
38+
m_items.append(make<GMenuItem>(move(action)));
3839
}
3940

4041
void GMenu::add_separator()
4142
{
42-
m_items.append(GMenuItem(GMenuItem::Separator));
43+
m_items.append(make<GMenuItem>(GMenuItem::Separator));
4344
}
4445

4546
int GMenu::realize_menu()
4647
{
4748
m_menu_id = gui_menu_create(m_name.characters());
4849
ASSERT(m_menu_id > 0);
49-
for (auto& item : m_items) {
50-
if (item.type() == GMenuItem::Separator)
50+
for (size_t i = 0; i < m_items.size(); ++i) {
51+
auto& item = *m_items[i];
52+
if (item.type() == GMenuItem::Separator) {
5153
gui_menu_add_separator(m_menu_id);
52-
else if (item.type() == GMenuItem::Text)
53-
gui_menu_add_item(m_menu_id, item.identifier(), item.text().characters());
54+
continue;
55+
}
56+
if (item.type() == GMenuItem::Action) {
57+
auto& action = *item.action();
58+
gui_menu_add_item(m_menu_id, i, action.text().characters());
59+
}
5460
}
5561
all_menus().set(m_menu_id, this);
5662
return m_menu_id;
5763
}
64+
65+
GAction* GMenu::action_at(size_t index)
66+
{
67+
if (index >= m_items.size())
68+
return nullptr;
69+
return m_items[index]->action();
70+
}

LibGUI/GMenu.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
#include <AK/Function.h>
55
#include <AK/Vector.h>
66

7+
class GAction;
8+
79
class GMenu {
810
public:
911
explicit GMenu(const String& name);
1012
~GMenu();
1113

1214
static GMenu* from_menu_id(int);
1315

14-
void add_item(unsigned identifier, const String& text);
16+
GAction* action_at(size_t);
17+
18+
void add_action(OwnPtr<GAction>&&);
1519
void add_separator();
1620

1721
Function<void(unsigned)> on_item_activation;
@@ -23,5 +27,5 @@ class GMenu {
2327

2428
int m_menu_id { 0 };
2529
String m_name;
26-
Vector<GMenuItem> m_items;
30+
Vector<OwnPtr<GMenuItem>> m_items;
2731
};

LibGUI/GMenuItem.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#include <LibGUI/GMenuItem.h>
2+
#include <LibGUI/GAction.h>
23

34
GMenuItem::GMenuItem(Type type)
45
: m_type(type)
56
{
67
}
78

8-
GMenuItem::GMenuItem(unsigned identifier, const String& text)
9-
: m_type(Text)
10-
, m_identifier(identifier)
11-
, m_text(text)
9+
GMenuItem::GMenuItem(OwnPtr<GAction>&& action)
10+
: m_type(Action)
11+
, m_action(move(action))
1212
{
1313
}
1414

LibGUI/GMenuItem.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@
22

33
#include <AK/AKString.h>
44

5+
class GAction;
6+
57
class GMenuItem {
68
public:
7-
enum Type { Invalid, Text, Separator };
9+
enum Type { Invalid, Action, Separator };
810

911
explicit GMenuItem(Type);
10-
GMenuItem(unsigned identifier, const String& text);
12+
explicit GMenuItem(OwnPtr<GAction>&&);
1113
~GMenuItem();
1214

1315
Type type() const { return m_type; }
14-
String text() const { return m_text; }
16+
String text() const;
17+
const GAction* action() const { return m_action.ptr(); }
18+
GAction* action() { return m_action.ptr(); }
1519
unsigned identifier() const { return m_identifier; }
1620

1721
private:
1822
Type m_type { Invalid };
1923
unsigned m_identifier { 0 };
20-
String m_text;
24+
OwnPtr<GAction> m_action;
2125
};
2226

LibGUI/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ LIBGUI_OBJS = \
2525
GMenu.o \
2626
GMenuItem.o \
2727
GApplication.o \
28+
GAction.o \
2829
GWindow.o
2930

3031
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)

0 commit comments

Comments
 (0)