aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-paned.c
diff options
context:
space:
mode:
Diffstat (limited to 'e-util/e-paned.c')
-rw-r--r--e-util/e-paned.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/e-util/e-paned.c b/e-util/e-paned.c
new file mode 100644
index 0000000000..c00c98ac53
--- /dev/null
+++ b/e-util/e-paned.c
@@ -0,0 +1,227 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-pane.c: A paned window which accepts more than one child
+ *
+ * Author:
+ * Matt Loper (matt@helixcode.com)
+ *
+ * Copyright 2000, Helix Code, Inc
+ */
+
+#include "e-paned.h"
+#include "e-util.h"
+
+#define PARENT_TYPE gtk_frame_get_type ()
+static GtkObjectClass *e_paned_parent_class;
+
+/*----------------------------------------------------------------------*
+ * (un)parenting functions
+ *----------------------------------------------------------------------*/
+
+static void
+unparent_all_children (EPaned *paned)
+{
+ GList *l;
+
+ for (l = paned->children; l != NULL; l = l->next) {
+ GtkWidget *child = GTK_WIDGET (l->data);
+
+ gtk_widget_ref (child);
+ gtk_container_remove (GTK_CONTAINER (child->parent),
+ child);
+ }
+
+ if (paned->toplevel_paned) {
+ GtkWidget* parent =
+ GTK_WIDGET (paned->toplevel_paned)->parent;
+
+ gtk_container_remove (GTK_CONTAINER (parent),
+ GTK_WIDGET (paned->toplevel_paned));
+ }
+
+
+ paned->toplevel_paned = NULL;
+}
+
+static GtkPaned*
+new_gtk_paned (EPaned *paned)
+{
+ return paned->horizontal?
+ GTK_PANED (gtk_hpaned_new ()):
+ GTK_PANED (gtk_vpaned_new ());
+}
+
+
+static void
+reparent_all_children (EPaned *paned)
+{
+ GtkPaned *cur_gtk_paned;
+ GList *l = paned->children;
+ int requested_size;
+
+ g_assert (E_IS_PANED (paned));
+
+ if (paned->toplevel_paned)
+ unparent_all_children (paned);
+
+ if (!l)
+ return;
+
+ /* if there's only one child in our list, we don't need a
+ splitter window; we can just show the one window */
+ if (!l->next)
+ {
+ gtk_container_add (GTK_CONTAINER (paned),
+ GTK_WIDGET (l->data));
+ return;
+ }
+
+ /* create a gtk_paned, and put it in our toplevel EPaned */
+ cur_gtk_paned = new_gtk_paned (paned);
+ paned->toplevel_paned = cur_gtk_paned;
+ gtk_container_add (GTK_CONTAINER (paned),
+ GTK_WIDGET (paned->toplevel_paned));
+
+ /* put the first widget in the left part of our pane,
+ and give it the amount of space requested */
+ gtk_paned_add1 (cur_gtk_paned, GTK_WIDGET (l->data));
+ requested_size = (int)gtk_object_get_data (
+ GTK_OBJECT (l->data),
+ "e_paned_requested_size");
+ gtk_paned_set_position (GTK_PANED (cur_gtk_paned),
+ requested_size);
+
+ l = l->next;
+
+ for (; l != NULL; l = l->next) {
+
+ if (l->next) {
+
+ GtkPaned *sub_gtk_paned =
+ new_gtk_paned (paned);
+ GtkWidget *w = GTK_WIDGET (l->data);
+
+ /* add our widget to the new subpane,
+ on the left */
+ gtk_paned_add1 (sub_gtk_paned, w);
+
+ requested_size = (int)gtk_object_get_data (
+ GTK_OBJECT (w),
+ "e_paned_requested_size");
+ gtk_paned_set_position (GTK_PANED (sub_gtk_paned),
+ requested_size);
+
+ gtk_paned_add2 (cur_gtk_paned,
+ GTK_WIDGET (sub_gtk_paned));
+ cur_gtk_paned = sub_gtk_paned;
+ }
+ else {
+ gtk_paned_add2 (cur_gtk_paned,
+ GTK_WIDGET (l->data));
+ }
+ }
+}
+
+/*----------------------------------------------------------------------*
+ * Exposed regular functions
+ *----------------------------------------------------------------------*/
+
+
+/**
+ * e_paned_insert:
+ * @paned: the #EPaned object
+ * @pos: the position where we should insert the widget
+ * @child: the widget to insert in the #EPaned object
+ * @requested_size: the requested span of the widget, which will be
+ * width of the #EPaned is horizontal, or height if it's vertical
+ *
+ * Inserts a widget into the #EPaned window, given a requested size
+ * and a position; the position specifies where, among the other
+ * widgets, the widget should be placed.
+ *
+ **/
+void
+e_paned_insert (EPaned *paned, int pos, GtkWidget *child, int requested_size)
+{
+ g_assert (GTK_IS_WIDGET (child));
+ g_assert (E_IS_PANED (paned));
+
+ unparent_all_children (paned);
+
+ paned->children = g_list_insert (paned->children, child, pos);
+ gtk_object_set_data (GTK_OBJECT (child),
+ "e_paned_requested_size",
+ (gpointer)requested_size);
+
+ reparent_all_children (paned);
+
+ g_print ("%s: %s(): exiting, length is %i\n",
+ __FILE__, __FUNCTION__, g_list_length (paned->children));
+}
+
+/**
+ * e_paned_remove:
+ * @paned: the #EPaned object
+ * @removed_child: the widget to remove
+ *
+ * Removes a widget from an #EPaned widget.
+ *
+ **/
+void
+e_paned_remove (EPaned *paned, GtkWidget *removed_child)
+{
+ unparent_all_children (paned);
+ paned->children = g_list_remove (paned->children, removed_child);
+ gtk_widget_unref (GTK_WIDGET (removed_child));
+ reparent_all_children (paned);
+}
+
+
+/*----------------------------------------------------------------------*
+ * Standard Gtk+ Class functions
+ *----------------------------------------------------------------------*/
+
+void
+e_paned_construct (EPaned *e_paned,
+ gboolean horizontal)
+{
+ g_return_if_fail (e_paned != NULL);
+ g_return_if_fail (E_IS_PANED (e_paned));
+
+
+ e_paned->horizontal = horizontal;
+}
+
+GtkWidget*
+e_paned_new (gboolean horizontal)
+{
+ EPaned *e_paned;
+
+ e_paned = gtk_type_new (e_paned_get_type ());
+
+ e_paned_construct (e_paned, horizontal);
+
+ g_assert (E_IS_PANED (e_paned));
+
+ return GTK_WIDGET (e_paned);
+}
+
+static void
+e_paned_init (GtkObject *object)
+{
+ EPaned *e_paned;
+
+ e_paned = E_PANED (object);
+
+ e_paned->children = NULL;
+ e_paned->toplevel_paned = NULL;
+ e_paned->horizontal = FALSE;
+}
+
+static void
+e_paned_class_init (GtkObjectClass *object_class)
+{
+ e_paned_parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+E_MAKE_TYPE(e_paned, "EPaned", EPaned, e_paned_class_init, e_paned_init, PARENT_TYPE);