1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-11-02 08:57:19 -04:00

[menu] _node

This commit is contained in:
Witold Filipczyk 2022-03-18 18:44:13 +01:00
parent 8497f59420
commit 1db4844920

View File

@ -396,6 +396,35 @@ draw_menu_left_text(struct terminal *term, char *text, int len,
draw_text(term, x + L_TEXT_SPACE, y, text, len, 0, color); draw_text(term, x + L_TEXT_SPACE, y, text, len, 0, color);
} }
/* width - number of standard terminal cells to be displayed (text + whitespace
* separators). For double-width glyph width == 2.
* len - length of text in bytes */
static inline void
draw_menu_left_text_node(struct terminal *term, char *text, int len,
int x, int y, int width, unsigned int color_node)
{
int w = width - (L_TEXT_SPACE + R_TEXT_SPACE);
int max_len;
if (w <= 0) return;
if (len < 0) len = strlen(text);
if (!len) return;
#ifdef CONFIG_UTF8
if (term->utf8_cp) {
max_len = utf8_cells2bytes(text, w, NULL);
if (max_len <= 0)
return;
} else
#endif /* CONFIG_UTF8 */
max_len = w;
if (len > max_len) len = max_len;
draw_text_node(term, x + L_TEXT_SPACE, y, text, len, 0, color_node);
}
static inline void static inline void
draw_menu_left_text_hk(struct terminal *term, char *text, draw_menu_left_text_hk(struct terminal *term, char *text,
@ -520,6 +549,129 @@ utf8:
#endif /* CONFIG_UTF8 */ #endif /* CONFIG_UTF8 */
} }
static inline void
draw_menu_left_text_hk_node(struct terminal *term, char *text,
int hotkey_pos, int x, int y, int width,
unsigned int color_node, int selected)
{
unsigned int hk_color_node = get_bfu_color_node(term, "menu.hotkey.normal");
unsigned int hk_color_sel_node = get_bfu_color_node(term, "menu.hotkey.selected");
screen_char_attr_T hk_attr = get_opt_bool("ui.dialogs.underline_hotkeys", NULL)
? SCREEN_ATTR_UNDERLINE : 0;
unsigned char c;
int xbase = x + L_TEXT_SPACE;
int w = width - (L_TEXT_SPACE + R_TEXT_SPACE);
int hk_state = 0;
#ifdef CONFIG_UTF8
char *text2, *end;
#endif
#ifdef CONFIG_DEBUG
/* For redundant hotkeys highlighting. */
int double_hk = 0;
if (hotkey_pos < 0) hotkey_pos = -hotkey_pos, double_hk = 1;
#endif
if (!hotkey_pos || w <= 0) return;
if (selected) {
unsigned int tmp = hk_color_node;
hk_color_node = hk_color_sel_node;
hk_color_sel_node = tmp;
}
#ifdef CONFIG_UTF8
if (term->utf8_cp) goto utf8;
#endif /* CONFIG_UTF8 */
for (x = 0; x - !!hk_state < w && (c = text[x]); x++) {
if (!hk_state && x == hotkey_pos - 1) {
hk_state = 1;
continue;
}
if (hk_state == 1) {
#ifdef CONFIG_DEBUG
draw_char_node(term, xbase + x - 1, y, c, hk_attr,
(double_hk ? hk_color_sel_node : hk_color_node));
#else
draw_char_node(term, xbase + x - 1, y, c, hk_attr, hk_color_node);
#endif /* CONFIG_DEBUG */
hk_state = 2;
} else {
draw_char_node(term, xbase + x - !!hk_state, y, c, 0, color_node);
}
}
return;
#ifdef CONFIG_UTF8
utf8:
end = strchr(text, '\0');
text2 = text;
for (x = 0; x - !!hk_state < w && *text2; x++) {
unicode_val_T data;
data = utf8_to_unicode(&text2, end);
if (!hk_state && (int)(text2 - text) == hotkey_pos) {
hk_state = 1;
continue;
}
if (hk_state == 1) {
if (unicode_to_cell(data) == 2) {
if (x < w && xbase + x < term->width) {
#ifdef CONFIG_DEBUG
draw_char_node(term, xbase + x - 1, y,
data, hk_attr,
(double_hk ? hk_color_sel_node
: hk_color_node));
#else
draw_char_node(term, xbase + x - 1, y,
data, hk_attr, hk_color_node);
#endif /* CONFIG_DEBUG */
x++;
draw_char_node(term, xbase + x - 1, y,
UCS_NO_CHAR, 0, hk_color_node);
} else {
draw_char_node(term, xbase + x - 1, y,
UCS_ORPHAN_CELL, 0, hk_color_node);
}
} else {
#ifdef CONFIG_DEBUG
draw_char_node(term, xbase + x - 1, y,
data, hk_attr,
(double_hk ? hk_color_sel_node
: hk_color_node));
#else
draw_char_node(term, xbase + x - 1, y,
data, hk_attr, hk_color_node);
#endif /* CONFIG_DEBUG */
}
hk_state = 2;
} else {
if (unicode_to_cell(data) == 2) {
if (x - !!hk_state + 1 < w &&
xbase + x - !!hk_state + 1 < term->width) {
draw_char_node(term, xbase + x - !!hk_state,
y, data, 0, color_node);
x++;
draw_char_node(term, xbase + x - !!hk_state,
y, UCS_NO_CHAR, 0, color_node);
} else {
draw_char_node(term, xbase + x - !!hk_state,
y, UCS_ORPHAN_CELL, 0, color_node);
}
} else {
draw_char_node(term, xbase + x - !!hk_state,
y, data, 0, color_node);
}
}
}
#endif /* CONFIG_UTF8 */
}
static inline void static inline void
draw_menu_right_text(struct terminal *term, char *text, int len, draw_menu_right_text(struct terminal *term, char *text, int len,
int x, int y, int width, struct color_pair *color) int x, int y, int width, struct color_pair *color)
@ -537,12 +689,34 @@ draw_menu_right_text(struct terminal *term, char *text, int len,
draw_text(term, x, y, text, len, 0, color); draw_text(term, x, y, text, len, 0, color);
} }
static inline void
draw_menu_right_text_node(struct terminal *term, char *text, int len,
int x, int y, int width, unsigned int color_node)
{
int w = width - (L_RTEXT_SPACE + R_RTEXT_SPACE);
if (w <= 0) return;
if (len < 0) len = strlen(text);
if (!len) return;
if (len > w) len = w;
x += w - len + L_RTEXT_SPACE + L_TEXT_SPACE;
draw_text_node(term, x, y, text, len, 0, color_node);
}
static void static void
display_menu(struct terminal *term, struct menu *menu) display_menu(struct terminal *term, struct menu *menu)
{ {
struct color_pair *normal_color = get_bfu_color(term, "menu.normal"); // struct color_pair *normal_color = get_bfu_color(term, "menu.normal");
struct color_pair *selected_color = get_bfu_color(term, "menu.selected"); // struct color_pair *selected_color = get_bfu_color(term, "menu.selected");
struct color_pair *frame_color = get_bfu_color(term, "menu.frame"); // struct color_pair *frame_color = get_bfu_color(term, "menu.frame");
unsigned int normal_color_node = get_bfu_color_node(term, "menu.normal");
unsigned int selected_color_node = get_bfu_color_node(term, "menu.selected");
unsigned int frame_color_node = get_bfu_color_node(term, "menu.frame");
struct el_box box; struct el_box box;
int p; int p;
int menu_height; int menu_height;
@ -553,13 +727,13 @@ display_menu(struct terminal *term, struct menu *menu)
int_max(0, menu->box.width - MENU_BORDER_SIZE * 2), int_max(0, menu->box.width - MENU_BORDER_SIZE * 2),
int_max(0, menu->box.height - MENU_BORDER_SIZE * 2)); int_max(0, menu->box.height - MENU_BORDER_SIZE * 2));
draw_box(term, &box, ' ', 0, normal_color); draw_box_node(term, &box, ' ', 0, normal_color_node);
draw_border(term, &box, frame_color, 1); draw_border_node(term, &box, frame_color_node, 1);
if (get_opt_bool("ui.dialogs.shadows", NULL)) { if (get_opt_bool("ui.dialogs.shadows", NULL)) {
/* Draw shadow */ /* Draw shadow */
draw_shadow(term, &menu->box, draw_shadow_node(term, &menu->box,
get_bfu_color(term, "dialog.shadow"), 2, 1); get_bfu_color_node(term, "dialog.shadow"), 2, 1);
#ifdef CONFIG_UTF8 #ifdef CONFIG_UTF8
if (term->utf8_cp) if (term->utf8_cp)
fix_dwchar_around_box(term, &box, 1, 2, 1); fix_dwchar_around_box(term, &box, 1, 2, 1);
@ -576,7 +750,8 @@ display_menu(struct terminal *term, struct menu *menu)
for (p = menu->first; for (p = menu->first;
p < menu->size && p < menu->first + menu_height; p < menu->size && p < menu->first + menu_height;
p++, box.y++) { p++, box.y++) {
struct color_pair *color = normal_color; // struct color_pair *color = normal_color;
unsigned int color_node = normal_color_node;
struct menu_item *mi = &menu->items[p]; struct menu_item *mi = &menu->items[p];
int selected = (p == menu->selected); int selected = (p == menu->selected);
@ -588,23 +763,23 @@ display_menu(struct terminal *term, struct menu *menu)
if (selected) { if (selected) {
/* This entry is selected. */ /* This entry is selected. */
color = selected_color; color_node = selected_color_node;
set_cursor(term, box.x, box.y, 1); set_cursor(term, box.x, box.y, 1);
set_window_ptr(menu->win, menu->box.x + menu->box.width, box.y); set_window_ptr(menu->win, menu->box.x + menu->box.width, box.y);
draw_box(term, &box, ' ', 0, color); draw_box_node(term, &box, ' ', 0, color_node);
} }
if (mi_is_horizontal_bar(mi)) { if (mi_is_horizontal_bar(mi)) {
/* Horizontal separator */ /* Horizontal separator */
draw_border_char(term, menu->box.x, box.y, draw_border_char_node(term, menu->box.x, box.y,
BORDER_SRTEE, frame_color); BORDER_SRTEE, frame_color_node);
draw_box(term, &box, BORDER_SHLINE, draw_box_node(term, &box, BORDER_SHLINE,
SCREEN_ATTR_FRAME, frame_color); SCREEN_ATTR_FRAME, frame_color_node);
draw_border_char(term, box.x + box.width, box.y, draw_border_char_node(term, box.x + box.width, box.y,
BORDER_SLTEE, frame_color); BORDER_SLTEE, frame_color_node);
continue; continue;
} }
@ -620,29 +795,34 @@ display_menu(struct terminal *term, struct menu *menu)
l = 0; l = 0;
if (l) { if (l) {
draw_menu_left_text_hk(term, text, l, draw_menu_left_text_hk_node(term, text, l,
box.x, box.y, box.width, color, box.x, box.y, box.width, color_node,
selected); selected);
} else { } else {
draw_menu_left_text(term, text, -1, draw_menu_left_text_node(term, text, -1,
box.x, box.y, box.width, color); box.x, box.y, box.width, color_node);
} }
} }
if (mi_is_submenu(mi)) { if (mi_is_submenu(mi)) {
draw_menu_right_text(term, m_submenu, m_submenu_len, draw_menu_right_text_node(term, m_submenu, m_submenu_len,
menu->box.x, box.y, box.width, color); menu->box.x, box.y, box.width, color_node);
} else if (mi->action_id != ACT_MAIN_NONE) { } else if (mi->action_id != ACT_MAIN_NONE) {
struct string keystroke; struct string keystroke;
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
/* Help to detect action + right text. --Zas */ /* Help to detect action + right text. --Zas */
if (mi_has_right_text(mi)) { if (mi_has_right_text(mi)) {
if (color == selected_color) // if (color == selected_color)
color = normal_color; // color = normal_color;
// else
// color = selected_color;
if (color_node == selected_color_node)
color_node = normal_color_node;
else else
color = selected_color; color_node = selected_color_node;
} }
#endif /* CONFIG_DEBUG */ #endif /* CONFIG_DEBUG */
@ -650,10 +830,10 @@ display_menu(struct terminal *term, struct menu *menu)
add_keystroke_action_to_string(&keystroke, add_keystroke_action_to_string(&keystroke,
mi->action_id, mi->action_id,
KEYMAP_MAIN); KEYMAP_MAIN);
draw_menu_right_text(term, keystroke.source, draw_menu_right_text_node(term, keystroke.source,
keystroke.length, keystroke.length,
menu->box.x, box.y, menu->box.x, box.y,
box.width, color); box.width, color_node);
done_string(&keystroke); done_string(&keystroke);
} }
@ -665,9 +845,9 @@ display_menu(struct terminal *term, struct menu *menu)
if (*rtext) { if (*rtext) {
/* There's a right text, so print it */ /* There's a right text, so print it */
draw_menu_right_text(term, rtext, -1, draw_menu_right_text_node(term, rtext, -1,
menu->box.x, menu->box.x,
box.y, box.width, color); box.y, box.width, color_node);
} }
} }
} }
@ -1085,8 +1265,8 @@ do_mainmenu(struct terminal *term, struct menu_item *items,
static void static void
display_mainmenu(struct terminal *term, struct menu *menu) display_mainmenu(struct terminal *term, struct menu *menu)
{ {
struct color_pair *normal_color = get_bfu_color(term, "menu.normal"); unsigned int normal_color_node = get_bfu_color_node(term, "menu.normal");
struct color_pair *selected_color = get_bfu_color(term, "menu.selected"); unsigned int selected_color_node = get_bfu_color_node(term, "menu.selected");
int p = 0; int p = 0;
int i; int i;
struct el_box box; struct el_box box;
@ -1115,18 +1295,18 @@ display_mainmenu(struct terminal *term, struct menu *menu)
int_bounds(&menu->first, 0, menu->last); int_bounds(&menu->first, 0, menu->last);
set_box(&box, 0, 0, term->width, 1); set_box(&box, 0, 0, term->width, 1);
draw_box(term, &box, ' ', 0, normal_color); draw_box_node(term, &box, ' ', 0, normal_color_node);
if (menu->first != 0) { if (menu->first != 0) {
box.width = L_MAINMENU_SPACE; box.width = L_MAINMENU_SPACE;
draw_box(term, &box, '<', 0, normal_color); draw_box_node(term, &box, '<', 0, normal_color_node);
} }
p += L_MAINMENU_SPACE; p += L_MAINMENU_SPACE;
for (i = menu->first; i < menu->size; i++) { for (i = menu->first; i < menu->size; i++) {
struct menu_item *mi = &menu->items[i]; struct menu_item *mi = &menu->items[i];
struct color_pair *color = normal_color; unsigned int color_node = normal_color_node;
char *text = mi->text; char *text = mi->text;
int l = mi->hotkey_pos; int l = mi->hotkey_pos;
int textlen; int textlen;
@ -1145,7 +1325,7 @@ display_mainmenu(struct terminal *term, struct menu *menu)
screencnt = textlen; screencnt = textlen;
if (selected) { if (selected) {
color = selected_color; color_node = selected_color_node;
box.x = p; box.x = p;
#ifdef CONFIG_UTF8 #ifdef CONFIG_UTF8
if (term->utf8_cp) if (term->utf8_cp)
@ -1158,7 +1338,7 @@ display_mainmenu(struct terminal *term, struct menu *menu)
+ textlen + textlen
+ R_TEXT_SPACE + R_MAINTEXT_SPACE; + R_TEXT_SPACE + R_MAINTEXT_SPACE;
draw_box(term, &box, ' ', 0, color); draw_box_node(term, &box, ' ', 0, color_node);
set_cursor(term, p, 0, 1); set_cursor(term, p, 0, 1);
set_window_ptr(menu->win, p, 1); set_window_ptr(menu->win, p, 1);
} }
@ -1166,13 +1346,13 @@ display_mainmenu(struct terminal *term, struct menu *menu)
p += L_MAINTEXT_SPACE; p += L_MAINTEXT_SPACE;
if (l) { if (l) {
draw_menu_left_text_hk(term, text, l, draw_menu_left_text_hk_node(term, text, l,
p, 0, textlen + R_TEXT_SPACE + L_TEXT_SPACE, p, 0, textlen + R_TEXT_SPACE + L_TEXT_SPACE,
color, selected); color_node, selected);
} else { } else {
draw_menu_left_text(term, text, textlen, draw_menu_left_text_node(term, text, textlen,
p, 0, textlen + R_TEXT_SPACE + L_TEXT_SPACE, p, 0, textlen + R_TEXT_SPACE + L_TEXT_SPACE,
color); color_node);
} }
p += screencnt; p += screencnt;
@ -1205,7 +1385,7 @@ display_mainmenu(struct terminal *term, struct menu *menu)
set_box(&box, set_box(&box,
term->width - R_MAINMENU_SPACE, 0, term->width - R_MAINMENU_SPACE, 0,
R_MAINMENU_SPACE, 1); R_MAINMENU_SPACE, 1);
draw_box(term, &box, '>', 0, normal_color); draw_box_node(term, &box, '>', 0, normal_color_node);
} }
redraw_windows(REDRAW_IN_FRONT_OF_WINDOW, menu->win); redraw_windows(REDRAW_IN_FRONT_OF_WINDOW, menu->win);