summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2022-04-18 09:52:01 +0200
committerSébastien Helleu <flashcode@flashtux.org>2022-04-18 09:52:01 +0200
commit674f52bf5867791059988af02089f3a8b82eeb98 (patch)
tree34f4b825c00cc9abc4171620cd5155c3e024203c /src
parent0af960dbde56d5d950997250acd4e53eb16223a5 (diff)
downloadweechat-674f52bf5867791059988af02089f3a8b82eeb98.zip
core: add bar item "spacer"
Diffstat (limited to 'src')
-rw-r--r--src/gui/curses/gui-curses-bar-window.c165
-rw-r--r--src/gui/curses/gui-curses-chat.c1
-rw-r--r--src/gui/gui-bar-item.c37
-rw-r--r--src/gui/gui-bar-item.h1
-rw-r--r--src/gui/gui-bar-window.c111
-rw-r--r--src/gui/gui-bar-window.h7
-rw-r--r--src/gui/gui-color.c3
-rw-r--r--src/gui/gui-color.h1
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