[patch] Save/restore position in GdlDock
- From: "Gustavo M. Giráldez" <gustavo giraldez gmx net>
- To: Gnome DevTools list <gnome-devtools gnome org>, Dave Camp <dave ximian com>
- Subject: [patch] Save/restore position in GdlDock
- Date: Sun, 2 Dec 2001 05:30:04 -0300
Hi Dave & others,
This patch adds some functionality to GdlDock to save and restore the docked position of an item. This is used when docking/undocking from the popup menu, but should be used in the Anjuta layout managment dialog (yet to be written) too. Also removes the location menu options from the popup.
The save/restore operations use hinted positions relative to other named items (e.g. "item1" was docked on left of "item2"). The main reason behind this is that non-named (anonymous) item containers are destroyed and created when changing the layout. Only named ones are guaranteed to always be bound to the dock. As far as I tested the restore operation is robust, but has the drawback of not always restoring the item's position as the user might expect. If somebody has an idea on how to improve this I would like to hear it.
May I commit?
Thanks,
Gustavo
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gdl/ChangeLog,v
retrieving revision 1.38
diff -u -r1.38 ChangeLog
--- ChangeLog 2001/11/21 23:04:55 1.38
+++ ChangeLog 2001/12/02 08:20:40
@@ -1,3 +1,30 @@
+2001-12-02 Gustavo Giráldez <gustavo giraldez gmx net>
+
+ * gdl/TODO.gdl-dock: Updated
+ * gdl/gdl-dock-item.[ch]:
+ Removed location menu option functions and struct fields.
+ Removed some (already fixed) FIXMEs.
+ (gdl_dock_item_save_position, gdl_dock_item_restore_position):
+ New docked position save/restore functions.
+ (gdl_dock_item_get_pos_hint): New class virtual method to support
+ position saving: returns a hinted relative position of the item to
+ another named item.
+ (gdl_dock_item_{dock,undock}_cb): Dock/Undock menu items
+ callbacks.
+ (gdl_dock_item_dock_to): Save docked position if item wants to
+ float. Containers can no longer be nested inside notebooks: the
+ item is docked relative to the container notebook in such case.
+ (gdl_dock_item_hide): Save current dock position.
+ (gdl_dock_item_show): New function, to show a previously hidden,
+ via gdl_dock_item_hide, item.
+ * gdl/gdl-dock-notebook.c: Implemented get_pos_hint virtual.
+ (gdl_dock_notebook_add): create default label from long name if
+ available.
+ * gdl/gdl-dock-paned.c: Implemented get_pos_hint virtual.
+ * gdl/gdl-dock-tablabel.c (gdl_dock_tablabel_size_allocate):
+ Fixed allocation bug related to unsigned arithmetic operations.
+ * gdl/gdl-dock.[ch] (gdl_dock_get_named_items): New function.
+
2001-11-18 Gustavo Giráldez <gustavo giraldez gmx net>
* gdl/gdl-dock.c (gdl_dock_layout_load): Test if we have docked
Index: gdl/TODO.gdl-dock
===================================================================
RCS file: /cvs/gnome/gdl/gdl/TODO.gdl-dock,v
retrieving revision 1.1
diff -u -r1.1 TODO.gdl-dock
--- gdl/TODO.gdl-dock 2001/10/10 13:09:14 1.1
+++ gdl/TODO.gdl-dock 2001/12/02 08:20:40
@@ -1,17 +1,9 @@
-* Popup menu for the dragbar
-
* In GdlDockPaned (drag_request): decide which child to pass the request to in function of the coordinate
* Keyboard navigation in floating items: if the parent window has the focus, the keyboard works (sawfish, follow-focus mode) and the item is still in the "tab ring" (don't know the exact name).
-* XML layout saving/restoring. Idea: make a per-item function which asks for the layout, and make nested calls to build the tree/XML stream
-
* Floating window size negotiation. See GnomeDockItem's implementation (preferred_width/height arguments). Also, if the item is resizable, provide some mechanism for doing that without the aid of the window manager.
-* Fix the undock final position. This is related to the relative sizes of the item (the docked vs. the floating sizes)
-
-* Emit "layout_changed" signal in the dock.
-
* When docking with paned, split the paned according to previous relative sizes or something like that.
* Dock to floating items (is this really useful/intuitive?)
@@ -24,8 +16,6 @@
* Make a nicer dragbar for the items, with buttons for undocking, closing, hidding, etc. (See sodipodi, kdevelop)
-* Decide whether to use signals for drag_{begin,motion,end} in the items, or just call gdl_dock_* directly. Signal pros: API hide, possibility to hook other functions, "compatibility" with GnomeDock. Signal cons: slower (?), less clear.
-
* Virtualize reorder (?): don't know if this would be useful.
* Virtualize dock_to: don't know either. Would allow implementing different docking behavior. Contrast with next item...
@@ -33,8 +23,6 @@
* Make a dock_to counterpart: dock_from or something like that. The basic idea is that if an item doesn't know how to solve a docking request, it transfers the task to the target. This way, both functions are complementary from a semantic point of view. This also allows for easier extensibility, as new docking ways are implemented in the "host" dockitem.
* Click to hide in paned handle: basically what mozilla and nautilus do. Should only be enabled if the "hideable" property (see above) is enabled.
-
-* GdlDockNotebook: self-explanatory, I think.
* GdlDockBand: implement a dockitem which can hold items the same way as GnomeDockBand does.
Index: gdl/gdl-dock-item.c
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock-item.c,v
retrieving revision 1.3
diff -u -r1.3 gdl-dock-item.c
--- gdl/gdl-dock-item.c 2001/11/10 14:52:24 1.3
+++ gdl/gdl-dock-item.c 2001/12/02 08:20:53
@@ -38,8 +38,6 @@
static void gdl_dock_item_set_floating (GdlDockItem *item,
gboolean val);
-static void gdl_dock_item_location (GtkWidget *widget,
- GdlDockItem *item);
static void gdl_dock_item_dock_drag_start (GdlDockItem *item);
static gint gdl_dock_item_button_changed (GtkWidget *widget,
@@ -58,7 +56,11 @@
static void gdl_dock_item_hide_cb (GtkWidget *widget,
GdlDockItem *item);
+static void gdl_dock_item_save_position (GdlDockItem *item,
+ gboolean save_floating);
+static void gdl_dock_item_restore_position (GdlDockItem *item);
+
/* Class variables and definitions */
enum {
@@ -91,8 +93,6 @@
struct DockItemMenu {
GtkWidget *dock, *undock;
GtkWidget *hide;
- GtkWidget *location_menu, *location;
- GtkWidget *left, *right, *top, *bottom, *center;
GtkWidget *first_option;
};
@@ -209,6 +209,7 @@
klass->set_orientation = NULL;
klass->save_layout = NULL;
klass->item_hide = NULL;
+ klass->get_pos_hint = NULL;
}
static void
@@ -236,6 +237,9 @@
item->in_resize = FALSE;
item->handle_shown = TRUE;
item->drag_handle_size = DEFAULT_DRAG_HANDLE_SIZE;
+
+ item->last_pos.position = GDL_DOCK_FLOATING;
+ item->last_pos.peer = NULL;
}
static void
@@ -345,6 +349,7 @@
};
g_free (item->name);
g_free (item->long_name);
+ g_free (item->last_pos.peer);
if (item->menu) {
gtk_widget_destroy (item->menu);
@@ -870,21 +875,6 @@
}
static void
-gdl_dock_item_location (GtkWidget *widget,
- GdlDockItem *item)
-{
- guint position;
- GtkWidget *parent;
-
- /* Reposition item. */
- position = GPOINTER_TO_UINT (gtk_object_get_data (GTK_OBJECT (widget), "position"));
- GDL_DOCK_ITEM_GET_PARENT (item, parent);
- gdl_dock_item_dock_to (item, GDL_DOCK_ITEM (parent), position, -1);
-
- /* FIXME: emit layout_changed signal on the dock */
-}
-
-static void
gdl_dock_item_dock_drag_start (GdlDockItem *item)
{
GtkWidget *widget;
@@ -942,6 +932,33 @@
}
static void
+gdl_dock_item_dock_cb (GtkWidget *widget,
+ GdlDockItem *item)
+{
+ g_return_if_fail (item != NULL);
+
+ /* force docking even if saved position is floating */
+ if (item->last_pos.position == GDL_DOCK_FLOATING)
+ item->last_pos.position = GDL_DOCK_TOP;
+
+ gdl_dock_item_restore_position (item);
+
+ /* layout has changed */
+ gtk_signal_emit_by_name (GTK_OBJECT (item->dock), "layout_changed");
+}
+
+static void
+gdl_dock_item_undock_cb (GtkWidget *widget,
+ GdlDockItem *item)
+{
+ g_return_if_fail (item != NULL);
+
+ /* current position is saved in dock_to when the item floats */
+ gdl_dock_item_dock_to (item, NULL, GDL_DOCK_FLOATING, -1);
+ gtk_signal_emit_by_name (GTK_OBJECT (item->dock), "layout_changed");
+}
+
+static void
gdl_dock_item_popup_menu (GdlDockItem *item,
gint button,
guint32 time)
@@ -962,6 +979,10 @@
/* Dock/Undock menuitem. */
menu_data->dock = gtk_menu_item_new_with_label (_("Dock"));
menu_data->undock = gtk_menu_item_new_with_label (_("Undock"));
+ gtk_signal_connect (GTK_OBJECT (menu_data->dock), "activate",
+ GTK_SIGNAL_FUNC (gdl_dock_item_dock_cb), item);
+ gtk_signal_connect (GTK_OBJECT (menu_data->undock), "activate",
+ GTK_SIGNAL_FUNC (gdl_dock_item_undock_cb), item);
gtk_widget_ref (menu_data->dock);
gtk_widget_ref (menu_data->undock);
menu_data->first_option = NULL;
@@ -972,58 +993,6 @@
gtk_signal_connect (GTK_OBJECT (mitem), "activate",
GTK_SIGNAL_FUNC (gdl_dock_item_hide_cb), item);
- /* Horizontal line. */
- gtk_menu_append (GTK_MENU (item->menu), gtk_menu_item_new ());
-
- /* Location menu. */
- mitem = menu_data->location =
- gtk_menu_item_new_with_label (_("Location"));
- gtk_menu_append (GTK_MENU (item->menu), mitem);
-
- menu_data->location_menu = gtk_menu_new ();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mitem),
- menu_data->location_menu);
-
- /* Top. */
- mitem = menu_data->top = gtk_menu_item_new_with_label (_("Top"));
- gtk_menu_append (GTK_MENU (menu_data->location_menu), mitem);
- gtk_object_set_data (GTK_OBJECT (mitem), "position",
- GUINT_TO_POINTER (GDL_DOCK_TOP));
- gtk_signal_connect (GTK_OBJECT (mitem), "activate",
- GTK_SIGNAL_FUNC (gdl_dock_item_location), item);
-
- /* Left. */
- mitem = menu_data->left = gtk_menu_item_new_with_label (_("Left"));
- gtk_menu_append (GTK_MENU (menu_data->location_menu), mitem);
- gtk_object_set_data (GTK_OBJECT (mitem), "position",
- GUINT_TO_POINTER (GDL_DOCK_LEFT));
- gtk_signal_connect (GTK_OBJECT (mitem), "activate",
- GTK_SIGNAL_FUNC (gdl_dock_item_location), item);
-
- /* Center. */
- mitem = menu_data->center = gtk_menu_item_new_with_label (_("Center"));
- gtk_menu_append (GTK_MENU (menu_data->location_menu), mitem);
- gtk_object_set_data (GTK_OBJECT (mitem), "position",
- GUINT_TO_POINTER (GDL_DOCK_CENTER));
- gtk_signal_connect (GTK_OBJECT (mitem), "activate",
- GTK_SIGNAL_FUNC (gdl_dock_item_location), item);
-
- /* Right */
- mitem = menu_data->right = gtk_menu_item_new_with_label (_("Right"));
- gtk_menu_append (GTK_MENU (menu_data->location_menu), mitem);
- gtk_object_set_data (GTK_OBJECT (mitem), "position",
- GUINT_TO_POINTER (GDL_DOCK_RIGHT));
- gtk_signal_connect (GTK_OBJECT (mitem), "activate",
- GTK_SIGNAL_FUNC (gdl_dock_item_location), item);
-
- /* Bottom. */
- mitem = menu_data->bottom = gtk_menu_item_new_with_label (_("Bottom"));
- gtk_menu_append (GTK_MENU (menu_data->location_menu), mitem);
- gtk_object_set_data (GTK_OBJECT (mitem), "position",
- GUINT_TO_POINTER (GDL_DOCK_BOTTOM));
- gtk_signal_connect (GTK_OBJECT (mitem), "activate",
- GTK_SIGNAL_FUNC (gdl_dock_item_location), item);
-
} else
menu_data = gtk_object_get_user_data (GTK_OBJECT (item->menu));
@@ -1040,9 +1009,6 @@
menu_data->first_option = menu_data->undock;
};
- gtk_widget_set_sensitive (menu_data->location,
- !GDL_DOCK_ITEM_IS_FLOATING (item));
-
/* Show popup menu. */
gtk_widget_show_all (item->menu);
gtk_menu_popup (GTK_MENU (item->menu), NULL, NULL, NULL, NULL,
@@ -1270,7 +1236,135 @@
gtk_signal_emit_by_name (dock, "layout_changed");
}
+/* save the current docked position wrt to a named (i.e. non-anonymous and
+ * bound to the dock) item */
+static void
+gdl_dock_item_save_position (GdlDockItem *item,
+ gboolean save_floating)
+{
+ GtkWidget *parent;
+
+ /* don't save floating pos */
+ if (GDL_DOCK_ITEM_IS_FLOATING (item) && !save_floating)
+ return;
+
+ GDL_DOCK_ITEM_GET_PARENT (GTK_WIDGET (item), parent);
+ if (parent) {
+ if (item->last_pos.peer) {
+ g_free (item->last_pos.peer);
+ item->last_pos.peer = NULL;
+ };
+
+ if (GDL_IS_DOCK (parent)) {
+ item->last_pos.position = GDL_DOCK_TOP;
+
+ /* peer NULL means the dock */
+ item->last_pos.peer = NULL;
+
+ } else {
+ item->last_pos.peer = gdl_dock_item_get_pos_hint (
+ GDL_DOCK_ITEM (parent), item, &item->last_pos.position);
+ };
+ };
+
+ return;
+}
+
+static void
+gdl_dock_item_restore_position (GdlDockItem *item)
+{
+ GtkWidget *target = GTK_WIDGET (item);
+ GtkWidget *parent;
+ GdlDockPlacement new_pos = GDL_DOCK_FLOATING;
+ GdlDockItem *item_target;
+
+ g_return_if_fail (item != NULL);
+
+ while (target) {
+ item_target = GDL_DOCK_ITEM (target);
+
+ new_pos = item_target->last_pos.position;
+ /* special cases */
+ if (new_pos == GDL_DOCK_FLOATING) {
+ target = NULL;
+ break;
+ } else if (!item_target->last_pos.peer) {
+ /* there is no saved docking position: dock to the dock :-) */
+ target = item->dock;
+ break;
+ };
+
+ /* find peer */
+ target = GTK_WIDGET (gdl_dock_get_item_by_name (
+ GDL_DOCK (item->dock), item_target->last_pos.peer));
+
+ if (target) {
+ /* found: check if still docked */
+ GDL_DOCK_ITEM_GET_PARENT (GDL_DOCK_ITEM (target), parent);
+ if (parent)
+ break;
+
+ } else {
+ /* the peer is no longer bound to the dock... dock it in the top
+ of the hierarchy but respecting the previous position */
+ target = item->dock;
+ break;
+ };
+ };
+
+ if (target == item->dock) {
+ GtkWidget *w;
+
+ /* FIXME: damned special case! we need a more uniform way to do this
+ it's also more or less done in gdl_dock_drag_end */
+ GDL_DOCK_ITEM_GET_PARENT (item, parent);
+
+ w = GTK_WIDGET (item);
+ gtk_widget_ref (w);
+ if (w->parent) {
+ gtk_container_remove (GTK_CONTAINER (w->parent), w);
+ if (GDL_IS_DOCK_ITEM (parent))
+ gdl_dock_item_auto_reduce (GDL_DOCK_ITEM (parent));
+ };
+ gdl_dock_add_item (GDL_DOCK (item->dock), item, new_pos);
+ gtk_widget_unref (w);
+
+ } else {
+ gdl_dock_item_dock_to (item, GDL_DOCK_ITEM (target), new_pos, -1);
+ };
+}
+
+/* This function returns the name of a peer dockitem to caller and sets
+ * position to the relative position between the items.
+ * If the caller is NULL, it means the parent has made the call and is
+ * looking for a child's name. */
+gchar *
+gdl_dock_item_get_pos_hint (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position)
+{
+ GdlDockItemClass *klass;
+
+ g_return_val_if_fail (item != NULL, NULL);
+
+ /* call virtual */
+ klass = GDL_DOCK_ITEM_CLASS (GTK_OBJECT (item)->klass);
+ if (klass->get_pos_hint)
+ return klass->get_pos_hint (item, caller, position);
+
+ if (caller) {
+ /* this would imply a dockitem is docked inside us, which is not
+ possible */
+ g_warning (_("gdl_dock_item_get_pos_hint called for a regular item "
+ "in traversing the docking hierarchy up"));
+ return NULL;
+
+ } else
+ return g_strdup (item->name);
+}
+
+
/* ----------------------------------------------------------------------
* Public interface
* ---------------------------------------------------------------------- */
@@ -1288,8 +1382,6 @@
item->long_name = g_strdup (long_name);
item->behavior = behavior;
- /* FIXME: this should create the label using the description
- (or translated name) */
gdl_dock_item_set_tablabel (item, gdl_dock_tablabel_new (item->long_name));
return GTK_WIDGET (item);
@@ -1374,6 +1466,9 @@
/* Item wants to float. */
if (position == GDL_DOCK_FLOATING || !target_item) {
+ /* save previous docking position */
+ gdl_dock_item_save_position (item, FALSE);
+
/* Remove widget from current container. */
if (real_old_parent)
gtk_container_remove (GTK_CONTAINER (real_old_parent), widget);
@@ -1388,13 +1483,22 @@
} else {
GtkWidget *target, *parent, *real_parent;
+ gboolean target_resolved = FALSE;
- target = GTK_WIDGET (target_item);
-
- real_parent = target->parent;
- GDL_DOCK_ITEM_GET_PARENT (target, parent);
- if (!parent)
- parent = real_parent;
+ do {
+ /* get target and target's parent */
+ target = GTK_WIDGET (target_item);
+ real_parent = target->parent;
+ GDL_DOCK_ITEM_GET_PARENT (target, parent);
+ if (!parent)
+ parent = real_parent;
+
+ if (GDL_IS_DOCK_NOTEBOOK (parent))
+ /* do not allow composite docking inside a notebook */
+ target_item = GDL_DOCK_ITEM (parent);
+ else
+ target_resolved = TRUE;
+ } while (!target_resolved);
/* Unfloat item. */
if (GDL_DOCK_ITEM_IS_FLOATING (item))
@@ -1408,6 +1512,8 @@
current item. Otherwise, we create a GdlDockNotebook and
add it in place of the target. */
if (!GDL_IS_DOCK_NOTEBOOK (target)) {
+ /* check if the target is already docked in a notebook
+ note: this disallows nesting notebooks */
gtk_widget_ref (target);
gtk_container_remove (GTK_CONTAINER (real_parent), target);
nb = gdl_dock_notebook_new ();
@@ -1491,9 +1597,6 @@
}
}
- /* Set item placement. */
- item->placement = position;
-
/* Decrease refcount (was increased to prevent destruction). */
gtk_widget_unref (widget);
@@ -1792,6 +1895,9 @@
{
GdlDockItemClass *klass;
+ /* save current docking position */
+ gdl_dock_item_save_position (item, TRUE);
+
/* auto_reduce barrier to avoid reentrancy problems */
item->disable_auto_reduce = TRUE;
@@ -1821,6 +1927,16 @@
item->disable_auto_reduce = FALSE;
}
+
+
+void
+gdl_dock_item_show (GdlDockItem *item)
+{
+ g_return_if_fail (item != NULL);
+
+ gdl_dock_item_restore_position (item);
+}
+
void
gdl_dock_item_save_layout (GdlDockItem *item,
Index: gdl/gdl-dock-item.h
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock-item.h,v
retrieving revision 1.2
diff -u -r1.2 gdl-dock-item.h
--- gdl/gdl-dock-item.h 2001/10/10 13:09:14 1.2
+++ gdl/gdl-dock-item.h 2001/12/02 08:20:55
@@ -14,6 +14,7 @@
#define GDL_IS_DOCK_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_ITEM))
#define GDL_DOCK_ITEM_IS_FLOATING(item) ((item)->is_floating)
+#define GDL_DOCK_ITEM_IS_SHOWN(item) (GTK_WIDGET (item)->parent)
#define GDL_DOCK_ITEM_IS_BOUND(item) ((item)->dock != NULL)
@@ -64,9 +65,6 @@
gchar *long_name;
GdlDockItemBehavior behavior;
- /* FIXME: this should go away and be replaced using layout managment
- functions */
- GdlDockPlacement placement;
GtkOrientation orientation;
GtkWidget *dock;
GtkWidget *tab_label;
@@ -87,6 +85,11 @@
/* these should be gint and not guint... trust me */
gint float_width, float_height;
+
+ struct {
+ GdlDockPlacement position;
+ gchar *peer;
+ } last_pos;
};
/* structure for drag_request return information */
@@ -98,6 +101,7 @@
GdkRectangle rect; /* where will the item dock */
};
+
struct _GdlDockItemClass {
GtkBinClass parent_class;
@@ -122,6 +126,10 @@
xmlNodePtr node);
void (* item_hide) (GdlDockItem *item);
+
+ gchar * (* get_pos_hint) (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position);
};
@@ -166,8 +174,13 @@
void gdl_dock_item_hide (GdlDockItem *item);
+void gdl_dock_item_show (GdlDockItem *item);
+
void gdl_dock_item_save_layout (GdlDockItem *item,
xmlNodePtr node);
+gchar *gdl_dock_item_get_pos_hint (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position);
#endif
Index: gdl/gdl-dock-notebook.c
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock-notebook.c,v
retrieving revision 1.3
diff -u -r1.3 gdl-dock-notebook.c
--- gdl/gdl-dock-notebook.c 2001/11/10 14:52:24 1.3
+++ gdl/gdl-dock-notebook.c 2001/12/02 08:20:56
@@ -36,6 +36,10 @@
static void gdl_dock_notebook_hide_foreach (GtkWidget *widget,
gpointer data);
+static gchar *gdl_dock_notebook_get_pos_hint (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position);
+
/* Class variables and definitions */
static GdlDockItemClass *parent_class = NULL;
@@ -66,6 +70,7 @@
item_class->set_orientation = gdl_dock_notebook_set_orientation;
item_class->save_layout = gdl_dock_notebook_layout_save;
item_class->item_hide = gdl_dock_notebook_hide;
+ item_class->get_pos_hint = gdl_dock_notebook_get_pos_hint;
}
static void
@@ -95,10 +100,12 @@
gdl_dock_item_window_sink (item);
label = gdl_dock_item_get_tablabel (item);
- if (!label)
- /* FIXME: get long name, and do it with gtk_object_get */
- label = gtk_label_new (item->name);
- else if (GDL_IS_DOCK_TABLABEL (label)) {
+ if (!label) {
+ if (item->long_name)
+ label = gtk_label_new (item->long_name);
+ else
+ label = gtk_label_new (item->name);
+ } else if (GDL_IS_DOCK_TABLABEL (label)) {
gdl_dock_tablabel_deactivate (GDL_DOCK_TABLABEL (label));
/* hide the item drag handle, as we will use the tablabel's */
gdl_dock_item_hide_handle (item);
@@ -282,6 +289,61 @@
gdl_dock_item_hide (GDL_DOCK_ITEM (widget));
}
+
+static gchar *
+gdl_dock_notebook_get_pos_hint (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position)
+{
+ GdlDockNotebook *notebook;
+ GList *pages, *l;
+ gchar *ret_val = NULL;
+ GdlDockItem *child;
+ GdlDockPlacement place;
+
+ g_return_val_if_fail (item != NULL, NULL);
+
+ notebook = GDL_DOCK_NOTEBOOK (item);
+ l = pages = gtk_container_children (GTK_CONTAINER (notebook->notebook));
+
+ if (caller) {
+ gboolean caller_found = FALSE;
+
+ while (l && !(ret_val && caller_found)) {
+ /* find caller among children and a peer with name */
+ child = GDL_DOCK_ITEM (l->data);
+ if (child == caller)
+ caller_found = TRUE;
+ else if (!ret_val)
+ ret_val = gdl_dock_item_get_pos_hint (child, NULL, &place);
+
+ l = l->next;
+ };
+
+ if (caller_found)
+ *position = GDL_DOCK_CENTER;
+ else
+ g_warning (_("gdl_dock_notebook_get_pos_hint called with a caller "
+ "not among notebook's children"));
+
+ } else {
+ if (item->name)
+ ret_val = g_strdup (item->name);
+ else {
+ /* traverse children looking for a named item */
+ while (l && !ret_val) {
+ child = GDL_DOCK_ITEM (l->data);
+ ret_val = gdl_dock_item_get_pos_hint (child, NULL, &place);
+ l = l->next;
+ };
+ };
+ };
+
+ g_list_free (pages);
+
+ return ret_val;
+}
+
/* Public interface */
Index: gdl/gdl-dock-paned.c
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock-paned.c,v
retrieving revision 1.2
diff -u -r1.2 gdl-dock-paned.c
--- gdl/gdl-dock-paned.c 2001/10/10 13:09:14 1.2
+++ gdl/gdl-dock-paned.c 2001/12/02 08:21:00
@@ -106,6 +106,10 @@
xmlNodePtr node);
static void gdl_dock_paned_hide (GdlDockItem *item);
+static gchar *gdl_dock_paned_get_pos_hint (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position);
+
static GdlDockItemClass *parent_class = NULL;
@@ -153,7 +157,8 @@
dock_item_class->set_orientation = gdl_dock_paned_set_orientation;
dock_item_class->save_layout = gdl_dock_paned_layout_save;
dock_item_class->item_hide = gdl_dock_paned_hide;
-
+ dock_item_class->get_pos_hint = gdl_dock_paned_get_pos_hint;
+
gtk_object_add_arg_type("GdlDockPaned::handle_size", GTK_TYPE_UINT,
GTK_ARG_READWRITE, ARG_HANDLE_SIZE);
gtk_object_add_arg_type("GdlDockPaned::quantum", GTK_TYPE_UINT,
@@ -1233,6 +1238,63 @@
/* Auto reduce parent. */
if (parent && GDL_IS_DOCK_ITEM (parent))
gdl_dock_item_auto_reduce (GDL_DOCK_ITEM (parent));
+}
+
+static gchar *
+gdl_dock_paned_get_pos_hint (GdlDockItem *item,
+ GdlDockItem *caller,
+ GdlDockPlacement *position)
+{
+ GdlDockPaned *paned;
+
+ g_return_val_if_fail (item != NULL, NULL);
+
+ paned = GDL_DOCK_PANED (item);
+ if (caller) {
+ GdlDockPlacement place;
+
+ /* going up the hierarchy */
+ /* FIXME: handle the case when the item has not been auto_reduced
+ and propagate the call to the parent */
+ if (GTK_WIDGET (caller) == paned->child1) {
+ if (item->orientation == GTK_ORIENTATION_HORIZONTAL)
+ *position = GDL_DOCK_LEFT;
+ else
+ *position = GDL_DOCK_TOP;
+ return gdl_dock_item_get_pos_hint (GDL_DOCK_ITEM (paned->child2),
+ NULL, &place);
+
+ }
+ else if (GTK_WIDGET (caller) == paned->child2) {
+ if (item->orientation == GTK_ORIENTATION_HORIZONTAL)
+ *position = GDL_DOCK_RIGHT;
+ else
+ *position = GDL_DOCK_BOTTOM;
+ return gdl_dock_item_get_pos_hint (GDL_DOCK_ITEM (paned->child1),
+ NULL, &place);
+
+ }
+ else {
+ g_warning (_("gdl_dock_paned_get_pos_hint called with a "
+ "contained child"));
+ return NULL;
+ };
+
+ } else {
+ /* going down the hierarchy */
+ if (item->name)
+ return g_strdup (item->name);
+
+ /* try with our children */
+ if (paned->child1)
+ return gdl_dock_item_get_pos_hint (GDL_DOCK_ITEM (paned->child1),
+ NULL, position);
+ else if (paned->child2)
+ return gdl_dock_item_get_pos_hint (GDL_DOCK_ITEM (paned->child2),
+ NULL, position);
+ else
+ return NULL;
+ };
}
Index: gdl/gdl-dock-tablabel.c
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock-tablabel.c,v
retrieving revision 1.1
diff -u -r1.1 gdl-dock-tablabel.c
--- gdl/gdl-dock-tablabel.c 2001/10/10 13:09:14 1.1
+++ gdl/gdl-dock-tablabel.c 2001/12/02 08:21:01
@@ -260,10 +260,12 @@
child_allocation.y = border_width;
if (tablabel->orientation == GTK_ORIENTATION_HORIZONTAL) {
- allocation->width -= tablabel->drag_handle_size;
+ allocation->width = MAX (1, (int) allocation->width -
+ (int) tablabel->drag_handle_size);
child_allocation.x += tablabel->drag_handle_size;
} else {
- allocation->height -= tablabel->drag_handle_size;
+ allocation->height = MAX (1, (int) allocation->height -
+ (int) tablabel->drag_handle_size);
};
child_allocation.width =
Index: gdl/gdl-dock.c
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock.c,v
retrieving revision 1.5
diff -u -r1.5 gdl-dock.c
--- gdl/gdl-dock.c 2001/11/21 23:05:04 1.5
+++ gdl/gdl-dock.c 2001/12/02 08:21:04
@@ -1025,3 +1025,11 @@
else
return NULL;
}
+
+GList *
+gdl_dock_get_named_items (GdlDock *dock)
+{
+ g_return_val_if_fail (dock != NULL, NULL);
+
+ return g_list_copy (dock->items);
+}
Index: gdl/gdl-dock.h
===================================================================
RCS file: /cvs/gnome/gdl/gdl/gdl-dock.h,v
retrieving revision 1.2
diff -u -r1.2 gdl-dock.h
--- gdl/gdl-dock.h 2001/10/10 13:09:14 1.2
+++ gdl/gdl-dock.h 2001/12/02 08:21:04
@@ -66,4 +66,6 @@
void gdl_dock_layout_save (GdlDock *dock,
xmlNodePtr node);
+GList *gdl_dock_get_named_items (GdlDock *dock);
+
#endif
[Date Prev][
Date Next] [Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]