mirror of
https://github.com/labwc/labwc.git
synced 2026-03-17 05:33:47 -04:00
menu: support borders
This commit adds following theme configurations: menu.border.width: 1 menu.border.color: #aaaaaa
This commit is contained in:
parent
fb6bf3fdde
commit
da418f9720
5 changed files with 67 additions and 19 deletions
|
|
@ -166,6 +166,12 @@ all are supported.
|
||||||
A fixed width can be achieved by setting .min and .max to the same
|
A fixed width can be achieved by setting .min and .max to the same
|
||||||
value.
|
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*
|
*menu.items.padding.x*
|
||||||
Horizontal padding of menu text entries in pixels.
|
Horizontal padding of menu text entries in pixels.
|
||||||
Default is 7.
|
Default is 7.
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ menu.overlap.x: 0
|
||||||
menu.overlap.y: 0
|
menu.overlap.y: 0
|
||||||
menu.width.min: 20
|
menu.width.min: 20
|
||||||
menu.width.max: 200
|
menu.width.max: 200
|
||||||
|
menu.border.width: 1
|
||||||
|
menu.border.color: #aaaaaa
|
||||||
menu.items.bg.color: #fcfbfa
|
menu.items.bg.color: #fcfbfa
|
||||||
menu.items.text.color: #000000
|
menu.items.text.color: #000000
|
||||||
menu.items.active.bg.color: #e1dedb
|
menu.items.active.bg.color: #e1dedb
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ struct theme {
|
||||||
int menu_overlap_y;
|
int menu_overlap_y;
|
||||||
int menu_min_width;
|
int menu_min_width;
|
||||||
int menu_max_width;
|
int menu_max_width;
|
||||||
|
int menu_border_width;
|
||||||
|
float menu_border_color[4];
|
||||||
|
|
||||||
int menu_items_padding_x;
|
int menu_items_padding_x;
|
||||||
int menu_items_padding_y;
|
int menu_items_padding_y;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
#include "common/nodename.h"
|
#include "common/nodename.h"
|
||||||
#include "common/scaled-font-buffer.h"
|
#include "common/scaled-font-buffer.h"
|
||||||
|
#include "common/scaled-rect-buffer.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
#include "common/spawn.h"
|
#include "common/spawn.h"
|
||||||
#include "common/string-helpers.h"
|
#include "common/string-helpers.h"
|
||||||
|
|
@ -169,14 +170,17 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
/* Hide selected state */
|
/* Hide selected state */
|
||||||
wlr_scene_node_set_enabled(&menuitem->selected.tree->node, false);
|
wlr_scene_node_set_enabled(&menuitem->selected.tree->node, false);
|
||||||
|
|
||||||
|
int bg_width = menu->size.width
|
||||||
|
- 2 * theme->menu_border_width;
|
||||||
|
|
||||||
/* Item background nodes */
|
/* Item background nodes */
|
||||||
menuitem->normal.background = &wlr_scene_rect_create(
|
menuitem->normal.background = &wlr_scene_rect_create(
|
||||||
menuitem->normal.tree,
|
menuitem->normal.tree,
|
||||||
menu->size.width, theme->menu_item_height,
|
bg_width, theme->menu_item_height,
|
||||||
theme->menu_items_bg_color)->node;
|
theme->menu_items_bg_color)->node;
|
||||||
menuitem->selected.background = &wlr_scene_rect_create(
|
menuitem->selected.background = &wlr_scene_rect_create(
|
||||||
menuitem->selected.tree,
|
menuitem->selected.tree,
|
||||||
menu->size.width, theme->menu_item_height,
|
bg_width, theme->menu_item_height,
|
||||||
theme->menu_items_active_bg_color)->node;
|
theme->menu_items_active_bg_color)->node;
|
||||||
|
|
||||||
/* Font nodes */
|
/* Font nodes */
|
||||||
|
|
@ -187,7 +191,7 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
menuitem->selected.text = &menuitem->selected.buffer->scene_buffer->node;
|
menuitem->selected.text = &menuitem->selected.buffer->scene_buffer->node;
|
||||||
|
|
||||||
/* Font buffers */
|
/* 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,
|
scaled_font_buffer_update(menuitem->normal.buffer, menuitem->text,
|
||||||
text_width, &rc.font_menuitem,
|
text_width, &rc.font_menuitem,
|
||||||
theme->menu_items_text_color,
|
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);
|
wlr_scene_node_set_position(menuitem->selected.text, x, y);
|
||||||
|
|
||||||
/* Position the item in relation to its menu */
|
/* 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;
|
*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);
|
assert(menuitem->type == LAB_MENU_SEPARATOR_LINE);
|
||||||
struct menu *menu = menuitem->parent;
|
struct menu *menu = menuitem->parent;
|
||||||
struct theme *theme = menu->server->theme;
|
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;
|
+ 2 * theme->menu_separator_padding_height;
|
||||||
|
|
||||||
/* Menu item root node */
|
/* Menu item root node */
|
||||||
|
|
@ -247,11 +253,11 @@ separator_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
|
|
||||||
/* Item background nodes */
|
/* Item background nodes */
|
||||||
menuitem->normal.background = &wlr_scene_rect_create(
|
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;
|
theme->menu_items_bg_color)->node;
|
||||||
|
|
||||||
/* Draw separator line */
|
/* 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.text = &wlr_scene_rect_create(
|
||||||
menuitem->normal.tree, line_width,
|
menuitem->normal.tree, line_width,
|
||||||
theme->menu_separator_line_thickness,
|
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,
|
wlr_scene_node_set_position(menuitem->normal.text,
|
||||||
theme->menu_separator_padding_width,
|
theme->menu_separator_padding_width,
|
||||||
theme->menu_separator_padding_height);
|
theme->menu_separator_padding_height);
|
||||||
wlr_scene_node_set_position(&menuitem->tree->node, 0, *item_y);
|
wlr_scene_node_set_position(&menuitem->tree->node,
|
||||||
*item_y += height;
|
theme->menu_border_width, *item_y);
|
||||||
|
*item_y += bg_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -274,6 +281,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
struct theme *theme = menu->server->theme;
|
struct theme *theme = menu->server->theme;
|
||||||
float *bg_color = theme->menu_title_bg_color;
|
float *bg_color = theme->menu_title_bg_color;
|
||||||
float *text_color = theme->menu_title_text_color;
|
float *text_color = theme->menu_title_text_color;
|
||||||
|
int bg_width = menu->size.width - 2 * theme->menu_border_width;
|
||||||
|
|
||||||
/* Menu item root node */
|
/* Menu item root node */
|
||||||
menuitem->tree = wlr_scene_tree_create(menu->scene_tree);
|
menuitem->tree = wlr_scene_tree_create(menu->scene_tree);
|
||||||
|
|
@ -285,7 +293,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
|
|
||||||
/* Background */
|
/* Background */
|
||||||
menuitem->normal.background = &wlr_scene_rect_create(
|
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;
|
theme->menu_header_height, bg_color)->node;
|
||||||
|
|
||||||
/* Draw separator title */
|
/* Draw separator title */
|
||||||
|
|
@ -293,27 +301,28 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
assert(menuitem->normal.buffer);
|
assert(menuitem->normal.buffer);
|
||||||
menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node;
|
menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node;
|
||||||
scaled_font_buffer_update(menuitem->normal.buffer, menuitem->text,
|
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);
|
&rc.font_menuheader, text_color, bg_color, /* arrow */ NULL);
|
||||||
|
|
||||||
int title_x = 0;
|
int title_x = 0;
|
||||||
switch (theme->menu_title_text_justify) {
|
switch (theme->menu_title_text_justify) {
|
||||||
case LAB_JUSTIFY_CENTER:
|
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);
|
title_x = MAX(title_x, 0);
|
||||||
break;
|
break;
|
||||||
case LAB_JUSTIFY_LEFT:
|
case LAB_JUSTIFY_LEFT:
|
||||||
title_x = theme->menu_items_padding_x;
|
title_x = theme->menu_items_padding_x;
|
||||||
break;
|
break;
|
||||||
case LAB_JUSTIFY_RIGHT:
|
case LAB_JUSTIFY_RIGHT:
|
||||||
title_x = menu->size.width - menuitem->native_width
|
title_x = bg_width - menuitem->native_width
|
||||||
- theme->menu_items_padding_x;
|
- theme->menu_items_padding_x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int title_y = (theme->menu_header_height - menuitem->normal.buffer->height) / 2;
|
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->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;
|
*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 width is the maximum item width, capped by menu.width.{min,max} */
|
||||||
menu->size.width = 0;
|
menu->size.width = 0;
|
||||||
wl_list_for_each(item, &menu->menuitems, link) {
|
wl_list_for_each(item, &menu->menuitems, link) {
|
||||||
menu->size.width = MAX(menu->size.width,
|
int width = item->native_width
|
||||||
item->native_width + 2 * theme->menu_items_padding_x);
|
+ 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 = MAX(menu->size.width, theme->menu_min_width);
|
||||||
menu->size.width = MIN(menu->size.width, theme->menu_max_width);
|
menu->size.width = MIN(menu->size.width, theme->menu_max_width);
|
||||||
|
|
||||||
/* Update all items for the new size */
|
/* 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) {
|
wl_list_for_each(item, &menu->menuitems, link) {
|
||||||
assert(!item->tree);
|
assert(!item->tree);
|
||||||
switch (item->type) {
|
switch (item->type) {
|
||||||
|
|
@ -360,7 +371,15 @@ menu_update_scene(struct menu *menu)
|
||||||
break;
|
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
|
static void
|
||||||
|
|
|
||||||
21
src/theme.c
21
src/theme.c
|
|
@ -597,6 +597,8 @@ theme_builtin(struct theme *theme, struct server *server)
|
||||||
theme->menu_overlap_y = 0;
|
theme->menu_overlap_y = 0;
|
||||||
theme->menu_min_width = 20;
|
theme->menu_min_width = 20;
|
||||||
theme->menu_max_width = 200;
|
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_x = 7;
|
||||||
theme->menu_items_padding_y = 4;
|
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(
|
theme->menu_max_width = get_int_if_positive(
|
||||||
value, "menu.width.max");
|
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")) {
|
if (match_glob(key, "menu.items.padding.x")) {
|
||||||
theme->menu_items_padding_x = get_int_if_positive(
|
theme->menu_items_padding_x = get_int_if_positive(
|
||||||
|
|
@ -1448,7 +1457,8 @@ post_processing(struct theme *theme)
|
||||||
+ 2 * theme->menu_items_padding_y;
|
+ 2 * theme->menu_items_padding_y;
|
||||||
|
|
||||||
theme->menu_header_height = font_height(&rc.font_menuheader)
|
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)
|
theme->osd_window_switcher_item_height = font_height(&rc.font_osd)
|
||||||
+ 2 * theme->osd_window_switcher_item_padding_y
|
+ 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;
|
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 */
|
/* Inherit OSD settings if not set */
|
||||||
if (theme->osd_bg_color[0] == FLT_MIN) {
|
if (theme->osd_bg_color[0] == FLT_MIN) {
|
||||||
memcpy(theme->osd_bg_color,
|
memcpy(theme->osd_bg_color,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue