diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2008-07-03 16:02:03 +0200 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2008-07-03 16:02:03 +0200 |
commit | b97a979f611c0ece7fd26f9c303394d2ee9d0b0e (patch) | |
tree | 26474a3c486c3bd2a69a5bc3ea2b9aaf962bd3bf /src/gui/curses/gui-curses-bar.c | |
parent | 31f9a82f1628212a3b43678c23e9828eede46911 (diff) | |
download | weechat-b97a979f611c0ece7fd26f9c303394d2ee9d0b0e.zip |
Add "buffer_nicklist" bar item and scroll feature in bars with /bar scroll
Diffstat (limited to 'src/gui/curses/gui-curses-bar.c')
-rw-r--r-- | src/gui/curses/gui-curses-bar.c | 381 |
1 files changed, 362 insertions, 19 deletions
diff --git a/src/gui/curses/gui-curses-bar.c b/src/gui/curses/gui-curses-bar.c index 22e681d3b..8aacb980c 100644 --- a/src/gui/curses/gui-curses-bar.c +++ b/src/gui/curses/gui-curses-bar.c @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <limits.h> #include "../../core/weechat.h" #include "../../core/wee-config.h" @@ -146,6 +147,80 @@ gui_bar_window_get_size (struct t_gui_bar *bar, struct t_gui_window *window, } /* + * gui_bar_get_min_width: return minimum width of a bar window displayed for + * a bar + * for example, if a bar is displayed in 3 windows, + * this function return min width of these 3 bar windows + */ + +int +gui_bar_get_min_width (struct t_gui_bar *bar) +{ + struct t_gui_window *ptr_win; + struct t_gui_bar_window *ptr_bar_win; + int min_width; + + if (CONFIG_INTEGER(bar->type) == GUI_BAR_TYPE_ROOT) + return bar->bar_window->width; + + min_width = INT_MAX; + for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) + { + for (ptr_bar_win = GUI_CURSES(ptr_win)->bar_windows; + ptr_bar_win; ptr_bar_win = ptr_bar_win->next_bar_window) + { + if (ptr_bar_win->bar == bar) + { + if (ptr_bar_win->width < min_width) + min_width = ptr_bar_win->width; + } + } + } + + if (min_width == INT_MAX) + return 0; + + return min_width; +} + +/* + * gui_bar_get_min_height: return minimum height of a bar window displayed for + * a bar + * for example, if a bar is displayed in 3 windows, + * this function return min width of these 3 bar windows + */ + +int +gui_bar_get_min_height (struct t_gui_bar *bar) +{ + struct t_gui_window *ptr_win; + struct t_gui_bar_window *ptr_bar_win; + int min_height; + + if (CONFIG_INTEGER(bar->type) == GUI_BAR_TYPE_ROOT) + return bar->bar_window->height; + + min_height = INT_MAX; + for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) + { + for (ptr_bar_win = GUI_CURSES(ptr_win)->bar_windows; + ptr_bar_win; ptr_bar_win = ptr_bar_win->next_bar_window) + { + if (ptr_bar_win->bar == bar) + { + if (ptr_bar_win->height < min_height) + min_height = ptr_bar_win->height; + } + } + } + + if (min_height == INT_MAX) + return 0; + + return min_height; +} + +/* * gui_bar_check_size_add: check if "add_size" is ok for bar * return 1 if new size is ok * 0 if new size is too big @@ -401,6 +476,8 @@ gui_bar_window_new (struct t_gui_bar *bar, struct t_gui_window *window) new_bar_window->y = 0; new_bar_window->width = 1; new_bar_window->height = 1; + new_bar_window->scroll_x = 0; + new_bar_window->scroll_y = 0; new_bar_window->cursor_x = -1; new_bar_window->cursor_y = -1; new_bar_window->current_size = (CONFIG_INTEGER(bar->size) == 0) ? @@ -579,9 +656,12 @@ gui_bar_window_add_missing_bars (struct t_gui_window *window) /* * gui_bar_window_print_string: print a string text on a bar window + * return 1 if all was printed, 0 if some text + * was not displayed (wrapped due to bar window + * width) */ -void +int gui_bar_window_print_string (struct t_gui_bar_window *bar_window, int *x, int *y, const char *string) @@ -590,7 +670,7 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, char str_fg[3], str_bg[3], utf_char[16], *next_char, *output; if (!string || !string[0]) - return; + return 1; wmove (bar_window->win_bar, *y, *x); @@ -710,9 +790,9 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, if (*x + size_on_screen > bar_window->width) { if (CONFIG_INTEGER(bar_window->bar->filling) == GUI_BAR_FILLING_VERTICAL) - return; + return 0; if (*y >= bar_window->height - 1) - return; + return 0; *x = 0; (*y)++; wmove (bar_window->win_bar, *y, *x); @@ -728,6 +808,7 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, string = next_char; } } + return 1; } /* @@ -743,6 +824,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, char space_with_reinit_color[32]; int length_reinit_color, content_length, length, length_on_screen; int max_length, optimal_number_of_lines, chars_available; + int some_data_not_displayed; if (!gui_init_ok) return; @@ -877,18 +959,60 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, CONFIG_COLOR(bar_window->bar->color_bg)); x = 0; y = 0; + some_data_not_displayed = 0; + if ((bar_window->scroll_y > 0) + && (bar_window->scroll_y >= items_count)) + { + bar_window->scroll_y = items_count - bar_window->height; + if (bar_window->scroll_y < 0) + bar_window->scroll_y = 0; + } for (line = 0; (line < items_count) && (y < bar_window->height); line++) { - gui_bar_window_print_string (bar_window, &x, &y, - items[line]); - if (CONFIG_INTEGER(bar_window->bar->filling) == GUI_BAR_FILLING_VERTICAL) + if ((bar_window->scroll_y == 0) + || (line >= bar_window->scroll_y)) { - x = 0; - y++; + if (!gui_bar_window_print_string (bar_window, &x, &y, + items[line])) + { + some_data_not_displayed = 1; + } + if (CONFIG_INTEGER(bar_window->bar->filling) == GUI_BAR_FILLING_VERTICAL) + { + x = 0; + y++; + } + else + { + gui_bar_window_print_string (bar_window, &x, &y, + space_with_reinit_color); + } } } + if (bar_window->scroll_y > 0) + { + x = (bar_window->height > 1) ? bar_window->width - 2 : 0; + if (x < 0) + x = 0; + y = 0; + gui_window_set_custom_color_fg_bg (bar_window->win_bar, + CONFIG_COLOR(config_color_bar_more), + CONFIG_INTEGER(bar_window->bar->color_bg)); + mvwprintw (bar_window->win_bar, y, x, "--"); + } + if (some_data_not_displayed || (line < items_count)) + { + x = bar_window->width - 2; + if (x < 0) + x = 0; + y = (bar_window->height > 1) ? bar_window->height - 1 : 0; + gui_window_set_custom_color_fg_bg (bar_window->win_bar, + CONFIG_COLOR(config_color_bar_more), + CONFIG_INTEGER(bar_window->bar->color_bg)); + mvwprintw (bar_window->win_bar, y, x, "++"); + } } if (items) string_free_exploded (items); @@ -936,23 +1060,60 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, item_value2 : item_value, "\n", 0, 0, &items_count); + some_data_not_displayed = 0; + if ((bar_window->scroll_y > 0) + && (bar_window->scroll_y >= items_count)) + { + bar_window->scroll_y = items_count - bar_window->height; + if (bar_window->scroll_y < 0) + bar_window->scroll_y = 0; + } for (line = 0; (line < items_count) && (y < bar_window->height); line++) { - gui_bar_window_print_string (bar_window, &x, &y, - items[line]); - if (CONFIG_INTEGER(bar_window->bar->filling) == GUI_BAR_FILLING_VERTICAL) + if ((bar_window->scroll_y == 0) + || (line >= bar_window->scroll_y)) { - x = 0; - y++; - } - else - { - gui_bar_window_print_string (bar_window, &x, &y, - space_with_reinit_color); + if (!gui_bar_window_print_string (bar_window, &x, &y, + items[line])) + { + some_data_not_displayed = 1; + } + if (CONFIG_INTEGER(bar_window->bar->filling) == GUI_BAR_FILLING_VERTICAL) + { + x = 0; + y++; + } + else + { + gui_bar_window_print_string (bar_window, &x, &y, + space_with_reinit_color); + } } } + if (bar_window->scroll_y > 0) + { + x = (bar_window->height > 1) ? bar_window->width - 2 : 0; + if (x < 0) + x = 0; + y = 0; + gui_window_set_custom_color_fg_bg (bar_window->win_bar, + CONFIG_COLOR(config_color_bar_more), + CONFIG_INTEGER(bar_window->bar->color_bg)); + mvwprintw (bar_window->win_bar, y, x, "--"); + } + if (some_data_not_displayed || (line < items_count)) + { + x = bar_window->width - 2; + if (x < 0) + x = 0; + y = (bar_window->height > 1) ? bar_window->height - 1 : 0; + gui_window_set_custom_color_fg_bg (bar_window->win_bar, + CONFIG_COLOR(config_color_bar_more), + CONFIG_INTEGER(bar_window->bar->color_bg)); + mvwprintw (bar_window->win_bar, y, x, "++"); + } if (item_value2) free (item_value2); if (items) @@ -1046,6 +1207,186 @@ gui_bar_draw (struct t_gui_bar *bar) } /* + * gui_bar_window_scroll: scroll a bar window with a value + * if add == 1, then value is added (otherwise subtracted) + * if add_x == 1, then value is added to scroll_x (otherwise scroll_y) + * if percent == 1, then value is a percentage (otherwise number of chars) + */ + +void +gui_bar_window_scroll (struct t_gui_bar_window *bar_window, + struct t_gui_window *window, + int add_x, int scroll_beginning, int scroll_end, + int add, int percent, int value) +{ + int old_scroll_x, old_scroll_y; + + old_scroll_x = bar_window->scroll_x; + old_scroll_y = bar_window->scroll_y; + + if (scroll_beginning) + { + if (add_x) + bar_window->scroll_x = 0; + else + bar_window->scroll_y = 0; + } + else if (scroll_end) + { + if (add_x) + bar_window->scroll_x = INT_MAX; + else + bar_window->scroll_y = INT_MAX; + } + else + { + if (percent) + { + if (add_x) + value = (bar_window->width * value) / 100; + else + value = (bar_window->height * value) / 100; + if (value == 0) + value = 1; + } + if (add) + { + if (add_x) + bar_window->scroll_x += value; + else + bar_window->scroll_y += value; + } + else + { + if (add_x) + bar_window->scroll_x -= value; + else + bar_window->scroll_y -= value; + } + } + + if (bar_window->scroll_x < 0) + bar_window->scroll_x = 0; + + if (bar_window->scroll_y < 0) + bar_window->scroll_y = 0; + + /* refresh only if scroll has changed (X and/or Y) */ + if ((old_scroll_x != bar_window->scroll_x) + || (old_scroll_y != bar_window->scroll_y)) + { + gui_bar_window_draw (bar_window, window); + } +} + +/* + * gui_bar_scroll: scroll a bar for a buffer + * return 1 if scroll is ok, 0 if error + */ + +int +gui_bar_scroll (struct t_gui_bar *bar, struct t_gui_buffer *buffer, + const char *scroll) +{ + struct t_gui_window *ptr_win; + struct t_gui_bar_window *ptr_bar_win; + long number; + char *str, *error; + int length, add_x, add, percent, scroll_beginning, scroll_end; + + add_x = 0; + str = NULL; + number = 0; + add = 0; + percent = 0; + scroll_beginning = 0; + scroll_end = 0; + + if ((scroll[0] == 'x') || (scroll[0] == 'X')) + { + add_x = 1; + scroll++; + } + else if ((scroll[0] == 'y') || (scroll[0] == 'Y')) + { + scroll++; + } + else + return 0; + + if ((scroll[0] == 'b') || (scroll[0] == 'B')) + { + scroll_beginning = 1; + } + else if ((scroll[0] == 'e') || (scroll[0] == 'E')) + { + scroll_end = 1; + } + else + { + if (scroll[0] == '+') + { + add = 1; + scroll++; + } + else if (scroll[0] == '-') + { + scroll++; + } + else + return 0; + + length = strlen (scroll); + if (length == 0) + return 0; + + if (scroll[length - 1] == '%') + { + str = string_strndup (scroll, length - 1); + percent = 1; + } + else + str = strdup (scroll); + if (!str) + return 0; + + error = NULL; + number = strtol (str, &error, 10); + + if (!error || error[0] || (number <= 0)) + { + free (str); + return 0; + } + } + + if (CONFIG_INTEGER(bar->type) == GUI_BAR_TYPE_ROOT) + gui_bar_window_scroll (bar->bar_window, NULL, + add_x, scroll_beginning, scroll_end, + add, percent, number); + else + { + for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) + { + if (ptr_win->buffer == buffer) + { + for (ptr_bar_win = GUI_CURSES(ptr_win)->bar_windows; + ptr_bar_win; ptr_bar_win = ptr_bar_win->next_bar_window) + { + gui_bar_window_scroll (ptr_bar_win, ptr_win, + add_x, scroll_beginning, scroll_end, + add, percent, number); + } + } + } + } + + free (str); + + return 1; +} + +/* * gui_bar_window_print_log: print bar window infos in log (usually for crash dump) */ @@ -1059,6 +1400,8 @@ gui_bar_window_print_log (struct t_gui_bar_window *bar_window) log_printf (" y . . . . . . . . : %d", bar_window->y); log_printf (" width . . . . . . : %d", bar_window->width); log_printf (" height. . . . . . : %d", bar_window->height); + log_printf (" scroll_x. . . . . : %d", bar_window->scroll_x); + log_printf (" scroll_y. . . . . : %d", bar_window->scroll_y); log_printf (" cursor_x. . . . . : %d", bar_window->cursor_x); log_printf (" cursor_y. . . . . : %d", bar_window->cursor_y); log_printf (" current_size. . . : %d", bar_window->current_size); |