Mercurial > pidgin
diff console/libgnt/gntwm.c @ 15741:50c25be2563b
Better handle large windows that don't fit into the screen (eg. the preference
window when we add more prefs there). The default binding for scrolling in such
a window are, for the moment, alt-ctrl-l and alt-ctrl-k.
Things still to be done:
* Give a clear onscreen indication that there is more to the window than meets the eye.
* Update the scrolling when the window is resized.
* Use some better binding.
* Update the manual.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Tue, 27 Feb 2007 09:06:05 +0000 |
parents | 73219517f583 |
children | 909e59dae123 |
line wrap: on
line diff
--- a/console/libgnt/gntwm.c Tue Feb 27 04:58:18 2007 +0000 +++ b/console/libgnt/gntwm.c Tue Feb 27 09:06:05 2007 +0000 @@ -119,6 +119,20 @@ wrefresh(taskbar); } + +static void +copy_win(GntWidget *widget, GntNode *node) +{ + WINDOW *src, *dst; + int shadow; + if (!node) + return; + src = widget->window; + dst = node->window; + shadow = gnt_widget_has_shadow(widget) ? 1 : 0; + copywin(src, dst, node->scroll, 0, 0, 0, getmaxy(dst) - 1, getmaxx(dst) - 1, 0); +} + static gboolean update_screen(GntWM *wm) { @@ -337,6 +351,55 @@ } return TRUE; } + +static gboolean +window_scroll_up(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *window; + GntNode *node; + int w, h; + + if (!wm->ordered) + return TRUE; + + window = wm->ordered->data; + node = g_hash_table_lookup(wm->nodes, window); + if (!node) + return TRUE; + + if (node->scroll) { + node->scroll--; + copy_win(window, node); + update_screen(wm); + } +} + +static gboolean +window_scroll_down(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *window; + GntNode *node; + int w, h; + + if (!wm->ordered) + return TRUE; + + window = wm->ordered->data; + node = g_hash_table_lookup(wm->nodes, window); + if (!node) + return TRUE; + + gnt_widget_get_size(window, &w, &h); + if (h - node->scroll > getmaxy(node->window)) { + node->scroll++; + copy_win(window, node); + update_screen(wm); + } + return TRUE; +} + static gboolean window_close(GntBindable *bindable, GList *null) { @@ -718,7 +781,7 @@ } static void -window_reverse(GntWidget *win, gboolean set) +window_reverse(GntWidget *win, gboolean set, GntWM *wm) { int i; int w, h; @@ -743,7 +806,8 @@ for (i = 0; i < h; i += reverse_char(d, i, 0, set)); for (i = 0; i < h; i += reverse_char(d, i, w-1, set)); - wrefresh(win->window); + copy_win(win, g_hash_table_lookup(wm->nodes, win)); + update_screen(wm); } static gboolean @@ -756,7 +820,7 @@ return TRUE; wm->mode = GNT_KP_MODE_MOVE; - window_reverse(GNT_WIDGET(wm->ordered->data), TRUE); + window_reverse(GNT_WIDGET(wm->ordered->data), TRUE, wm); return TRUE; } @@ -771,7 +835,7 @@ return TRUE; wm->mode = GNT_KP_MODE_RESIZE; - window_reverse(GNT_WIDGET(wm->ordered->data), TRUE); + window_reverse(GNT_WIDGET(wm->ordered->data), TRUE, wm); return TRUE; } @@ -934,6 +998,10 @@ "\033" "l", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "switch-window-n", switch_window_n, NULL, NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-down", window_scroll_down, + "\033" GNT_KEY_CTRL_J, NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-up", window_scroll_up, + "\033" GNT_KEY_CTRL_K, NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); GNTDEBUG; @@ -994,6 +1062,7 @@ node = g_new0(GntNode, 1); node->me = widget; + node->scroll = 0; g_hash_table_replace(wm->nodes, widget, node); @@ -1001,7 +1070,38 @@ transient = !!GNT_WIDGET_IS_FLAG_SET(node->me, GNT_WIDGET_TRANSIENT); - node->panel = new_panel(node->me->window); +#if 1 + { + int x, y, w, h, maxx, maxy; + gboolean shadow = TRUE; + + if (!gnt_widget_has_shadow(widget)) + shadow = FALSE; + x = widget->priv.x; + y = widget->priv.y; + w = widget->priv.width; + h = widget->priv.height; + + getmaxyx(stdscr, maxy, maxx); + maxy -= 1; /* room for the taskbar */ + maxy -= shadow; + maxx -= shadow; + + x = MAX(0, x); + y = MAX(0, y); + if (x + w >= maxx) + x = MAX(0, maxx - w); + if (y + h >= maxy) + y = MAX(0, maxy - h); + + w = MIN(w, maxx); + h = MIN(h, maxy); + node->window = newwin(h + shadow, w + shadow, y, x); + copy_win(widget, node); + } +#endif + + node->panel = new_panel(node->window); set_panel_userptr(node->panel, node); if (!transient) { @@ -1146,7 +1246,7 @@ } if (ox != x || oy != y) { gnt_screen_move_widget(widget, x, y); - window_reverse(widget, TRUE); + window_reverse(widget, TRUE, wm); return; } } else if (wm->mode == GNT_KP_MODE_RESIZE) { @@ -1163,12 +1263,12 @@ } if (oh != h || ow != w) { gnt_screen_resize_widget(widget, w, h); - window_reverse(widget, TRUE); + window_reverse(widget, TRUE, wm); return; } } if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) { - window_reverse(widget, FALSE); + window_reverse(widget, FALSE, wm); wm->mode = GNT_KP_MODE_NORMAL; } return; @@ -1209,8 +1309,7 @@ static void gnt_wm_win_resized(GntWM *wm, GntNode *node) { - refresh_node(node->me, node, NULL); - replace_panel(node->panel, node->me->window); + /*refresh_node(node->me, node, NULL);*/ } static void @@ -1223,6 +1322,8 @@ { gboolean ret = TRUE; GntNode *node; + int shadow; + int maxx, maxy; while (widget->parent) widget = widget->parent; @@ -1237,6 +1338,14 @@ gnt_widget_set_size(widget, width, height); gnt_widget_draw(widget); + shadow = gnt_widget_has_shadow(widget) ? 1 : 0; + maxx = getmaxx(stdscr) - shadow; + maxy = getmaxy(stdscr) - 1 - shadow; + height = MIN(height, maxy); + width = MIN(width, maxx); + wresize(node->window, height + shadow, width + shadow); + replace_panel(node->panel, node->window); + g_signal_emit(wm, signals[SIG_RESIZED], 0, node); show_panel(node->panel); @@ -1360,6 +1469,7 @@ } else g_signal_emit(wm, signals[SIG_UPDATE_WIN], 0, node); + copy_win(widget, node); update_screen(wm); draw_taskbar(wm, FALSE); }