[evolution] Bug 596947 - Calendar view forgets memo pane height



commit f989e5d9702ae54343cf28cecae1d045b416afb6
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Dec 19 23:54:54 2009 -0500

    Bug 596947 - Calendar view forgets memo pane height

 modules/calendar/e-cal-shell-content.c |    7 +-
 widgets/misc/e-paned.c                 |  158 +++++++++++++++++++++++++++++---
 widgets/misc/e-paned.h                 |    6 +
 3 files changed, 155 insertions(+), 16 deletions(-)
---
diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c
index fcebf59..3f56f01 100644
--- a/modules/calendar/e-cal-shell-content.c
+++ b/modules/calendar/e-cal-shell-content.c
@@ -383,7 +383,8 @@ cal_shell_content_constructed (GObject *object)
 
 	/* FIXME Need to deal with saving and restoring the position.
 	 *       Month view has its own position. */
-	widget = gtk_vpaned_new ();
+	widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
+	e_paned_set_fixed_resize (E_PANED (widget), FALSE);
 	gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, TRUE);
 	priv->vpaned = g_object_ref (widget);
 	gtk_widget_show (widget);
@@ -517,8 +518,8 @@ cal_shell_content_constructed (GObject *object)
 	bridge = gconf_bridge_get ();
 
 	object = G_OBJECT (priv->vpaned);
-	key = "/apps/evolution/calendar/display/vpane_position";
-	gconf_bridge_bind_property_delayed (bridge, key, object, "position");
+	key = "/apps/evolution/calendar/display/tag_vpane_position";
+	gconf_bridge_bind_property_delayed (bridge, key, object, "proportion");
 
 	g_object_unref (memo_model);
 	g_object_unref (task_model);
diff --git a/widgets/misc/e-paned.c b/widgets/misc/e-paned.c
index b363d0a..83f9614 100644
--- a/widgets/misc/e-paned.c
+++ b/widgets/misc/e-paned.c
@@ -28,20 +28,28 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_PANED, EPanedPrivate))
 
+#define SYNC_REQUEST_NONE		0
+#define SYNC_REQUEST_POSITION		1
+#define SYNC_REQUEST_PROPORTION		2
+
 struct _EPanedPrivate {
 	gint hposition;
 	gint vposition;
+	gdouble proportion;
 
 	gulong wse_handler_id;
 
-	guint sync_position	: 1;
+	guint fixed_resize	: 1;
+	guint sync_request	: 2;
 	guint toplevel_ready	: 1;
 };
 
 enum {
 	PROP_0,
 	PROP_HPOSITION,
-	PROP_VPOSITION
+	PROP_VPOSITION,
+	PROP_PROPORTION,
+	PROP_FIXED_RESIZE
 };
 
 static gpointer parent_class;
@@ -61,8 +69,8 @@ paned_window_state_event_cb (EPaned *paned,
 	 * Set a flag so we know it's safe to set GtkPaned position. */
 	paned->priv->toplevel_ready = TRUE;
 
-	paned->priv->sync_position = TRUE;
-	gtk_widget_queue_resize (GTK_WIDGET (paned));
+	if (paned->priv->sync_request != SYNC_REQUEST_NONE)
+		gtk_widget_queue_resize (GTK_WIDGET (paned));
 
 	/* We don't need to listen for window state events anymore. */
 	g_signal_handler_disconnect (toplevel, paned->priv->wse_handler_id);
@@ -75,7 +83,10 @@ static void
 paned_notify_orientation_cb (EPaned *paned)
 {
 	/* Ignore the next "notify::position" emission. */
-	paned->priv->sync_position = TRUE;
+	if (e_paned_get_fixed_resize (paned))
+		paned->priv->sync_request = SYNC_REQUEST_POSITION;
+	else
+		paned->priv->sync_request = SYNC_REQUEST_PROPORTION;
 	gtk_widget_queue_resize (GTK_WIDGET (paned));
 }
 
@@ -85,9 +96,11 @@ paned_notify_position_cb (EPaned *paned)
 	GtkAllocation *allocation;
 	GtkOrientable *orientable;
 	GtkOrientation orientation;
+	gdouble proportion;
 	gint position;
 
-	if (paned->priv->sync_position)
+	/* If a sync has already been requested, do nothing. */
+	if (paned->priv->sync_request != SYNC_REQUEST_NONE)
 		return;
 
 	orientable = GTK_ORIENTABLE (paned);
@@ -96,13 +109,31 @@ paned_notify_position_cb (EPaned *paned)
 	allocation = &GTK_WIDGET (paned)->allocation;
 	position = gtk_paned_get_position (GTK_PANED (paned));
 
+	g_object_freeze_notify (G_OBJECT (paned));
+
 	if (orientation == GTK_ORIENTATION_HORIZONTAL) {
 		position = MAX (0, allocation->width - position);
-		e_paned_set_hposition (paned, position);
+		proportion = (gdouble) position / allocation->width;
+
+		paned->priv->hposition = position;
+		g_object_notify (G_OBJECT (paned), "hposition");
 	} else {
 		position = MAX (0, allocation->height - position);
-		e_paned_set_vposition (paned, position);
+		proportion = (gdouble) position / allocation->height;
+
+		paned->priv->vposition = position;
+		g_object_notify (G_OBJECT (paned), "vposition");
 	}
+
+	paned->priv->proportion = proportion;
+	g_object_notify (G_OBJECT (paned), "proportion");
+
+	if (e_paned_get_fixed_resize (paned))
+		paned->priv->sync_request = SYNC_REQUEST_POSITION;
+	else
+		paned->priv->sync_request = SYNC_REQUEST_PROPORTION;
+
+	g_object_thaw_notify (G_OBJECT (paned));
 }
 
 static void
@@ -123,6 +154,18 @@ paned_set_property (GObject *object,
 				E_PANED (object),
 				g_value_get_int (value));
 			return;
+
+		case PROP_PROPORTION:
+			e_paned_set_proportion (
+				E_PANED (object),
+				g_value_get_double (value));
+			return;
+
+		case PROP_FIXED_RESIZE:
+			e_paned_set_fixed_resize (
+				E_PANED (object),
+				g_value_get_boolean (value));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -146,6 +189,18 @@ paned_get_property (GObject *object,
 				value, e_paned_get_vposition (
 				E_PANED (object)));
 			return;
+
+		case PROP_PROPORTION:
+			g_value_set_double (
+				value, e_paned_get_proportion (
+				E_PANED (object)));
+			return;
+
+		case PROP_FIXED_RESIZE:
+			g_value_set_boolean (
+				value, e_paned_get_fixed_resize (
+				E_PANED (object)));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -190,6 +245,7 @@ paned_size_allocate (GtkWidget *widget,
 	EPaned *paned = E_PANED (widget);
 	GtkOrientable *orientable;
 	GtkOrientation orientation;
+	gdouble proportion;
 	gint allocated;
 	gint position;
 
@@ -199,7 +255,7 @@ paned_size_allocate (GtkWidget *widget,
 	if (!paned->priv->toplevel_ready)
 		return;
 
-	if (!paned->priv->sync_position)
+	if (paned->priv->sync_request == SYNC_REQUEST_NONE)
 		return;
 
 	orientable = GTK_ORIENTABLE (paned);
@@ -213,10 +269,16 @@ paned_size_allocate (GtkWidget *widget,
 		position = e_paned_get_vposition (paned);
 	}
 
-	position = MAX (0, allocated - position);
+	proportion = e_paned_get_proportion (paned);
+
+	if (paned->priv->sync_request == SYNC_REQUEST_POSITION)
+		position = MAX (0, allocated - position);
+	else
+		position = (1.0 - proportion) * allocated;
+
 	gtk_paned_set_position (GTK_PANED (paned), position);
 
-	paned->priv->sync_position = FALSE;
+	paned->priv->sync_request = SYNC_REQUEST_NONE;
 }
 
 static void
@@ -259,6 +321,28 @@ paned_class_init (EPanedClass *class)
 			G_MAXINT,
 			0,
 			G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_PROPORTION,
+		g_param_spec_double (
+			"proportion",
+			_("Proportion"),
+			_("Proportion of the 2nd pane size"),
+			0.0,
+			1.0,
+			0.0,
+			G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_FIXED_RESIZE,
+		g_param_spec_boolean (
+			"fixed-resize",
+			_("Fixed Resize"),
+			_("Keep the 2nd pane fixed during resize"),
+			TRUE,
+			G_PARAM_READWRITE));
 }
 
 static void
@@ -266,6 +350,9 @@ paned_init (EPaned *paned)
 {
 	paned->priv = E_PANED_GET_PRIVATE (paned);
 
+	paned->priv->proportion = 0.5;
+	paned->priv->fixed_resize = TRUE;
+
 	g_signal_connect (
 		paned, "notify::orientation",
 		G_CALLBACK (paned_notify_orientation_cb), NULL);
@@ -335,7 +422,7 @@ e_paned_set_hposition (EPaned *paned,
 	orientation = gtk_orientable_get_orientation (orientable);
 
 	if (orientation == GTK_ORIENTATION_HORIZONTAL) {
-		paned->priv->sync_position = TRUE;
+		paned->priv->sync_request = SYNC_REQUEST_POSITION;
 		gtk_widget_queue_resize (GTK_WIDGET (paned));
 	}
 }
@@ -368,7 +455,52 @@ e_paned_set_vposition (EPaned *paned,
 	orientation = gtk_orientable_get_orientation (orientable);
 
 	if (orientation == GTK_ORIENTATION_VERTICAL) {
-		paned->priv->sync_position = TRUE;
+		paned->priv->sync_request = SYNC_REQUEST_POSITION;
 		gtk_widget_queue_resize (GTK_WIDGET (paned));
 	}
 }
+
+gdouble
+e_paned_get_proportion (EPaned *paned)
+{
+	g_return_val_if_fail (E_IS_PANED (paned), 0.5);
+
+	return paned->priv->proportion;
+}
+
+void
+e_paned_set_proportion (EPaned *paned,
+                        gdouble proportion)
+{
+	g_return_if_fail (E_IS_PANED (paned));
+	g_return_if_fail (CLAMP (proportion, 0.0, 1.0) == proportion);
+
+	paned->priv->proportion = proportion;
+
+	paned->priv->sync_request = SYNC_REQUEST_PROPORTION;
+	gtk_widget_queue_resize (GTK_WIDGET (paned));
+
+	g_object_notify (G_OBJECT (paned), "proportion");
+}
+
+gboolean
+e_paned_get_fixed_resize (EPaned *paned)
+{
+	g_return_val_if_fail (E_IS_PANED (paned), FALSE);
+
+	return paned->priv->fixed_resize;
+}
+
+void
+e_paned_set_fixed_resize (EPaned *paned,
+                          gboolean fixed_resize)
+{
+	g_return_if_fail (E_IS_PANED (paned));
+
+	if (fixed_resize == paned->priv->fixed_resize)
+		return;
+
+	paned->priv->fixed_resize = fixed_resize;
+
+	g_object_notify (G_OBJECT (paned), "fixed-resize");
+}
diff --git a/widgets/misc/e-paned.h b/widgets/misc/e-paned.h
index 8bd1c22..1867a04 100644
--- a/widgets/misc/e-paned.h
+++ b/widgets/misc/e-paned.h
@@ -66,6 +66,12 @@ void		e_paned_set_hposition		(EPaned *paned,
 gint		e_paned_get_vposition		(EPaned *paned);
 void		e_paned_set_vposition		(EPaned *paned,
 						 gint vposition);
+gdouble		e_paned_get_proportion		(EPaned *paned);
+void		e_paned_set_proportion		(EPaned *paned,
+						 gdouble proportion);
+gboolean	e_paned_get_fixed_resize	(EPaned *paned);
+void		e_paned_set_fixed_resize	(EPaned *paned,
+						 gboolean fixed_resize);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]