/* bonobo-dock-band.c
Copyright (C) 1998 Free Software Foundation
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Ettore Perazzoli <ettore@comm2000.it>
*/
#include <config.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <libgnome/gnome-macros.h>
#include "bonobo-dock.h"
#include "bonobo-dock-band.h"
#include "bonobo-dock-item.h"
GNOME_CLASS_BOILERPLATE (BonoboDockBand, bonobo_dock_band,
GtkContainer, GTK_TYPE_CONTAINER)
#define noBONOBO_DOCK_BAND_DEBUG
/* FIXME: To be removed. */
#if defined BONOBO_DOCK_BAND_DEBUG && defined __GNUC__
#define DEBUG(x) \
do \
{ \
printf ("%s.%d: ", __FUNCTION__, __LINE__); \
printf x; \
putchar ('\n'); \
} \
while (0)
#else
#define DEBUG(x)
#endif
static void bonobo_dock_band_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void bonobo_dock_band_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void bonobo_dock_band_map (GtkWidget *widget);
static void bonobo_dock_band_unmap (GtkWidget *widget);
static void bonobo_dock_band_add (GtkContainer *container,
GtkWidget *child);
static void bonobo_dock_band_remove (GtkContainer *container,
GtkWidget *widget);
static void bonobo_dock_band_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static void bonobo_dock_band_finalize (GObject *object);
static void size_allocate_child (BonoboDockBand *band,
BonoboDockBandChild *child,
guint space,
GtkAllocation *child_allocation);
static void size_allocate_small (BonoboDockBand *band,
GtkAllocation *allocation,
guint space,
guint requested_space);
static gboolean docking_allowed (BonoboDockBand *band,
BonoboDockItem *item);
static GList *find_child (BonoboDockBand *band,
GtkWidget *child);
static GList *prev_if_floating (BonoboDockBand *band,
GList *c);
static GList *next_if_floating (BonoboDockBand *band,
GList *c);
static GList *prev_not_floating (BonoboDockBand *band,
GList *c);
static GList *next_not_floating (BonoboDockBand *band,
GList *c);
static void calc_prev_and_foll_space (BonoboDockBand *band);
static guint attempt_move_backward (BonoboDockBand *band,
GList *child,
guint amount);
static guint attempt_move_forward (BonoboDockBand *band,
GList *child,
guint amount);
static gboolean dock_nonempty (BonoboDockBand *band,
BonoboDockItem *item,
GList *where,
gint x, gint y);
static gboolean dock_empty (BonoboDockBand *band,
BonoboDockItem *item,
GList *where,
gint x, gint y);
static gboolean dock_empty_right (BonoboDockBand *band,
BonoboDockItem *item,
GList *where,
gint x, gint y);
static gboolean check_guint_arg (GObject *object,
const gchar *name,
guint *value_return);
static void
bonobo_dock_band_class_init (BonoboDockBandClass *klass)
{
GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
gobject_class = (GObjectClass *) klass;
widget_class = (GtkWidgetClass *) klass;
container_class = (GtkContainerClass *) klass;
gobject_class->finalize = bonobo_dock_band_finalize;
widget_class->map = bonobo_dock_band_map;
widget_class->unmap = bonobo_dock_band_unmap;
widget_class->size_request = bonobo_dock_band_size_request;
widget_class->size_allocate = bonobo_dock_band_size_allocate;
container_class->add = bonobo_dock_band_add;
container_class->remove = bonobo_dock_band_remove;
container_class->forall = bonobo_dock_band_forall;
}
static void
bonobo_dock_band_instance_init (BonoboDockBand *band)
{
GtkWidget *widget = GTK_WIDGET (band);
GTK_WIDGET_SET_FLAGS (band, GTK_NO_WINDOW);
band->_priv = NULL;
band->orientation = GTK_ORIENTATION_HORIZONTAL;
band->children = NULL;
band->num_children = 0;
band->floating_child = NULL;
band->doing_drag = FALSE;
band->max_space_requisition = 0;
band->tot_offsets = 0;
band->drag_allocation.x = band->drag_allocation.y = -1;
band->drag_allocation.width = band->drag_allocation.height = 0;
band->new_for_drag = FALSE;
if (GTK_WIDGET_VISIBLE (widget))
gtk_widget_queue_resize (widget);
}
static void
bonobo_dock_band_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
BonoboDockBand *band;
GList *lp;
DEBUG (("entering function"));
band = BONOBO_DOCK_BAND (widget);
band->max_space_requisition = 0;
band->tot_offsets = 0;
requisition->width = 0;
requisition->height = 0;
for (lp = band->children; lp != NULL; lp = lp->next)
{
BonoboDockBandChild *c = lp->data;
if (GTK_WIDGET_VISIBLE (c->widget))
{
GtkRequisition req;
req.width = req.height = 0;
if (BONOBO_IS_DOCK_ITEM (c->widget))
bonobo_dock_item_handle_size_request(BONOBO_DOCK_ITEM (c->widget),
&req);
else
gtk_widget_size_request (c->widget, &req);
if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
{
gboolean has_preferred_width;
guint preferred_width;
has_preferred_width = check_guint_arg (G_OBJECT (c->widget),
"preferred_width",
&preferred_width);
if (has_preferred_width)
c->max_space_requisition = MAX ((int)preferred_width, req.width);
else
c->max_space_requisition = req.width;
}
else
{
gboolean has_preferred_height;
guint preferred_height;