diff finch/libgnt/gntbox.c @ 30036:33a4d72232a7

Improve resizing a box. libgnt used to always change the size of the first widget. So in a lot of dialogs (e.g. the log viewer, the add-buddy dialogs etc.) only the labels would be resized, and the entry/comboboxes, resizing which would be more useful, would never be resized. So change that behaviour to cycle through all the widgets in the box for resize. Fixes #11580, #7843.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 24 Mar 2010 02:38:56 +0000
parents a18f421696dc
children 5d3f64f8e7b5
line wrap: on
line diff
--- a/finch/libgnt/gntbox.c	Tue Mar 23 23:25:14 2010 +0000
+++ b/finch/libgnt/gntbox.c	Wed Mar 24 02:38:56 2010 +0000
@@ -27,6 +27,9 @@
 
 #include <string.h>
 
+#define PROP_LAST_RESIZE_S "last-resize"
+#define PROP_SIZE_QUEUED_S "size-queued"
+
 enum
 {
 	PROP_0,
@@ -194,7 +197,7 @@
 	GntBox *box = GNT_BOX(widget);
 	GList *iter;
 	int maxw = 0, maxh = 0;
-	
+
 	g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
 
 	for (iter = box->list; iter; iter = iter->next)
@@ -398,6 +401,7 @@
 	GList *iter;
 	GntBox *box = GNT_BOX(widget);
 	int wchange, hchange;
+	GntWidget *child, *last;
 
 	if (!box->list)
 		return TRUE;
@@ -406,67 +410,59 @@
 	hchange = widget->priv.height - height;
 
 	if (wchange == 0 && hchange == 0)
-		return TRUE;		/* Quit playing games */
+		return TRUE;		/* Quit playing games with my size */
 
-	/* XXX: Right now, I am trying to just apply all the changes to 
-	 * just one widget. It should be possible to distribute the
-	 * changes to all the widgets in the box. */
-	for (iter = box->list; iter; iter = iter->next)
-	{
+	child = NULL;
+	last = g_object_get_data(G_OBJECT(box), PROP_LAST_RESIZE_S);
+
+	/* First, make sure all the widgets will fit into the box after resizing. */
+	for (iter = box->list; iter; iter = iter->next) {
 		GntWidget *wid = iter->data;
 		int w, h;
 
 		gnt_widget_get_size(wid, &w, &h);
 
-		if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))
-		{
-			GList *i;
-
-			for (i = box->list; i; i = i->next)
-			{
-				int tw, th;
-				if (i == iter) continue;
-				gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
-				if (box->vertical)
-				{
-					if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) {
-						/* If we are decreasing the size and the widget is going
-						 * to be too large to fit into the box, then do not allow
-						 * resizing. */
-						if (wchange > 0 && tw >= widget->priv.width)
-							return FALSE;
-					}
-				}
-				else
-				{
-					if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) {
-						if (hchange > 0 && th >= widget->priv.height)
-							return FALSE;
-						return FALSE;
-					}
-				}
-			}
-#if 0
-			gnt_widget_set_size(wid, w - wchange, h - hchange);
-			if (box->vertical)
-				hchange = 0;
-			else
-				wchange = 0;
-
-			for (i = box->list; i; i = i->next)
-			{
-				int tw, th;
-				if (i == iter) continue;
-				gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
-				gnt_widget_set_size(i->data, tw - wchange, th - hchange);
-			}
-#endif
-			g_object_set_data(G_OBJECT(box), "size-queued", wid);
-			return TRUE;
+		if (wid != last && !child && gnt_widget_confirm_size(wid, w - wchange, h - hchange)) {
+			child = wid;
+			break;
 		}
 	}
 
-	return FALSE;
+	if (!child && (child = last)) {
+		int w, h;
+		gnt_widget_get_size(child, &w, &h);
+		if (!gnt_widget_confirm_size(child, w - wchange, h - hchange))
+			child = NULL;
+	}
+
+	g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, child);
+
+	if (child) {
+		for (iter = box->list; iter; iter = iter->next) {
+			GntWidget *wid = iter->data;
+			int w, h;
+
+			gnt_widget_get_size(wid, &w, &h);
+			if (box->vertical) {
+				/* For a vertical box, if we are changing the width, make sure the widgets
+				 * in the box will fit after resizing the width. */
+				if (wchange > 0 &&
+						w >= child->priv.width &&
+						!gnt_widget_confirm_size(wid, w - wchange, h))
+					return FALSE;
+			} else {
+				/* If we are changing the height, make sure the widgets in the box fit after
+				 * the resize. */
+				if (hchange > 0 &&
+						h >= child->priv.height &&
+						!gnt_widget_confirm_size(wid, w, h - hchange))
+					return FALSE;
+			}
+
+		}
+	}
+
+	return (child != NULL);
 }
 
 static void
@@ -477,16 +473,16 @@
 	GntBox *box = GNT_BOX(widget);
 	GntWidget *wid;
 	int tw, th;
-		
+
 	wchange = widget->priv.width - oldw;
 	hchange = widget->priv.height - oldh;
-	
-	wid = g_object_get_data(G_OBJECT(box), "size-queued");
-	if (wid)
-	{
+
+	wid = g_object_get_data(G_OBJECT(box), PROP_SIZE_QUEUED_S);
+	if (wid) {
 		gnt_widget_get_size(wid, &tw, &th);
 		gnt_widget_set_size(wid, tw + wchange, th + hchange);
-		g_object_set_data(G_OBJECT(box), "size-queued", NULL);
+		g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, NULL);
+		g_object_set_data(G_OBJECT(box), PROP_LAST_RESIZE_S, wid);
 	}
 
 	if (box->vertical)