1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 06:24:58 +00:00

LibGUI: Allow updating the names of menus and submenus

This commit is contained in:
MacDue 2023-03-26 19:39:58 +01:00 committed by Linus Groh
parent cf730403ea
commit a2d333ff4a
4 changed files with 58 additions and 4 deletions

View file

@ -73,6 +73,37 @@ void Menu::remove_all_actions()
m_items.clear();
}
void Menu::update_parent_menu_item()
{
if (auto parent = m_parent_menu.strong_ref()) {
auto const& parent_items = parent->items();
if (m_index_in_parent_menu >= 0 && static_cast<unsigned>(m_index_in_parent_menu) < parent_items.size()) {
auto& item = *parent_items[m_index_in_parent_menu];
if (item.submenu() == this)
item.update_from_menu(Badge<Menu> {});
return;
}
// Parent has since been cleared/repopulated:
parent = nullptr;
m_index_in_parent_menu = -1;
}
}
void Menu::set_name(DeprecatedString name)
{
m_name = move(name);
if (m_menu_id != -1) {
ConnectionToWindowServer::the().async_set_menu_name(m_menu_id, m_name);
update_parent_menu_item();
}
}
void Menu::set_parent(Menu& menu, int submenu_index)
{
m_parent_menu = menu;
m_index_in_parent_menu = submenu_index;
}
ErrorOr<NonnullRefPtr<Menu>> Menu::try_add_submenu(DeprecatedString name)
{
// NOTE: We grow the vector first, to get allocation failure handled immediately.
@ -81,6 +112,8 @@ ErrorOr<NonnullRefPtr<Menu>> Menu::try_add_submenu(DeprecatedString name)
auto submenu = TRY(Menu::try_create(name));
auto item = TRY(adopt_nonnull_own_or_enomem(new (nothrow) MenuItem(m_menu_id, submenu)));
submenu->set_parent(*this, m_items.size());
if (m_menu_id != -1)
realize_menu_item(*item, m_items.size());

View file

@ -33,6 +33,8 @@ public:
int menu_id() const { return m_menu_id; }
DeprecatedString const& name() const { return m_name; }
void set_name(DeprecatedString);
Gfx::Bitmap const* icon() const { return m_icon.ptr(); }
void set_icon(Gfx::Bitmap const*);
@ -73,12 +75,17 @@ private:
void realize_menu_item(MenuItem&, int item_id);
void set_parent(Menu& menu, int submenu_index);
void update_parent_menu_item();
int m_menu_id { -1 };
DeprecatedString m_name;
RefPtr<Gfx::Bitmap const> m_icon;
Vector<NonnullOwnPtr<MenuItem>> m_items;
WeakPtr<Action> m_current_default_action;
bool m_visible { false };
WeakPtr<Menu> m_parent_menu;
int m_index_in_parent_menu { -1 };
Function<void(Action&)> m_recent_files_callback;
};

View file

@ -80,10 +80,23 @@ void MenuItem::update_window_server()
{
if (m_menu_id < 0)
return;
auto& action = *m_action;
auto shortcut_text = action.shortcut().is_valid() ? action.shortcut().to_deprecated_string() : DeprecatedString();
auto icon = action.icon() ? action.icon()->to_shareable_bitmap() : Gfx::ShareableBitmap();
ConnectionToWindowServer::the().async_update_menu_item(m_menu_id, m_identifier, -1, action.text(), action.is_enabled(), action.is_visible(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, m_default, shortcut_text, icon);
switch (m_type) {
case MenuItem::Type::Action: {
auto& action = *m_action;
auto shortcut_text = action.shortcut().is_valid() ? action.shortcut().to_deprecated_string() : DeprecatedString();
auto icon = action.icon() ? action.icon()->to_shareable_bitmap() : Gfx::ShareableBitmap();
ConnectionToWindowServer::the().async_update_menu_item(m_menu_id, m_identifier, -1, action.text(), action.is_enabled(), action.is_visible(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, m_default, shortcut_text, icon);
break;
}
case MenuItem::Type::Submenu: {
auto& submenu = *m_submenu;
auto icon = submenu.icon() ? submenu.icon()->to_shareable_bitmap() : Gfx::ShareableBitmap();
ConnectionToWindowServer::the().async_update_menu_item(m_menu_id, m_identifier, submenu.menu_id(), submenu.name(), m_enabled, m_visible, false, false, m_default, "", icon);
break;
}
default:
VERIFY_NOT_REACHED();
}
}
void MenuItem::set_menu_id(Badge<Menu>, unsigned int menu_id)

View file

@ -56,6 +56,7 @@ public:
void set_identifier(Badge<Menu>, unsigned identifier);
void update_from_action(Badge<Action>) { update_window_server(); }
void update_from_menu(Badge<Menu>) { update_window_server(); }
private:
void update_window_server();