]> git.mdlowis.com Git - proto/labwc.git/commitdiff
menu: support borders
authortokyo4j <hrak1529@gmail.com>
Sun, 24 Nov 2024 05:40:40 +0000 (14:40 +0900)
committerJohan Malm <johanmalm@users.noreply.github.com>
Mon, 25 Nov 2024 19:41:07 +0000 (19:41 +0000)
This commit adds following theme configurations:

  menu.border.width: 1
  menu.border.color: #aaaaaa

docs/labwc-theme.5.scd
docs/themerc
include/theme.h
src/menu/menu.c
src/theme.c

index 9f4b2e9b7bd77c5d2593031468e473553f720090..16cb390f8bec4c2b8ef2ee0b576600715606e849 100644 (file)
@@ -166,6 +166,12 @@ all are supported.
        A fixed width can be achieved by setting .min and .max to the same
        value.
 
+*menu.border.width*
+       Border width of menus in pixels. Inherits *border.width* if not set.
+
+*menu.border.color*
+       Border color of menus. Inherits *window.active.border.color* if not set.
+
 *menu.items.padding.x*
        Horizontal padding of menu text entries in pixels.
        Default is 7.
index 8c6271710f32b8ac0fcba43dcf5b29876adddd2e..1ab3934b8b39f5439be553a6dd1228f232fad08b 100644 (file)
@@ -59,6 +59,8 @@ menu.overlap.x: 0
 menu.overlap.y: 0
 menu.width.min: 20
 menu.width.max: 200
+menu.border.width: 1
+menu.border.color: #aaaaaa
 menu.items.bg.color: #fcfbfa
 menu.items.text.color: #000000
 menu.items.active.bg.color: #e1dedb
index 779b9499db7483b33c6a53a36cafc4ef8c575766..a297e05e0a83a367a1a0e0bfac910840ef0505bd 100644 (file)
@@ -101,6 +101,8 @@ struct theme {
        int menu_overlap_y;
        int menu_min_width;
        int menu_max_width;
+       int menu_border_width;
+       float menu_border_color[4];
 
        int menu_items_padding_x;
        int menu_items_padding_y;
index 1d6da07f2437fee56602ac839c6e4d71209f41bb..d8a99787bb5b1e89494b2dbd592c28b6c1a841fe 100644 (file)
@@ -19,6 +19,7 @@
 #include "common/mem.h"
 #include "common/nodename.h"
 #include "common/scaled-font-buffer.h"
+#include "common/scaled-rect-buffer.h"
 #include "common/scene-helpers.h"
 #include "common/spawn.h"
 #include "common/string-helpers.h"
@@ -169,14 +170,17 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
        /* 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,
-               menu->size.width, theme->menu_item_height,
+               bg_width, theme->menu_item_height,
                theme->menu_items_bg_color)->node;
        menuitem->selected.background = &wlr_scene_rect_create(
                menuitem->selected.tree,
-               menu->size.width, theme->menu_item_height,
+               bg_width, theme->menu_item_height,
                theme->menu_items_active_bg_color)->node;
 
        /* Font nodes */
@@ -187,7 +191,7 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
        menuitem->selected.text = &menuitem->selected.buffer->scene_buffer->node;
 
        /* Font buffers */
-       int text_width = menu->size.width - 2 * theme->menu_items_padding_x;
+       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,
                theme->menu_items_text_color,
@@ -205,7 +209,8 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
        wlr_scene_node_set_position(menuitem->selected.text, x, y);
 
        /* Position the item in relation to its menu */
-       wlr_scene_node_set_position(&menuitem->tree->node, 0, *item_y);
+       wlr_scene_node_set_position(&menuitem->tree->node,
+               theme->menu_border_width, *item_y);
        *item_y += theme->menu_item_height;
 }
 
@@ -234,7 +239,8 @@ separator_create_scene(struct menuitem *menuitem, int *item_y)
        assert(menuitem->type == LAB_MENU_SEPARATOR_LINE);
        struct menu *menu = menuitem->parent;
        struct theme *theme = menu->server->theme;
-       int height = theme->menu_separator_line_thickness
+       int bg_width = menu->size.width - 2 * theme->menu_border_width;
+       int bg_height = theme->menu_separator_line_thickness
                + 2 * theme->menu_separator_padding_height;
 
        /* Menu item root node */
@@ -247,11 +253,11 @@ separator_create_scene(struct menuitem *menuitem, int *item_y)
 
        /* Item background nodes */
        menuitem->normal.background = &wlr_scene_rect_create(
-               menuitem->normal.tree, menu->size.width, height,
+               menuitem->normal.tree, bg_width, bg_height,
                theme->menu_items_bg_color)->node;
 
        /* Draw separator line */
-       int line_width = menu->size.width - 2 * theme->menu_separator_padding_width;
+       int line_width = bg_width - 2 * theme->menu_separator_padding_width;
        menuitem->normal.text = &wlr_scene_rect_create(
                menuitem->normal.tree, line_width,
                theme->menu_separator_line_thickness,
@@ -261,8 +267,9 @@ separator_create_scene(struct menuitem *menuitem, int *item_y)
        wlr_scene_node_set_position(menuitem->normal.text,
                theme->menu_separator_padding_width,
                theme->menu_separator_padding_height);
-       wlr_scene_node_set_position(&menuitem->tree->node, 0, *item_y);
-       *item_y += height;
+       wlr_scene_node_set_position(&menuitem->tree->node,
+               theme->menu_border_width, *item_y);
+       *item_y += bg_height;
 }
 
 static void
@@ -274,6 +281,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
        struct theme *theme = menu->server->theme;
        float *bg_color = theme->menu_title_bg_color;
        float *text_color = theme->menu_title_text_color;
+       int bg_width = menu->size.width - 2 * theme->menu_border_width;
 
        /* Menu item root node */
        menuitem->tree = wlr_scene_tree_create(menu->scene_tree);
@@ -285,7 +293,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
 
        /* Background */
        menuitem->normal.background = &wlr_scene_rect_create(
-               menuitem->normal.tree, menu->size.width,
+               menuitem->normal.tree, bg_width,
                theme->menu_header_height, bg_color)->node;
 
        /* Draw separator title */
@@ -293,27 +301,28 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
        assert(menuitem->normal.buffer);
        menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node;
        scaled_font_buffer_update(menuitem->normal.buffer, menuitem->text,
-               menu->size.width - 2 * theme->menu_items_padding_x,
+               bg_width - 2 * theme->menu_items_padding_x,
                &rc.font_menuheader, text_color, bg_color, /* arrow */ NULL);
 
        int title_x = 0;
        switch (theme->menu_title_text_justify) {
        case LAB_JUSTIFY_CENTER:
-               title_x = (menu->size.width - menuitem->native_width) / 2;
+               title_x = (bg_width - menuitem->native_width) / 2;
                title_x = MAX(title_x, 0);
                break;
        case LAB_JUSTIFY_LEFT:
                title_x = theme->menu_items_padding_x;
                break;
        case LAB_JUSTIFY_RIGHT:
-               title_x = menu->size.width - menuitem->native_width
+               title_x = bg_width - menuitem->native_width
                                - 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);
 
-       wlr_scene_node_set_position(&menuitem->tree->node, 0, *item_y);
+       wlr_scene_node_set_position(&menuitem->tree->node,
+               theme->menu_border_width, *item_y);
        *item_y += theme->menu_header_height;
 }
 
@@ -338,14 +347,16 @@ menu_update_scene(struct menu *menu)
        /* Menu width is the maximum item width, capped by menu.width.{min,max} */
        menu->size.width = 0;
        wl_list_for_each(item, &menu->menuitems, link) {
-               menu->size.width = MAX(menu->size.width,
-                       item->native_width + 2 * theme->menu_items_padding_x);
+               int width = item->native_width
+                       + 2 * theme->menu_items_padding_x
+                       + 2 * theme->menu_border_width;
+               menu->size.width = MAX(menu->size.width, width);
        }
        menu->size.width = MAX(menu->size.width, theme->menu_min_width);
        menu->size.width = MIN(menu->size.width, theme->menu_max_width);
 
        /* Update all items for the new size */
-       int item_y = 0;
+       int item_y = theme->menu_border_width;
        wl_list_for_each(item, &menu->menuitems, link) {
                assert(!item->tree);
                switch (item->type) {
@@ -360,7 +371,15 @@ menu_update_scene(struct menu *menu)
                        break;
                }
        }
-       menu->size.height = item_y;
+       menu->size.height = item_y + theme->menu_border_width;
+
+       float transparent[4] = {0};
+       struct scaled_rect_buffer *bg_buffer = scaled_rect_buffer_create(
+               menu->scene_tree, menu->size.width, menu->size.height,
+               theme->menu_border_width, transparent,
+               theme->menu_border_color);
+       assert(bg_buffer);
+       wlr_scene_node_lower_to_bottom(&bg_buffer->scene_buffer->node);
 }
 
 static void
index 6e3ebbd88c37d9a38e5cece752f3fe56335aa1a9..0637a8dfd9634302d40d5c474a184e76f1e80865 100644 (file)
@@ -597,6 +597,8 @@ theme_builtin(struct theme *theme, struct server *server)
        theme->menu_overlap_y = 0;
        theme->menu_min_width = 20;
        theme->menu_max_width = 200;
+       theme->menu_border_width = INT_MIN;
+       theme->menu_border_color[0] = FLT_MIN;
 
        theme->menu_items_padding_x = 7;
        theme->menu_items_padding_y = 4;
@@ -864,6 +866,13 @@ entry(struct theme *theme, const char *key, const char *value)
                theme->menu_max_width = get_int_if_positive(
                        value, "menu.width.max");
        }
+       if (match_glob(key, "menu.border.width")) {
+               theme->menu_border_width = get_int_if_positive(
+                       value, "menu.border.width");
+       }
+       if (match_glob(key, "menu.border.color")) {
+               parse_hexstr(value, theme->menu_border_color);
+       }
 
        if (match_glob(key, "menu.items.padding.x")) {
                theme->menu_items_padding_x = get_int_if_positive(
@@ -1448,7 +1457,8 @@ post_processing(struct theme *theme)
                + 2 * theme->menu_items_padding_y;
 
        theme->menu_header_height = font_height(&rc.font_menuheader)
-               + 2 * theme->menu_items_padding_y;
+               + 2 * theme->menu_items_padding_y
+               + 2 * theme->menu_border_width;
 
        theme->osd_window_switcher_item_height = font_height(&rc.font_osd)
                + 2 * theme->osd_window_switcher_item_padding_y
@@ -1471,6 +1481,15 @@ post_processing(struct theme *theme)
                theme->menu_max_width = theme->menu_min_width;
        }
 
+       if (theme->menu_border_width == INT_MIN) {
+               theme->menu_border_width = theme->border_width;
+       }
+       if (theme->menu_border_color[0] == FLT_MIN) {
+               memcpy(theme->menu_border_color,
+                       theme->window[THEME_ACTIVE].border_color,
+                       sizeof(theme->menu_border_color));
+       }
+
        /* Inherit OSD settings if not set */
        if (theme->osd_bg_color[0] == FLT_MIN) {
                memcpy(theme->osd_bg_color,