Better handle large windows that don't fit into the screen (eg. the preference

Tue, 27 Feb 2007 09:06:05 +0000

author
Sadrul Habib Chowdhury <sadrul@pidgin.im>
date
Tue, 27 Feb 2007 09:06:05 +0000
changeset 15804
a06705e0130e
parent 15803
4f04b9413b50
child 15805
a80eb333bae9
child 15806
1972a83ada1f

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.

console/libgnt/gntwidget.c file | annotate | diff | comparison | revisions
console/libgnt/gntwm.c file | annotate | diff | comparison | revisions
console/libgnt/gntwm.h file | annotate | diff | comparison | revisions
console/libgnt/test/key.c file | annotate | diff | comparison | revisions
--- 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();
 	}

mercurial