mirror of
https://github.com/labwc/labwc.git
synced 2026-03-01 01:40:24 -05:00
menu: support <separator />
Add theme options: - menu.separator.width - menu.separator.padding.width - menu.separator.padding.height - menu.separator.color Support separator lines defined by <separator /> Note that separator labels (with text) defined by <separator label="" /> are not supported.
This commit is contained in:
parent
f13fbd7aa6
commit
437230b3a0
6 changed files with 123 additions and 19 deletions
|
|
@ -101,6 +101,18 @@ elements are not listed here, but are supported.
|
||||||
*menu.items.active.text.color*
|
*menu.items.active.text.color*
|
||||||
Text color of active menu item
|
Text color of active menu item
|
||||||
|
|
||||||
|
*menu.separator.width*
|
||||||
|
Line thickness of menu separators. Default 1.
|
||||||
|
|
||||||
|
*menu.separator.padding.width*
|
||||||
|
Space on the left and right side of each separator line. Default 6.
|
||||||
|
|
||||||
|
*menu.separator.padding.height*
|
||||||
|
Space above and below each separator line. Default 3.
|
||||||
|
|
||||||
|
*menu.separator.color*
|
||||||
|
Menu separator color. Default #888888.
|
||||||
|
|
||||||
*osd.bg.color*
|
*osd.bg.color*
|
||||||
Background color of on-screen-display
|
Background color of on-screen-display
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,13 @@ menu.items.bg.color: #fcfbfa
|
||||||
menu.items.text.color: #000000
|
menu.items.text.color: #000000
|
||||||
menu.items.active.bg.color: #dddad6
|
menu.items.active.bg.color: #dddad6
|
||||||
menu.items.active.text.color: #000000
|
menu.items.active.text.color: #000000
|
||||||
|
menu.separator.width: 1
|
||||||
|
menu.separator.padding.width: 6
|
||||||
|
menu.separator.padding.height: 3
|
||||||
|
menu.separator.color: #888888
|
||||||
|
|
||||||
# on screen display (window-cycle dialog)
|
# on screen display (window-cycle dialog)
|
||||||
osd.bg.color: #dddda6
|
osd.bg.color: #dddda6
|
||||||
osd.border.color: #000000
|
osd.border.color: #000000
|
||||||
osd.border.width: 1
|
osd.border.width: 1
|
||||||
osd.label.text.color: #000000
|
osd.label.text.color: #000000
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ struct menuitem {
|
||||||
struct wl_list actions;
|
struct wl_list actions;
|
||||||
struct menu *parent;
|
struct menu *parent;
|
||||||
struct menu *submenu;
|
struct menu *submenu;
|
||||||
|
bool selectable;
|
||||||
|
int height;
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
struct menu_scene normal;
|
struct menu_scene normal;
|
||||||
struct menu_scene selected;
|
struct menu_scene selected;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,11 @@ struct theme {
|
||||||
float menu_items_active_bg_color[4];
|
float menu_items_active_bg_color[4];
|
||||||
float menu_items_active_text_color[4];
|
float menu_items_active_text_color[4];
|
||||||
|
|
||||||
|
int menu_separator_width;
|
||||||
|
int menu_separator_padding_width;
|
||||||
|
int menu_separator_padding_height;
|
||||||
|
float menu_separator_color[4];
|
||||||
|
|
||||||
int osd_border_width;
|
int osd_border_width;
|
||||||
float osd_bg_color[4];
|
float osd_bg_color[4];
|
||||||
float osd_border_color[4];
|
float osd_border_color[4];
|
||||||
|
|
|
||||||
100
src/menu/menu.c
100
src/menu/menu.c
|
|
@ -85,6 +85,7 @@ item_create(struct menu *menu, const char *text)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
menuitem->parent = menu;
|
menuitem->parent = menu;
|
||||||
|
menuitem->selectable = true;
|
||||||
struct server *server = menu->server;
|
struct server *server = menu->server;
|
||||||
struct theme *theme = server->theme;
|
struct theme *theme = server->theme;
|
||||||
struct font font = {
|
struct font font = {
|
||||||
|
|
@ -95,6 +96,7 @@ item_create(struct menu *menu, const char *text)
|
||||||
if (!menu->item_height) {
|
if (!menu->item_height) {
|
||||||
menu->item_height = font_height(&font) + 2 * MENU_ITEM_PADDING_Y;
|
menu->item_height = font_height(&font) + 2 * MENU_ITEM_PADDING_Y;
|
||||||
}
|
}
|
||||||
|
menuitem->height = menu->item_height;
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
int item_max_width = MENUWIDTH - 2 * MENU_ITEM_PADDING_X;
|
int item_max_width = MENUWIDTH - 2 * MENU_ITEM_PADDING_X;
|
||||||
|
|
@ -148,21 +150,62 @@ item_create(struct menu *menu, const char *text)
|
||||||
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 */
|
||||||
int item_count = wl_list_length(&menu->menuitems);
|
wlr_scene_node_set_position(&menuitem->tree->node, 0, menu->size.height);
|
||||||
y = item_count * menu->item_height;
|
|
||||||
wlr_scene_node_set_position(&menuitem->tree->node, 0, 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);
|
||||||
|
|
||||||
/* Update menu extents */
|
/* Update menu extents */
|
||||||
menu->size.height = (item_count + 1) * menu->item_height;
|
menu->size.height += menuitem->height;
|
||||||
|
|
||||||
wl_list_insert(&menu->menuitems, &menuitem->link);
|
wl_list_insert(&menu->menuitems, &menuitem->link);
|
||||||
wl_list_init(&menuitem->actions);
|
wl_list_init(&menuitem->actions);
|
||||||
return menuitem;
|
return menuitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct menuitem *
|
||||||
|
separator_create(struct menu *menu, const char *label)
|
||||||
|
{
|
||||||
|
struct menuitem *menuitem = calloc(1, sizeof(struct menuitem));
|
||||||
|
if (!menuitem) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
menuitem->parent = menu;
|
||||||
|
menuitem->selectable = false;
|
||||||
|
struct server *server = menu->server;
|
||||||
|
struct theme *theme = server->theme;
|
||||||
|
menuitem->height = theme->menu_separator_width +
|
||||||
|
2 * theme->menu_separator_padding_height;
|
||||||
|
|
||||||
|
menuitem->tree = wlr_scene_tree_create(menu->scene_tree);
|
||||||
|
node_descriptor_create(&menuitem->tree->node,
|
||||||
|
LAB_NODE_DESC_MENUITEM, menuitem);
|
||||||
|
menuitem->normal.tree = wlr_scene_tree_create(menuitem->tree);
|
||||||
|
menuitem->normal.background = &wlr_scene_rect_create(
|
||||||
|
menuitem->normal.tree,
|
||||||
|
MENUWIDTH, menuitem->height,
|
||||||
|
theme->menu_items_bg_color)->node;
|
||||||
|
|
||||||
|
/* theme->menu_separator_width is the line-thickness (so height here) */
|
||||||
|
menuitem->normal.text = &wlr_scene_rect_create(
|
||||||
|
menuitem->normal.tree,
|
||||||
|
MENUWIDTH - 2 * theme->menu_separator_padding_width,
|
||||||
|
theme->menu_separator_width,
|
||||||
|
theme->menu_separator_color)->node;
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&menuitem->tree->node, 0, menu->size.height);
|
||||||
|
|
||||||
|
/* Vertically center-align separator line */
|
||||||
|
wlr_scene_node_set_position(menuitem->normal.text,
|
||||||
|
theme->menu_separator_padding_width,
|
||||||
|
theme->menu_separator_padding_height);
|
||||||
|
|
||||||
|
menu->size.height += menuitem->height;
|
||||||
|
wl_list_insert(&menu->menuitems, &menuitem->link);
|
||||||
|
wl_list_init(&menuitem->actions);
|
||||||
|
return menuitem;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle the following:
|
* Handle the following:
|
||||||
* <item label="">
|
* <item label="">
|
||||||
|
|
@ -309,6 +352,17 @@ handle_menu_element(xmlNode *n, struct server *server)
|
||||||
zfree(id);
|
zfree(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This can be one of <separator> and <separator label=""> */
|
||||||
|
static void
|
||||||
|
handle_separator_element(xmlNode *n)
|
||||||
|
{
|
||||||
|
char *label = (char *)xmlGetProp(n, (const xmlChar *)"label");
|
||||||
|
current_item = separator_create(current_menu, label);
|
||||||
|
if (label) {
|
||||||
|
free(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xml_tree_walk(xmlNode *node, struct server *server)
|
xml_tree_walk(xmlNode *node, struct server *server)
|
||||||
{
|
{
|
||||||
|
|
@ -320,6 +374,10 @@ xml_tree_walk(xmlNode *node, struct server *server)
|
||||||
handle_menu_element(n, server);
|
handle_menu_element(n, server);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcasecmp((char *)n->name, "separator")) {
|
||||||
|
handle_separator_element(n);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcasecmp((char *)n->name, "item")) {
|
if (!strcasecmp((char *)n->name, "item")) {
|
||||||
in_item = true;
|
in_item = true;
|
||||||
traverse(n, server);
|
traverse(n, server);
|
||||||
|
|
@ -468,24 +526,24 @@ menu_hide_submenu(const char *id)
|
||||||
}
|
}
|
||||||
for (int i = 0; i < nr_menus; ++i) {
|
for (int i = 0; i < nr_menus; ++i) {
|
||||||
menu = menus + i;
|
menu = menus + i;
|
||||||
size_t item_index = 0;
|
bool should_reposition = false;
|
||||||
size_t items_destroyed = 0;
|
struct menuitem *item, *next;
|
||||||
struct menuitem *item, *item_tmp;
|
wl_list_for_each_reverse_safe(item, next, &menu->menuitems, link) {
|
||||||
wl_list_for_each_reverse_safe(item, item_tmp, &menu->menuitems, link) {
|
|
||||||
if (item->submenu == hide_menu) {
|
if (item->submenu == hide_menu) {
|
||||||
item_destroy(item);
|
item_destroy(item);
|
||||||
items_destroyed++;
|
should_reposition = true;
|
||||||
item_index++;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (items_destroyed) {
|
|
||||||
int y = (item_index - items_destroyed) * menu->item_height;
|
|
||||||
wlr_scene_node_set_position(&item->tree->node, 0, y);
|
|
||||||
}
|
|
||||||
item_index++;
|
|
||||||
}
|
}
|
||||||
if (items_destroyed) {
|
|
||||||
menu->size.height -= items_destroyed * menu->item_height;
|
if (!should_reposition) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Re-position items vertically */
|
||||||
|
menu->size.height = 0;
|
||||||
|
wl_list_for_each_reverse(item, &menu->menuitems, link) {
|
||||||
|
wlr_scene_node_set_position(&item->tree->node, 0,
|
||||||
|
menu->size.height);
|
||||||
|
menu->size.height += item->height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -645,6 +703,12 @@ menu_process_cursor_motion(struct wlr_scene_node *node)
|
||||||
assert(node && node->data);
|
assert(node && node->data);
|
||||||
struct menuitem *item = node_menuitem_from_node(node);
|
struct menuitem *item = node_menuitem_from_node(node);
|
||||||
|
|
||||||
|
/* This function shall only be called for menu nodes */
|
||||||
|
assert(item);
|
||||||
|
|
||||||
|
if (!item->selectable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (node == &item->selected.tree->node) {
|
if (node == &item->selected.tree->node) {
|
||||||
/* We are on an already selected item */
|
/* We are on an already selected item */
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
18
src/theme.c
18
src/theme.c
|
|
@ -128,6 +128,11 @@ theme_builtin(struct theme *theme)
|
||||||
parse_hexstr("#dddad6", theme->menu_items_active_bg_color);
|
parse_hexstr("#dddad6", theme->menu_items_active_bg_color);
|
||||||
parse_hexstr("#000000", theme->menu_items_active_text_color);
|
parse_hexstr("#000000", theme->menu_items_active_text_color);
|
||||||
|
|
||||||
|
theme->menu_separator_width = 1;
|
||||||
|
theme->menu_separator_padding_width = 6;
|
||||||
|
theme->menu_separator_padding_height = 3;
|
||||||
|
parse_hexstr("#888888", theme->menu_separator_color);
|
||||||
|
|
||||||
/* inherit settings in post_processing() if not set elsewhere */
|
/* inherit settings in post_processing() if not set elsewhere */
|
||||||
theme->osd_bg_color[0] = FLT_MIN;
|
theme->osd_bg_color[0] = FLT_MIN;
|
||||||
theme->osd_border_width = INT_MIN;
|
theme->osd_border_width = INT_MIN;
|
||||||
|
|
@ -259,6 +264,19 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
parse_hexstr(value, theme->menu_items_active_text_color);
|
parse_hexstr(value, theme->menu_items_active_text_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match(key, "menu.separator.width")) {
|
||||||
|
theme->menu_separator_width = atoi(value);
|
||||||
|
}
|
||||||
|
if (match(key, "menu.separator.padding.width")) {
|
||||||
|
theme->menu_separator_padding_width = atoi(value);
|
||||||
|
}
|
||||||
|
if (match(key, "menu.separator.padding.height")) {
|
||||||
|
theme->menu_separator_padding_height = atoi(value);
|
||||||
|
}
|
||||||
|
if (match(key, "menu.separator.color")) {
|
||||||
|
parse_hexstr(value, theme->menu_separator_color);
|
||||||
|
}
|
||||||
|
|
||||||
if (match(key, "osd.bg.color")) {
|
if (match(key, "osd.bg.color")) {
|
||||||
parse_hexstr(value, theme->osd_bg_color);
|
parse_hexstr(value, theme->osd_bg_color);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue