diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2022-04-18 09:52:01 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2022-04-18 09:52:01 +0200 |
commit | 674f52bf5867791059988af02089f3a8b82eeb98 (patch) | |
tree | 34f4b825c00cc9abc4171620cd5155c3e024203c /src | |
parent | 0af960dbde56d5d950997250acd4e53eb16223a5 (diff) | |
download | weechat-674f52bf5867791059988af02089f3a8b82eeb98.zip |
core: add bar item "spacer"
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/curses/gui-curses-bar-window.c | 165 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-chat.c | 1 | ||||
-rw-r--r-- | src/gui/gui-bar-item.c | 37 | ||||
-rw-r--r-- | src/gui/gui-bar-item.h | 1 | ||||
-rw-r--r-- | src/gui/gui-bar-window.c | 111 | ||||
-rw-r--r-- | src/gui/gui-bar-window.h | 7 | ||||
-rw-r--r-- | src/gui/gui-color.c | 3 | ||||
-rw-r--r-- | src/gui/gui-color.h | 1 |
8 files changed, 302 insertions, 24 deletions
diff --git a/src/gui/curses/gui-curses-bar-window.c b/src/gui/curses/gui-curses-bar-window.c index e3bc5b55b..6b2ba74be 100644 --- a/src/gui/curses/gui-curses-bar-window.c +++ b/src/gui/curses/gui-curses-bar-window.c @@ -300,6 +300,9 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, *x + bar_window->x, *y + bar_window->y); break; + case GUI_COLOR_BAR_SPACER: + string += 2; + break; default: string++; break; @@ -407,6 +410,115 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, } /* + * Expands spacers using the sizes computed, replacing them by 0 to N spaces. + * + * Note: result must be freed after use. + */ + +char * +gui_bar_window_expand_spacers (const char *string, int length_on_screen, + int bar_window_width, int num_spacers) +{ + int *spacers, index_spacer, i; + char **result, *result2, *next_char; + + if (!string || !string[0]) + return NULL; + + spacers = gui_bar_window_compute_spacers_size (length_on_screen, + bar_window_width, + num_spacers); + if (!spacers) + return NULL; + + result = string_dyn_alloc (256); + if (!result) + { + free (spacers); + return NULL; + } + + index_spacer = 0; + + while (string && string[0]) + { + switch (string[0]) + { + case GUI_COLOR_COLOR_CHAR: + switch (string[1]) + { + case GUI_COLOR_FG_CHAR: + case GUI_COLOR_BG_CHAR: + case GUI_COLOR_FG_BG_CHAR: + case GUI_COLOR_EXTENDED_CHAR: + case GUI_COLOR_EMPHASIS_CHAR: + case GUI_COLOR_RESET_CHAR: + string_dyn_concat (result, string, 2); + string += 2; + break; + case GUI_COLOR_BAR_CHAR: + switch (string[2]) + { + case GUI_COLOR_BAR_FG_CHAR: + case GUI_COLOR_BAR_DELIM_CHAR: + case GUI_COLOR_BAR_BG_CHAR: + case GUI_COLOR_BAR_START_INPUT_CHAR: + case GUI_COLOR_BAR_START_INPUT_HIDDEN_CHAR: + case GUI_COLOR_BAR_MOVE_CURSOR_CHAR: + case GUI_COLOR_BAR_START_ITEM: + case GUI_COLOR_BAR_START_LINE_ITEM: + string_dyn_concat (result, string, 3); + string += 3; + break; + case GUI_COLOR_BAR_SPACER: + if (index_spacer < num_spacers) + { + for (i = 0; i < spacers[index_spacer]; i++) + { + string_dyn_concat (result, " ", 1); + } + } + index_spacer++; + string += 3; + break; + default: + string_dyn_concat (result, string, 2); + string += 2; + break; + } + break; + default: + string_dyn_concat (result, string, 1); + string++; + break; + } + break; + case GUI_COLOR_SET_ATTR_CHAR: + case GUI_COLOR_REMOVE_ATTR_CHAR: + case GUI_COLOR_RESET_CHAR: + string_dyn_concat (result, string, 1); + string++; + break; + default: + next_char = (char *)utf8_next_char (string); + if (!next_char) + break; + string_dyn_concat (result, string, next_char - string); + string = next_char; + break; + } + } + + free (spacers); + + result2 = *result; + + string_dyn_free (result, 0); + + return result2; +} + +/* * Draws a bar for a window. */ @@ -414,16 +526,16 @@ void gui_bar_window_draw (struct t_gui_bar_window *bar_window, struct t_gui_window *window) { - int x, y, items_count, num_lines, line, color_bg; - enum t_gui_bar_filling filling; - char *content, **items; + int x, y, items_count, num_lines, line, color_bg, bar_position, bar_size; + enum t_gui_bar_filling bar_filling; + char *content, *content2, **items; static char str_start_input[16] = { '\0' }; static char str_start_input_hidden[16] = { '\0' }; static char str_cursor[16] = { '\0' }; char *pos_start_input, *pos_after_start_input, *pos_cursor, *buf; char *new_start_input, *ptr_string; static int length_start_input, length_start_input_hidden; - int length_on_screen; + int num_spacers, length_on_screen; int chars_available, index, size; int length_screen_before_cursor, length_screen_after_cursor; int diff, max_length, optimal_number_of_lines; @@ -478,16 +590,31 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, gui_window_current_emphasis = 0; - filling = gui_bar_get_filling (bar_window->bar); + bar_position = CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_POSITION]); + bar_filling = gui_bar_get_filling (bar_window->bar); + bar_size = CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]); - content = gui_bar_window_content_get_with_filling (bar_window, window); + content = gui_bar_window_content_get_with_filling (bar_window, window, + &num_spacers); if (content) { utf8_normalize (content, '?'); - if ((filling == GUI_BAR_FILLING_HORIZONTAL) + length_on_screen = gui_chat_strlen_screen (content); + if ((num_spacers > 0) && gui_bar_window_can_use_spacer (bar_window)) + { + content2 = gui_bar_window_expand_spacers (content, + length_on_screen, + bar_window->width, + num_spacers); + if (content2) + { + free (content); + content = content2; + } + } + if ((bar_filling == GUI_BAR_FILLING_HORIZONTAL) && (bar_window->scroll_x > 0)) { - length_on_screen = gui_chat_strlen_screen (content); if (bar_window->scroll_x > length_on_screen - bar_window->width) { bar_window->scroll_x = length_on_screen - bar_window->width; @@ -502,7 +629,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, 0, &items_count); if (items_count == 0) { - if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]) == 0) + if (bar_size == 0) gui_bar_window_set_current_size (bar_window, window, 1); gui_window_clear (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar, CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]), @@ -511,7 +638,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, else { /* bar with auto size ? then compute new size, according to content */ - if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]) == 0) + if (bar_size == 0) { /* search longer line and optimal number of lines */ max_length = 0; @@ -538,11 +665,11 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, if (max_length == 0) max_length = 1; - switch (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_POSITION])) + switch (bar_position) { case GUI_BAR_POSITION_BOTTOM: case GUI_BAR_POSITION_TOP: - if (filling == GUI_BAR_FILLING_HORIZONTAL) + if (bar_filling == GUI_BAR_FILLING_HORIZONTAL) num_lines = optimal_number_of_lines; else num_lines = items_count; @@ -656,7 +783,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, { if (!gui_bar_window_print_string (bar_window, window, - filling, + bar_filling, &x, &y, items[line], 1, 1, &index_item, @@ -668,7 +795,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, if (x < bar_window->width) { - if (filling == GUI_BAR_FILLING_HORIZONTAL) + if (bar_filling == GUI_BAR_FILLING_HORIZONTAL) { gui_window_set_custom_color_fg_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar, CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]), @@ -687,7 +814,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, { gui_bar_window_print_string (bar_window, window, - filling, + bar_filling, &x, &y, " ", 0, 0, &index_item, &index_subitem, @@ -702,7 +829,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, if ((bar_window->cursor_x < 0) && (bar_window->cursor_y < 0) && ((bar_window->scroll_x > 0) || (bar_window->scroll_y > 0))) { - if (filling == GUI_BAR_FILLING_HORIZONTAL) + if (bar_filling == GUI_BAR_FILLING_HORIZONTAL) { ptr_string = CONFIG_STRING(config_look_bar_more_left); x = 0; @@ -728,7 +855,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, if ((bar_window->cursor_x < 0) && (bar_window->cursor_y < 0) && (some_data_not_displayed || (line < items_count))) { - ptr_string = (filling == GUI_BAR_FILLING_HORIZONTAL) ? + ptr_string = (bar_filling == GUI_BAR_FILLING_HORIZONTAL) ? CONFIG_STRING(config_look_bar_more_right) : CONFIG_STRING(config_look_bar_more_down); x = bar_window->width - utf8_strlen_screen (ptr_string); @@ -752,7 +879,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, } else { - if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]) == 0) + if (bar_size == 0) gui_bar_window_set_current_size (bar_window, window, 1); gui_window_clear (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar, CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]), @@ -784,7 +911,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SEPARATOR])) { - switch (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_POSITION])) + switch (bar_position) { case GUI_BAR_POSITION_BOTTOM: gui_window_set_weechat_color (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator, diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c index a7776e491..5ad362bbc 100644 --- a/src/gui/curses/gui-curses-chat.c +++ b/src/gui/curses/gui-curses-chat.c @@ -292,6 +292,7 @@ gui_chat_string_next_char (struct t_gui_window *window, struct t_gui_line *line, case GUI_COLOR_BAR_MOVE_CURSOR_CHAR: case GUI_COLOR_BAR_START_ITEM: case GUI_COLOR_BAR_START_LINE_ITEM: + case GUI_COLOR_BAR_SPACER: string++; break; } diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c index 75d576c45..758d34702 100644 --- a/src/gui/gui-bar-item.c +++ b/src/gui/gui-bar-item.c @@ -63,7 +63,8 @@ char *gui_bar_item_names[GUI_BAR_NUM_ITEMS] = "buffer_name", "buffer_short_name", "buffer_modes", "buffer_filter", "buffer_zoom", "buffer_nicklist_count", "buffer_nicklist_count_groups", "buffer_nicklist_count_all", "scroll", "hotlist", "completion", - "buffer_title", "buffer_nicklist", "window_number", "mouse_status", "away" + "buffer_title", "buffer_nicklist", "window_number", "mouse_status", "away", + "spacer" }; char *gui_bar_items_default_for_bars[][2] = { { GUI_BAR_DEFAULT_NAME_INPUT, @@ -1989,6 +1990,35 @@ gui_bar_item_away_cb (const void *pointer, void *data, } /* + * Bar item with spacer. + */ + +char * +gui_bar_item_spacer_cb (const void *pointer, void *data, + struct t_gui_bar_item *item, + struct t_gui_window *window, + struct t_gui_buffer *buffer, + struct t_hashtable *extra_info) +{ + char str_spacer[16]; + + /* make C compiler happy */ + (void) pointer; + (void) data; + (void) item; + (void) window; + (void) buffer; + (void) extra_info; + + snprintf (str_spacer, sizeof (str_spacer), "%c%c%c", + GUI_COLOR_COLOR_CHAR, + GUI_COLOR_BAR_CHAR, + GUI_COLOR_BAR_SPACER); + + return strdup (str_spacer); +} + +/* * Focus on nicklist. */ @@ -2436,6 +2466,11 @@ gui_bar_item_init () &gui_bar_item_away_cb, NULL, NULL); gui_bar_item_hook_signal ("buffer_localvar_*", gui_bar_item_names[GUI_BAR_ITEM_AWAY]); + + /* spacer */ + gui_bar_item_new (NULL, + gui_bar_item_names[GUI_BAR_ITEM_SPACER], + &gui_bar_item_spacer_cb, NULL, NULL); } /* diff --git a/src/gui/gui-bar-item.h b/src/gui/gui-bar-item.h index 822cfb1d0..fc8dda3bf 100644 --- a/src/gui/gui-bar-item.h +++ b/src/gui/gui-bar-item.h @@ -47,6 +47,7 @@ enum t_gui_bar_item_weechat GUI_BAR_ITEM_WINDOW_NUMBER, GUI_BAR_ITEM_MOUSE_STATUS, GUI_BAR_ITEM_AWAY, + GUI_BAR_ITEM_SPACER, /* number of bar items */ GUI_BAR_NUM_ITEMS, }; diff --git a/src/gui/gui-bar-window.c b/src/gui/gui-bar-window.c index f87ee210b..a5a943c9d 100644 --- a/src/gui/gui-bar-window.c +++ b/src/gui/gui-bar-window.c @@ -668,15 +668,37 @@ gui_bar_window_content_get (struct t_gui_bar_window *bar_window, } /* + * Checks if the item content is a spacer (bar item "spacer"). + * + * Returns: + * 1: item is a spacer + * 1: item is not a spacer + */ + +int +gui_bar_window_item_is_spacer (const char *item) +{ + return (item + && (item[0] == GUI_COLOR_COLOR_CHAR) + && (item[1] == GUI_COLOR_BAR_CHAR) + && (item[2] == GUI_COLOR_BAR_SPACER) + && !item[3]); +} + +/* * Gets content of a bar window, formatted for display, according to filling * for bar position. * + * The integer variable *num_spacers is set with the number of spacers found + * (bar item "spacer"). + * * Note: result must be freed after use. */ char * gui_bar_window_content_get_with_filling (struct t_gui_bar_window *bar_window, - struct t_gui_window *window) + struct t_gui_window *window, + int *num_spacers) { enum t_gui_bar_filling filling; const char *ptr_content; @@ -689,6 +711,9 @@ gui_bar_window_content_get_with_filling (struct t_gui_bar_window *bar_window, int length_reinit_color, length_reinit_color_space, length_start_item; int length, max_length, max_length_screen; int total_items, columns, lines; + int item_is_spacer; + + *num_spacers = 0; if (!bar_window || !bar_window->items_subcount || !bar_window->items_content @@ -757,7 +782,10 @@ gui_bar_window_content_get_with_filling (struct t_gui_bar_window *bar_window, { item_value = NULL; } - if (at_least_one_item && first_sub_item) + item_is_spacer = gui_bar_window_item_is_spacer ( + (item_value) ? item_value : ptr_content); + if (at_least_one_item && first_sub_item + && !item_is_spacer) { /* first sub item: insert space after last item */ if (filling == GUI_BAR_FILLING_HORIZONTAL) @@ -788,7 +816,10 @@ gui_bar_window_content_get_with_filling (struct t_gui_bar_window *bar_window, first_sub_item = 0; if (item_value) free (item_value); - at_least_one_item = 1; + if (item_is_spacer) + (*num_spacers)++; + else + at_least_one_item = 1; } else { @@ -963,6 +994,80 @@ gui_bar_window_content_get_with_filling (struct t_gui_bar_window *bar_window, } /* + * Checks if spacer can be used in the bar according to its position, filling + * and size. + * + * Returns: + * 1: spacers can be used + * 0: spacers can not be used + */ + +int +gui_bar_window_can_use_spacer (struct t_gui_bar_window *bar_window) +{ + int position, filling, bar_size; + int pos_ok, filling_ok, size_ok; + + if (!bar_window) + return 0; + + position = CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_POSITION]); + filling = gui_bar_get_filling (bar_window->bar); + bar_size = CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]); + + pos_ok = ((position == GUI_BAR_POSITION_TOP) + || (position == GUI_BAR_POSITION_BOTTOM)); + filling_ok = (filling == GUI_BAR_FILLING_HORIZONTAL); + size_ok = (bar_size == 1); + + return pos_ok && filling_ok && size_ok; +} + +/* + * Computes size of each spacer in the bar. + * + * Note: result must be freed after use. + */ + +int * +gui_bar_window_compute_spacers_size (int length_on_screen, + int bar_window_width, + int num_spacers) +{ + int *spacers, spacer_size, i; + + if ((length_on_screen < 0) || (bar_window_width < 1) || (num_spacers <= 0)) + return NULL; + + /* if not enough space for spacers, ignore them all */ + if (length_on_screen >= bar_window_width) + return NULL; + + spacers = malloc (num_spacers * sizeof (spacers[0])); + if (!spacers) + return NULL; + + spacer_size = (bar_window_width - length_on_screen) / num_spacers; + + for (i = 0; i < num_spacers; i++) + { + spacers[i] = spacer_size; + } + + length_on_screen += num_spacers * spacer_size; + + i = 0; + while ((length_on_screen < bar_window_width) && (i < num_spacers)) + { + spacers[i]++; + i++; + length_on_screen++; + } + + return spacers; +} + +/* * Adds coordinates (item index/subindex and x,y). */ diff --git a/src/gui/gui-bar-window.h b/src/gui/gui-bar-window.h index 37b1fbc39..4813e63c1 100644 --- a/src/gui/gui-bar-window.h +++ b/src/gui/gui-bar-window.h @@ -77,7 +77,12 @@ extern void gui_bar_window_calculate_pos_size (struct t_gui_bar_window *bar_wind extern void gui_bar_window_content_build (struct t_gui_bar_window *bar_window, struct t_gui_window *window); extern char *gui_bar_window_content_get_with_filling (struct t_gui_bar_window *bar_window, - struct t_gui_window *window); + struct t_gui_window *window, + int *num_spacers); +extern int gui_bar_window_can_use_spacer (struct t_gui_bar_window *bar_window); +extern int *gui_bar_window_compute_spacers_size (int length_on_screen, + int bar_window_width, + int num_spacers); extern struct t_gui_bar_window *gui_bar_window_search_bar (struct t_gui_window *window, struct t_gui_bar *bar); extern int gui_bar_window_get_current_size (struct t_gui_bar_window *bar_window); diff --git a/src/gui/gui-color.c b/src/gui/gui-color.c index a4557ac57..1bd0aca63 100644 --- a/src/gui/gui-color.c +++ b/src/gui/gui-color.c @@ -707,6 +707,7 @@ gui_color_code_size (const char *string) case GUI_COLOR_BAR_MOVE_CURSOR_CHAR: case GUI_COLOR_BAR_START_ITEM: case GUI_COLOR_BAR_START_LINE_ITEM: + case GUI_COLOR_BAR_SPACER: ptr_string++; break; } @@ -892,6 +893,7 @@ gui_color_decode (const char *string, const char *replacement) case GUI_COLOR_BAR_MOVE_CURSOR_CHAR: case GUI_COLOR_BAR_START_ITEM: case GUI_COLOR_BAR_START_LINE_ITEM: + case GUI_COLOR_BAR_SPACER: ptr_string++; break; } @@ -1518,6 +1520,7 @@ gui_color_encode_ansi (const char *string) case GUI_COLOR_BAR_MOVE_CURSOR_CHAR: case GUI_COLOR_BAR_START_ITEM: case GUI_COLOR_BAR_START_LINE_ITEM: + case GUI_COLOR_BAR_SPACER: ptr_string++; break; } diff --git a/src/gui/gui-color.h b/src/gui/gui-color.h index 50e78d018..799fd76bd 100644 --- a/src/gui/gui-color.h +++ b/src/gui/gui-color.h @@ -134,6 +134,7 @@ enum t_gui_color_enum #define GUI_COLOR_BAR_MOVE_CURSOR_CHAR '#' #define GUI_COLOR_BAR_START_ITEM 'i' #define GUI_COLOR_BAR_START_LINE_ITEM 'l' +#define GUI_COLOR_BAR_SPACER 's' #define GUI_COLOR_EXTENDED_FLAG 0x0100000 #define GUI_COLOR_EXTENDED_BOLD_FLAG 0x0200000 |