From 10fc656c2378f61ff6fc88045c1f9e5ba208487d Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Tue, 3 Dec 2024 15:58:07 +0900 Subject: [PATCH] menu: some refactor - Don't store font/background buffers in menuitem struct since we no longer dynamically update buffers of existing menuitems. - Factor out the duplicated codes for creating menu item scenes for each unselected/selected states. --- include/menu/menu.h | 11 +--- src/menu/menu.c | 125 +++++++++++++++++++++----------------------- 2 files changed, 62 insertions(+), 74 deletions(-) diff --git a/include/menu/menu.h b/include/menu/menu.h index 3be301f9..d91dbab8 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -20,13 +20,6 @@ enum menu_align { LAB_MENU_OPEN_BOTTOM = 1 << 3, }; -struct menu_scene { - struct wlr_scene_tree *tree; - struct wlr_scene_node *text; - struct wlr_scene_node *background; - struct scaled_font_buffer *buffer; -}; - enum menuitem_type { LAB_MENU_ITEM = 0, LAB_MENU_SEPARATOR_LINE, @@ -45,8 +38,8 @@ struct menuitem { enum menuitem_type type; int native_width; struct wlr_scene_tree *tree; - struct menu_scene normal; - struct menu_scene selected; + struct wlr_scene_tree *normal_tree; + struct wlr_scene_tree *selected_tree; struct menu_pipe_context *pipe_ctx; struct view *client_list_view; /* used by internal client-list */ struct wl_list link; /* menu.menuitems */ diff --git a/src/menu/menu.c b/src/menu/menu.c index 0cb00647..d4194221 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -151,6 +151,38 @@ item_create(struct menu *menu, const char *text, bool show_arrow) return menuitem; } +static struct wlr_scene_tree * +item_create_scene_for_state(struct menuitem *item, float *text_color, + float *bg_color) +{ + struct menu *menu = item->parent; + struct theme *theme = menu->server->theme; + + /* Tree to hold background and label buffers */ + struct wlr_scene_tree *tree = wlr_scene_tree_create(item->tree); + + /* Create background */ + int bg_width = menu->size.width + - 2 * theme->menu_border_width; + wlr_scene_rect_create(tree, bg_width, theme->menu_item_height, bg_color); + + int arrow_width = item->arrow ? + font_width(&rc.font_menuitem, item->arrow) : 0; + int text_width = bg_width - 2 * theme->menu_items_padding_x - arrow_width; + + /* Create label */ + struct scaled_font_buffer *label_buffer = scaled_font_buffer_create(tree); + assert(label_buffer); + scaled_font_buffer_update(label_buffer, item->text, text_width, + &rc.font_menuitem, text_color, bg_color, item->arrow); + /* Vertically center and left-align label */ + int x = theme->menu_items_padding_x; + int y = (theme->menu_item_height - label_buffer->height) / 2; + wlr_scene_node_set_position(&label_buffer->scene_buffer->node, x, y); + + return tree; +} + static void item_create_scene(struct menuitem *menuitem, int *item_y) { @@ -164,49 +196,15 @@ item_create_scene(struct menuitem *menuitem, int *item_y) node_descriptor_create(&menuitem->tree->node, LAB_NODE_DESC_MENUITEM, menuitem); - /* Tree for each state to hold background and text buffer */ - menuitem->normal.tree = wlr_scene_tree_create(menuitem->tree); - menuitem->selected.tree = wlr_scene_tree_create(menuitem->tree); - /* Hide selected state */ - wlr_scene_node_set_enabled(&menuitem->selected.tree->node, false); - - int bg_width = menu->size.width - - 2 * theme->menu_border_width; - - /* Item background nodes */ - menuitem->normal.background = &wlr_scene_rect_create( - menuitem->normal.tree, - bg_width, theme->menu_item_height, - theme->menu_items_bg_color)->node; - menuitem->selected.background = &wlr_scene_rect_create( - menuitem->selected.tree, - bg_width, theme->menu_item_height, - theme->menu_items_active_bg_color)->node; - - /* Font nodes */ - menuitem->normal.buffer = scaled_font_buffer_create(menuitem->normal.tree); - menuitem->selected.buffer = scaled_font_buffer_create(menuitem->selected.tree); - assert(menuitem->normal.buffer && menuitem->selected.buffer); - menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node; - menuitem->selected.text = &menuitem->selected.buffer->scene_buffer->node; - - /* Font buffers */ - int text_width = bg_width - 2 * theme->menu_items_padding_x; - scaled_font_buffer_update(menuitem->normal.buffer, menuitem->text, - text_width, &rc.font_menuitem, + /* Create scenes for unselected/selected states */ + menuitem->normal_tree = item_create_scene_for_state(menuitem, theme->menu_items_text_color, - theme->menu_items_bg_color, menuitem->arrow); - scaled_font_buffer_update(menuitem->selected.buffer, menuitem->text, - text_width, &rc.font_menuitem, + theme->menu_items_bg_color); + menuitem->selected_tree = item_create_scene_for_state(menuitem, theme->menu_items_active_text_color, - theme->menu_items_active_bg_color, menuitem->arrow); - - /* Center font nodes */ - int x = theme->menu_items_padding_x; - int y = (theme->menu_item_height - menuitem->normal.buffer->height) / 2; - wlr_scene_node_set_position(menuitem->normal.text, x, y); - y = (theme->menu_item_height - menuitem->selected.buffer->height) / 2; - wlr_scene_node_set_position(menuitem->selected.text, x, y); + theme->menu_items_active_bg_color); + /* Hide selected state */ + wlr_scene_node_set_enabled(&menuitem->selected_tree->node, false); /* Position the item in relation to its menu */ wlr_scene_node_set_position(&menuitem->tree->node, @@ -249,22 +247,21 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) LAB_NODE_DESC_MENUITEM, menuitem); /* Tree to hold background and line buffer */ - menuitem->normal.tree = wlr_scene_tree_create(menuitem->tree); + menuitem->normal_tree = wlr_scene_tree_create(menuitem->tree); /* Item background nodes */ - menuitem->normal.background = &wlr_scene_rect_create( - menuitem->normal.tree, bg_width, bg_height, - theme->menu_items_bg_color)->node; + wlr_scene_rect_create(menuitem->normal_tree, bg_width, bg_height, + theme->menu_items_bg_color); /* Draw separator line */ int line_width = bg_width - 2 * theme->menu_separator_padding_width; - menuitem->normal.text = &wlr_scene_rect_create( - menuitem->normal.tree, line_width, + struct wlr_scene_rect *line_rect = wlr_scene_rect_create( + menuitem->normal_tree, line_width, theme->menu_separator_line_thickness, - theme->menu_separator_color)->node; + theme->menu_separator_color); /* Vertically center-align separator line */ - wlr_scene_node_set_position(menuitem->normal.text, + wlr_scene_node_set_position(&line_rect->node, theme->menu_separator_padding_width, theme->menu_separator_padding_height); wlr_scene_node_set_position(&menuitem->tree->node, @@ -289,18 +286,17 @@ title_create_scene(struct menuitem *menuitem, int *item_y) LAB_NODE_DESC_MENUITEM, menuitem); /* Tree to hold background and text buffer */ - menuitem->normal.tree = wlr_scene_tree_create(menuitem->tree); + menuitem->normal_tree = wlr_scene_tree_create(menuitem->tree); /* Background */ - menuitem->normal.background = &wlr_scene_rect_create( - menuitem->normal.tree, bg_width, - theme->menu_header_height, bg_color)->node; + wlr_scene_rect_create(menuitem->normal_tree, + bg_width, theme->menu_header_height, bg_color); /* Draw separator title */ - menuitem->normal.buffer = scaled_font_buffer_create(menuitem->normal.tree); - assert(menuitem->normal.buffer); - menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node; - scaled_font_buffer_update(menuitem->normal.buffer, menuitem->text, + struct scaled_font_buffer *title_font_buffer = + scaled_font_buffer_create(menuitem->normal_tree); + assert(title_font_buffer); + scaled_font_buffer_update(title_font_buffer, menuitem->text, bg_width - 2 * theme->menu_items_padding_x, &rc.font_menuheader, text_color, bg_color, /* arrow */ NULL); @@ -318,8 +314,9 @@ title_create_scene(struct menuitem *menuitem, int *item_y) - theme->menu_items_padding_x; break; } - int title_y = (theme->menu_header_height - menuitem->normal.buffer->height) / 2; - wlr_scene_node_set_position(menuitem->normal.text, title_x, title_y); + int title_y = (theme->menu_header_height - title_font_buffer->height) / 2; + wlr_scene_node_set_position(&title_font_buffer->scene_buffer->node, + title_x, title_y); wlr_scene_node_set_position(&menuitem->tree->node, theme->menu_border_width, *item_y); @@ -337,8 +334,6 @@ menu_update_scene(struct menu *menu) wlr_scene_node_destroy(&menu->scene_tree->node); wl_list_for_each(item, &menu->menuitems, link) { item->tree = NULL; - item->normal = (struct menu_scene){0}; - item->selected = (struct menu_scene){0}; } } menu->scene_tree = wlr_scene_tree_create(menu->server->menu_tree); @@ -1264,14 +1259,14 @@ menu_set_selection(struct menu *menu, struct menuitem *item) /* Clear old selection */ if (menu->selection.item) { wlr_scene_node_set_enabled( - &menu->selection.item->normal.tree->node, true); + &menu->selection.item->normal_tree->node, true); wlr_scene_node_set_enabled( - &menu->selection.item->selected.tree->node, false); + &menu->selection.item->selected_tree->node, false); } /* Set new selection */ if (item) { - wlr_scene_node_set_enabled(&item->normal.tree->node, false); - wlr_scene_node_set_enabled(&item->selected.tree->node, true); + wlr_scene_node_set_enabled(&item->normal_tree->node, false); + wlr_scene_node_set_enabled(&item->selected_tree->node, true); } menu->selection.item = item; } -- 2.52.0