changeset 15742: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 2273694a865d
children 6d4c5218b90b e11859350489
files console/libgnt/gntwidget.c console/libgnt/gntwm.c console/libgnt/gntwm.h console/libgnt/test/key.c
diffstat 4 files changed, 127 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/console/libgnt/gntwidget.c	Tue Feb 27 04:58:18 2007 +0000
+++ b/console/libgnt/gntwidget.c	Tue Feb 27 09:06:05 2007 +0000
@@ -323,6 +323,7 @@
 
 	if (widget->window == NULL)
 	{
+#if 0
 		int x, y, maxx, maxy, w, h;
 		int oldw, oldh;
 		gboolean shadow = TRUE;
@@ -355,9 +356,9 @@
 			widget->priv.height = h - shadow;
 			g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh);
 		}
-
-		widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow,
-						widget->priv.y, widget->priv.x);
+#else
+		widget->window = newpad(150, 350);  /* XXX: */
+#endif
 		init_widget(widget);
 	}
 
@@ -524,7 +525,6 @@
 
 		if (widget->window)
 		{
-			wresize(widget->window, height + shadow, width + shadow);
 			init_widget(widget);
 		}
 		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
--- 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);
 }
--- a/console/libgnt/gntwm.h	Tue Feb 27 04:58:18 2007 +0000
+++ b/console/libgnt/gntwm.h	Tue Feb 27 09:06:05 2007 +0000
@@ -22,6 +22,8 @@
 {
 	GntWidget *me;
 
+	WINDOW *window;
+	int scroll;
 	PANEL *panel;
 } GntNode;
 
--- a/console/libgnt/test/key.c	Tue Feb 27 04:58:18 2007 +0000
+++ b/console/libgnt/test/key.c	Tue Feb 27 09:06:05 2007 +0000
@@ -7,7 +7,7 @@
 
 	noecho();
 
-	while ((ch = getch()) != 27) {
+	while ((ch = getch())) {
 		printw("%d ", ch);
 		refresh();
 	}