From f0cde70c18b51f8e2a701a0cbf0df028e7231e12 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 29 Apr 2020 11:48:11 +0200 Subject: [PATCH] LibGUI: Simplify submenu construction The API for adding a submenu to a menu is now: auto& submenu = menu.add_submenu("Name"); submenu.add_action(my_action); --- Applications/HexEditor/HexEditorWidget.cpp | 16 +++++----- Applications/IRCClient/IRCAppWindow.cpp | 19 ++++++------ Applications/IRCClient/IRCWindow.cpp | 32 +++++++++----------- Applications/SystemMenu/main.cpp | 8 ++--- Applications/TextEditor/TextEditorWidget.cpp | 31 +++++++++---------- Libraries/LibGUI/Menu.cpp | 6 ++-- Libraries/LibGUI/Menu.h | 2 +- Libraries/LibGUI/MenuItem.cpp | 4 +-- Libraries/LibGUI/MenuItem.h | 4 +-- 9 files changed, 57 insertions(+), 65 deletions(-) diff --git a/Applications/HexEditor/HexEditorWidget.cpp b/Applications/HexEditor/HexEditorWidget.cpp index 963068d4112..59d887789ef 100644 --- a/Applications/HexEditor/HexEditorWidget.cpp +++ b/Applications/HexEditor/HexEditorWidget.cpp @@ -146,14 +146,6 @@ HexEditorWidget::HexEditorWidget() GUI::Application::the().quit(0); })); - auto bytes_per_row_menu = GUI::Menu::construct("Bytes Per Row"); - for (int i = 8; i <= 32; i += 8) { - bytes_per_row_menu->add_action(GUI::Action::create(String::number(i), [this, i](auto&) { - m_editor->set_bytes_per_row(i); - m_editor->update(); - })); - } - m_goto_decimal_offset_action = GUI::Action::create("Go To Offset (Decimal)...", { Mod_Ctrl | Mod_Shift, Key_G }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [this](const GUI::Action&) { auto input_box = GUI::InputBox::construct("Enter Decimal offset:", "Go To", window()); if (input_box->exec() == GUI::InputBox::ExecOK && !input_box->text_value().is_empty()) { @@ -197,7 +189,13 @@ HexEditorWidget::HexEditorWidget() })); auto& view_menu = menubar->add_menu("View"); - view_menu.add_submenu(move(bytes_per_row_menu)); + auto& bytes_per_row_menu = view_menu.add_submenu("Bytes per row"); + for (int i = 8; i <= 32; i += 8) { + bytes_per_row_menu.add_action(GUI::Action::create(String::number(i), [this, i](auto&) { + m_editor->set_bytes_per_row(i); + m_editor->update(); + })); + } auto& help_menu = menubar->add_menu("Help"); help_menu.add_action(GUI::Action::create("About", [&](auto&) { diff --git a/Applications/IRCClient/IRCAppWindow.cpp b/Applications/IRCClient/IRCAppWindow.cpp index cbb94670b86..b6fc9c01bfb 100644 --- a/Applications/IRCClient/IRCAppWindow.cpp +++ b/Applications/IRCClient/IRCAppWindow.cpp @@ -283,16 +283,15 @@ void IRCAppWindow::setup_menus() channel_menu.add_action(*m_invite_user_action); channel_menu.add_action(*m_banlist_action); - RefPtr channel_control_menu = GUI::Menu::construct("Control"); - channel_menu.add_submenu(*channel_control_menu); - channel_control_menu->add_action(*m_voice_user_action); - channel_control_menu->add_action(*m_devoice_user_action); - channel_control_menu->add_action(*m_hop_user_action); - channel_control_menu->add_action(*m_dehop_user_action); - channel_control_menu->add_action(*m_op_user_action); - channel_control_menu->add_action(*m_deop_user_action); - channel_control_menu->add_separator(); - channel_control_menu->add_action(*m_kick_user_action); + auto& channel_control_menu = channel_menu.add_submenu("Control"); + channel_control_menu.add_action(*m_voice_user_action); + channel_control_menu.add_action(*m_devoice_user_action); + channel_control_menu.add_action(*m_hop_user_action); + channel_control_menu.add_action(*m_dehop_user_action); + channel_control_menu.add_action(*m_op_user_action); + channel_control_menu.add_action(*m_deop_user_action); + channel_control_menu.add_separator(); + channel_control_menu.add_action(*m_kick_user_action); channel_menu.add_separator(); channel_menu.add_action(*m_cycle_channel_action); diff --git a/Applications/IRCClient/IRCWindow.cpp b/Applications/IRCClient/IRCWindow.cpp index ad6a1095ef5..7557621b20b 100644 --- a/Applications/IRCClient/IRCWindow.cpp +++ b/Applications/IRCClient/IRCWindow.cpp @@ -90,10 +90,9 @@ IRCWindow::IRCWindow(IRCClient& client, void* owner, Type type, const String& na m_client.handle_whois_action(m_client.nick_without_prefix(nick.characters())); })); - RefPtr m_context_control_menu = GUI::Menu::construct("Control"); - m_context_menu->add_submenu(*m_context_control_menu); + auto& context_control_menu = m_context_menu->add_submenu("Control"); - m_context_control_menu->add_action(GUI::Action::create("Voice", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("Voice", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; @@ -101,44 +100,44 @@ IRCWindow::IRCWindow(IRCClient& client, void* owner, Type type, const String& na m_client.handle_voice_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters())); })); - m_context_control_menu->add_action(GUI::Action::create("DeVoice", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("DeVoice", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_devoice_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters())); })); - m_context_control_menu->add_action(GUI::Action::create("Hop", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("Hop", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_hop_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters())); })); - m_context_control_menu->add_action(GUI::Action::create("DeHop", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("DeHop", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_dehop_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters())); })); - m_context_control_menu->add_action(GUI::Action::create("Op", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("Op", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_op_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters())); })); - m_context_control_menu->add_action(GUI::Action::create("DeOp", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("DeOp", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_deop_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters())); })); - m_context_control_menu->add_separator(); + context_control_menu.add_separator(); - m_context_control_menu->add_action(GUI::Action::create("Kick", [&](const GUI::Action&) { + context_control_menu.add_action(GUI::Action::create("Kick", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; @@ -149,38 +148,37 @@ IRCWindow::IRCWindow(IRCClient& client, void* owner, Type type, const String& na m_client.handle_kick_user_action(m_name.characters(), m_client.nick_without_prefix(nick.characters()), input_box->text_value()); })); - RefPtr m_context_ctcp_menu = GUI::Menu::construct("CTCP"); - m_context_menu->add_submenu(*m_context_ctcp_menu); + auto& context_ctcp_menu = m_context_menu->add_submenu("CTCP"); - m_context_ctcp_menu->add_action(GUI::Action::create("User info", [&](const GUI::Action&) { + context_ctcp_menu.add_action(GUI::Action::create("User info", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "USERINFO"); })); - m_context_ctcp_menu->add_action(GUI::Action::create("Finger", [&](const GUI::Action&) { + context_ctcp_menu.add_action(GUI::Action::create("Finger", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "FINGER"); })); - m_context_ctcp_menu->add_action(GUI::Action::create("Time", [&](const GUI::Action&) { + context_ctcp_menu.add_action(GUI::Action::create("Time", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "TIME"); })); - m_context_ctcp_menu->add_action(GUI::Action::create("Version", [&](const GUI::Action&) { + context_ctcp_menu.add_action(GUI::Action::create("Version", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "VERSION"); })); - m_context_ctcp_menu->add_action(GUI::Action::create("Client info", [&](const GUI::Action&) { + context_ctcp_menu.add_action(GUI::Action::create("Client info", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty()) return; diff --git a/Applications/SystemMenu/main.cpp b/Applications/SystemMenu/main.cpp index 4398acb82d6..1a12b9548b3 100644 --- a/Applications/SystemMenu/main.cpp +++ b/Applications/SystemMenu/main.cpp @@ -137,9 +137,8 @@ NonnullRefPtr build_system_menu() if (g_app_category_menus.contains(category)) continue; - auto category_menu = GUI::Menu::construct(category); - system_menu->add_submenu(category_menu); - g_app_category_menus.set(category, move(category_menu)); + auto& category_menu = system_menu->add_submenu(category); + g_app_category_menus.set(category, category_menu); } // Then we create and insert all the app menu items into the right place. @@ -171,9 +170,8 @@ NonnullRefPtr build_system_menu() g_themes_group.set_exclusive(true); g_themes_group.set_unchecking_allowed(false); - g_themes_menu = GUI::Menu::construct("Themes"); - system_menu->add_submenu(*g_themes_menu); + g_themes_menu = &system_menu->add_submenu("Themes"); { Core::DirIterator dt("/res/themes", Core::DirIterator::SkipDots); diff --git a/Applications/TextEditor/TextEditorWidget.cpp b/Applications/TextEditor/TextEditorWidget.cpp index f3d3a5a0d28..5533b396200 100644 --- a/Applications/TextEditor/TextEditorWidget.cpp +++ b/Applications/TextEditor/TextEditorWidget.cpp @@ -384,7 +384,19 @@ TextEditorWidget::TextEditorWidget() edit_menu.add_action(*m_replace_previous_action); edit_menu.add_action(*m_replace_all_action); - auto& font_menu = menubar->add_menu("Font"); + m_markdown_preview_action = GUI::Action::create_checkable( + "Markdown preview", [this](auto& action) { + set_markdown_preview_enabled(action.is_checked()); + }, + this); + + auto& view_menu = menubar->add_menu("View"); + view_menu.add_action(*m_line_wrapping_setting_action); + view_menu.add_separator(); + view_menu.add_action(*m_markdown_preview_action); + view_menu.add_separator(); + + auto& font_menu = view_menu.add_submenu("Font"); GUI::FontDatabase::the().for_each_fixed_width_font([&](const StringView& font_name) { font_menu.add_action(GUI::Action::create(font_name, [this](const GUI::Action& action) { m_editor->set_font(GUI::FontDatabase::the().get_by_name(action.text())); @@ -392,10 +404,9 @@ TextEditorWidget::TextEditorWidget() })); }); - syntax_actions = GUI::ActionGroup {}; syntax_actions.set_exclusive(true); - auto& syntax_menu = menubar->add_menu("Syntax"); + auto& syntax_menu = view_menu.add_submenu("Syntax"); m_plain_text_highlight = GUI::Action::create_checkable("Plain text", [&](auto&) { m_editor->set_syntax_highlighter(nullptr); m_editor->update(); @@ -418,20 +429,6 @@ TextEditorWidget::TextEditorWidget() syntax_actions.add_action(*m_js_highlight); syntax_menu.add_action(*m_js_highlight); - m_markdown_preview_action = GUI::Action::create_checkable( - "Markdown preview", [this](auto& action) { - set_markdown_preview_enabled(action.is_checked()); - }, - this); - - auto& view_menu = menubar->add_menu("View"); - view_menu.add_action(*m_line_wrapping_setting_action); - view_menu.add_separator(); - view_menu.add_action(*m_markdown_preview_action); - view_menu.add_separator(); - view_menu.add_submenu(move(font_menu)); - view_menu.add_submenu(move(syntax_menu)); - auto& help_menu = menubar->add_menu("Help"); help_menu.add_action(GUI::Action::create("About", [&](auto&) { GUI::AboutDialog::show("Text Editor", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-texteditor.png"), window()); diff --git a/Libraries/LibGUI/Menu.cpp b/Libraries/LibGUI/Menu.cpp index c06fa631b29..2e39b886909 100644 --- a/Libraries/LibGUI/Menu.cpp +++ b/Libraries/LibGUI/Menu.cpp @@ -71,9 +71,11 @@ void Menu::add_action(NonnullRefPtr action) #endif } -void Menu::add_submenu(NonnullRefPtr submenu) +Menu& Menu::add_submenu(const String& name) { - m_items.append(make(m_menu_id, move(submenu))); + auto submenu = Menu::construct(name); + m_items.append(make(m_menu_id, submenu)); + return submenu; } void Menu::add_separator() diff --git a/Libraries/LibGUI/Menu.h b/Libraries/LibGUI/Menu.h index e0516383134..8770b21b533 100644 --- a/Libraries/LibGUI/Menu.h +++ b/Libraries/LibGUI/Menu.h @@ -54,7 +54,7 @@ public: void add_action(NonnullRefPtr); void add_separator(); - void add_submenu(NonnullRefPtr); + Menu& add_submenu(const String& name); void popup(const Gfx::Point& screen_position); void dismiss(); diff --git a/Libraries/LibGUI/MenuItem.cpp b/Libraries/LibGUI/MenuItem.cpp index 8b75a45e69c..cc6aa81b222 100644 --- a/Libraries/LibGUI/MenuItem.cpp +++ b/Libraries/LibGUI/MenuItem.cpp @@ -37,7 +37,7 @@ MenuItem::MenuItem(unsigned menu_id, Type type) { } -MenuItem::MenuItem(unsigned menu_id, NonnullRefPtr&& action) +MenuItem::MenuItem(unsigned menu_id, NonnullRefPtr action) : m_type(Type::Action) , m_menu_id(menu_id) , m_action(move(action)) @@ -49,7 +49,7 @@ MenuItem::MenuItem(unsigned menu_id, NonnullRefPtr&& action) m_checked = m_action->is_checked(); } -MenuItem::MenuItem(unsigned menu_id, NonnullRefPtr&& submenu) +MenuItem::MenuItem(unsigned menu_id, NonnullRefPtr submenu) : m_type(Type::Submenu) , m_menu_id(menu_id) , m_submenu(move(submenu)) diff --git a/Libraries/LibGUI/MenuItem.h b/Libraries/LibGUI/MenuItem.h index a55d60fdccb..871690a805e 100644 --- a/Libraries/LibGUI/MenuItem.h +++ b/Libraries/LibGUI/MenuItem.h @@ -42,8 +42,8 @@ public: }; MenuItem(unsigned menu_id, Type); - MenuItem(unsigned menu_id, NonnullRefPtr&&); - MenuItem(unsigned menu_id, NonnullRefPtr&&); + MenuItem(unsigned menu_id, NonnullRefPtr); + MenuItem(unsigned menu_id, NonnullRefPtr); ~MenuItem(); Type type() const { return m_type; }