Re: cascading size callbacks
- From: Havoc Pennington <hp redhat com>
- To: Paul Davis <pbd Op Net>
- Cc: gtk-list gnome org
- Subject: Re: cascading size callbacks
- Date: 09 Mar 2002 09:31:40 -0500
Paul Davis <pbd Op Net> writes:
> lets suppose i use a fixed or a layout widget to put children
> inside. i want the position of the children to be based on a
> fractional coordinate system (0..1.0). this means that when the parent
> changes size, i need to move the children.
>
> it seemed to me that the obvious thing to do was to use the
> size_allocate signal to drive the repositioning of the children. so i
> tried it. it ends up causing a cascade of size_allocate events that
> ripple all the way to the top level window on a repeated basis?
>
There's nothing weird about what you want to do - GtkAlignment does it
pretty much exactly, and most containers do it in general.
However it's normally done by overriding size_allocate in a container
subclass. Moving children under the nose of fixed/layout probably
won't work so well.
BTW, I recently wrote an "enhanced fixed" for the Eclipse project that
you might like. It supports widget Z-order and negative coordinates
and so forth. The expose_event and draw handlers should be deleted for
GTK 2 (letting the default container implementation of expose do the
work).
Havoc
/* Copyright 2001, Havoc Pennington and others */
/* Contributors:
* Havoc Pennington - the original version
* Boris Shingarov (OTI) - minor modifications for GTK2; JNI layer
*/
/* Derived from GtkFixed from GTK+:
* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This 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.
*
* This 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 this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at <A HREF="ftp://ftp.gtk.org/pub/gtk/">ftp://ftp.gtk.org/pub/gtk/</A>.
*/
#include <gdk/gdk.h>
#include <gtk/gtkcontainer.h>
#define ECLIPSE_TYPE_FIXED (eclipse_fixed_get_type ())
#define ECLIPSE_FIXED(obj) (GTK_CHECK_CAST ((obj), ECLIPSE_TYPE_FIXED, EclipseFixed))
#define ECLIPSE_FIXED_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), ECLIPSE_TYPE_FIXED, EclipseFixedClass))
#define GTK_IS_ECLIPSE_FIXED(obj) (GTK_CHECK_TYPE ((obj), ECLIPSE_TYPE_FIXED))
#define GTK_IS_FIXED_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), ECLIPSE_TYPE_FIXED))
typedef struct _EclipseFixed EclipseFixed;
typedef struct _EclipseFixedClass EclipseFixedClass;
typedef struct _EclipseFixedChild EclipseFixedChild;
struct _EclipseFixed
{
GtkContainer container;
GList *children;
};
struct _EclipseFixedClass
{
GtkContainerClass parent_class;
};
struct _EclipseFixedChild
{
GtkWidget *widget;
int x;
int y;
int width;
int height;
};
GtkType eclipse_fixed_get_type (void) G_GNUC_CONST;
GtkWidget* eclipse_fixed_new (void);
void eclipse_fixed_set_location (EclipseFixed *fixed,
GtkWidget *widget,
int x,
int y);
void eclipse_fixed_set_size (EclipseFixed *fixed,
GtkWidget *widget,
int width,
int height);
void eclipse_fixed_move_above (EclipseFixed *fixed,
GtkWidget *widget,
GtkWidget *sibling);
void eclipse_fixed_move_below (EclipseFixed *fixed,
GtkWidget *widget,
GtkWidget *sibling);
/* Copyright 2001, Havoc Pennington and others */
/* Contributors:
* Havoc Pennington - the original version
* Boris Shingarov (OTI) - minor modifications for GTK2; JNI layer
*/
/* Derived from EclipseFixed in GTK+:
* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This 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.
*
* This 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 this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at <A HREF="ftp://ftp.gtk.org/pub/gtk/">ftp://ftp.gtk.org/pub/gtk/</A>.
*/
#include "eclipsefixed.h"
#include "swt.h"
static void eclipse_fixed_class_init (EclipseFixedClass *klass);
static void eclipse_fixed_init (EclipseFixed *fixed);
static void eclipse_fixed_map (GtkWidget *widget);
static void eclipse_fixed_realize (GtkWidget *widget);
static void eclipse_fixed_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void eclipse_fixed_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void eclipse_fixed_paint (GtkWidget *widget,
GdkRectangle *area);
static void eclipse_fixed_draw (GtkWidget *widget,
GdkRectangle *area);
static gint eclipse_fixed_expose (GtkWidget *widget,
GdkEventExpose *event);
static void eclipse_fixed_add (GtkContainer *container,
GtkWidget *widget);
static void eclipse_fixed_remove (GtkContainer *container,
GtkWidget *widget);
static void eclipse_fixed_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static GtkType eclipse_fixed_child_type (GtkContainer *container);
static void move_gdk_window_above (GdkWindow *window,
GdkWindow *sibling);
static void move_gdk_window_below (GdkWindow *window,
GdkWindow *sibling);
static GtkContainerClass *parent_class = NULL;
GtkType
eclipse_fixed_get_type (void)
{
static GtkType fixed_type = 0;
if (!fixed_type)
{
static const GtkTypeInfo fixed_info =
{
"EclipseFixed",
sizeof (EclipseFixed),
sizeof (EclipseFixedClass),
(GtkClassInitFunc) eclipse_fixed_class_init,
(GtkObjectInitFunc) eclipse_fixed_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
fixed_type = gtk_type_unique (GTK_TYPE_CONTAINER, &fixed_info);
}
return fixed_type;
}
static void
eclipse_fixed_class_init (EclipseFixedClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
container_class = (GtkContainerClass*) class;
parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
widget_class->realize = eclipse_fixed_realize;
widget_class->size_request = eclipse_fixed_size_request;
widget_class->size_allocate = eclipse_fixed_size_allocate;
container_class->add = eclipse_fixed_add;
container_class->remove = eclipse_fixed_remove;
container_class->forall = eclipse_fixed_forall;
container_class->child_type = eclipse_fixed_child_type;
/* container_class->set_child_property = eclipse_fixed_set_child_property;
container_class->get_child_property = eclipse_fixed_get_child_property;*/
}
static GtkType
eclipse_fixed_child_type (GtkContainer *container)
{
return GTK_TYPE_WIDGET;
}
static void
eclipse_fixed_init (EclipseFixed *fixed)
{
GTK_WIDGET_SET_FLAGS (fixed, GTK_NO_WINDOW);
fixed->children = NULL;
}
static void
eclipse_fixed_realize (GtkWidget *widget)
{
GdkWindowAttr attributes;
gint attributes_mask;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (widget));
if (GTK_WIDGET_NO_WINDOW (widget))
GTK_WIDGET_CLASS (parent_class)->realize (widget);
else
{
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.width = widget->allocation.width;
attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
attributes.colormap = gtk_widget_get_colormap (widget);
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
attributes_mask);
gdk_window_set_user_data (widget->window, widget);
widget->style = gtk_style_attach (widget->style, widget->window);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
}
}
GtkWidget*
eclipse_fixed_new (void)
{
EclipseFixed *fixed;
fixed = gtk_type_new (ECLIPSE_TYPE_FIXED);
return GTK_WIDGET (fixed);
}
static EclipseFixedChild*
get_child_info (EclipseFixed *fixed,
GtkWidget *widget)
{
GList *children;
EclipseFixedChild *child_info;
children = fixed->children;
while (children)
{
child_info = children->data;
children = children->next;
if (child_info->widget == widget)
return child_info;
}
return NULL;
}
void
eclipse_fixed_set_location (EclipseFixed *fixed,
GtkWidget *widget,
int x,
int y)
{
EclipseFixedChild *child_info;
g_return_if_fail (fixed != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (fixed));
g_return_if_fail (widget != NULL);
g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
child_info = get_child_info (fixed, widget);
if (child_info->x == x && child_info->y == y)
return; /* nothing to do */
child_info->x = x;
child_info->y = y;
if (GTK_WIDGET_VISIBLE (fixed) && GTK_WIDGET_VISIBLE (widget))
gtk_widget_queue_resize (GTK_WIDGET (fixed));
}
/* set size to -1 to use natural size */
void
eclipse_fixed_set_size (EclipseFixed *fixed,
GtkWidget *widget,
int width,
int height)
{
EclipseFixedChild *child_info;
g_return_if_fail (fixed != NULL);
if (!GTK_IS_ECLIPSE_FIXED (fixed)) { printf("hey, %s\n", -1); }
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (fixed));
g_return_if_fail (widget != NULL);
g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
child_info = get_child_info (fixed, widget);
if (child_info->width == width && child_info->height == height)
return; /* nothing to do */
child_info->width = width;
child_info->height = height;
if (GTK_WIDGET_VISIBLE (fixed) && GTK_WIDGET_VISIBLE (widget))
gtk_widget_queue_resize (GTK_WIDGET (fixed));
}
static GList*
find_link (EclipseFixed *fixed,
GtkWidget *widget)
{
GList *tmp;
tmp = fixed->children;
while (tmp != NULL)
{
if (((EclipseFixedChild*)tmp->data)->widget == widget)
return tmp;
tmp = tmp->next;
}
return NULL;
}
static void
find_sibling_windows (EclipseFixed *fixed,
GtkWidget *widget,
GdkWindow **above,
GdkWindow **below)
{
GList *tmp;
gboolean seen_ourselves;
seen_ourselves = FALSE;
if (below)
*below = NULL;
if (above)
*above = NULL;
tmp = fixed->children;
while (tmp != NULL)
{
EclipseFixedChild *child = tmp->data;
if (child->widget == widget)
{
seen_ourselves = TRUE;
}
else if (below && !seen_ourselves)
{
if (*below == NULL &&
!GTK_WIDGET_NO_WINDOW (child->widget) &&
GTK_WIDGET_REALIZED (child->widget))
*below = child->widget->window;
}
else if (above && seen_ourselves)
{
if (*above == NULL &&
!GTK_WIDGET_NO_WINDOW (child->widget) &&
GTK_WIDGET_REALIZED (child->widget))
*above = child->widget->window;
}
tmp = tmp->next;
}
}
/* sibling == NULL means raise to top */
void
eclipse_fixed_move_above (EclipseFixed *fixed,
GtkWidget *widget,
GtkWidget *sibling)
{
GList *sibling_link;
GList *widget_link;
g_return_if_fail (fixed != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (fixed));
g_return_if_fail (widget != sibling);
g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
g_return_if_fail (sibling == NULL || sibling->parent == GTK_WIDGET (fixed));
sibling_link = find_link (fixed, sibling);
widget_link = find_link (fixed, widget);
g_assert (widget_link);
/* remove widget link */
fixed->children = g_list_remove_link (fixed->children, widget_link);
if (sibling_link)
{
GdkWindow *above, *below;
widget_link->prev = sibling_link;
widget_link->next = sibling_link->next;
if (widget_link->next)
widget_link->next->prev = widget_link;
sibling_link->next = widget_link;
if (!GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REALIZED (widget))
{
find_sibling_windows (fixed, widget, &above, &below);
if (below)
move_gdk_window_above (widget->window, below);
else if (above)
move_gdk_window_below (widget->window, above);
}
}
else
{
if (!GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REALIZED (widget))
gdk_window_raise (widget->window);
fixed->children = g_list_append (fixed->children, widget_link->data);
g_list_free_1 (widget_link);
}
/* Redraw no-window widgets, window widgets will do fine
* on their own
*/
if (GTK_WIDGET_NO_WINDOW (widget))
gtk_widget_queue_draw (widget);
if (sibling && GTK_WIDGET_NO_WINDOW (sibling))
gtk_widget_queue_draw (sibling);
}
/* sibling == NULL means lower to bottom */
void
eclipse_fixed_move_below (EclipseFixed *fixed,
GtkWidget *widget,
GtkWidget *sibling)
{
GList *sibling_link;
GList *widget_link;
g_return_if_fail (fixed != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (fixed));
g_return_if_fail (widget != sibling);
g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
g_return_if_fail (sibling == NULL || sibling->parent == GTK_WIDGET (fixed));
sibling_link = find_link (fixed, sibling);
widget_link = find_link (fixed, widget);
g_assert (widget_link);
/* remove widget link */
fixed->children = g_list_remove_link (fixed->children, widget_link);
if (sibling_link)
{
GdkWindow *above, *below;
widget_link->next = sibling_link;
widget_link->prev = sibling_link->prev;
if (widget_link->prev)
widget_link->prev->next = widget_link;
sibling_link->prev = widget_link;
if (widget_link->prev == NULL)
fixed->children = widget_link;
if (!GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REALIZED (widget))
{
find_sibling_windows (fixed, widget, &above, &below);
if (above)
move_gdk_window_below (widget->window, above);
else if (below)
move_gdk_window_above (widget->window, below);
}
}
else
{
if (!GTK_WIDGET_NO_WINDOW (widget) & GTK_WIDGET_REALIZED (widget))
gdk_window_lower (widget->window);
fixed->children = g_list_prepend (fixed->children, widget_link->data);
g_list_free_1 (widget_link);
}
/* Redraw no-window widgets, window widgets will do fine
* on their own
*/
if (GTK_WIDGET_NO_WINDOW (widget))
gtk_widget_queue_draw (widget);
if (sibling && GTK_WIDGET_NO_WINDOW (sibling))
gtk_widget_queue_draw (sibling);
}
static void
eclipse_fixed_map (GtkWidget *widget)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GList *children;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (widget));
GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
fixed = ECLIPSE_FIXED (widget);
/* First we need to realize all children and fix their
* stacking order, before we map them
*/
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
if (GTK_WIDGET_VISIBLE (child->widget) &&
!GTK_WIDGET_REALIZED (child->widget))
gtk_widget_realize (child->widget);
if (!GTK_WIDGET_NO_WINDOW (child->widget))
gdk_window_raise (child->widget->window);
}
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
if (GTK_WIDGET_VISIBLE (child->widget) &&
!GTK_WIDGET_MAPPED (child->widget))
gtk_widget_map (child->widget);
}
}
static void
eclipse_fixed_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GList *children;
GtkRequisition child_requisition;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (widget));
g_return_if_fail (requisition != NULL);
fixed = ECLIPSE_FIXED (widget);
requisition->width = 0;
requisition->height = 0;
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
if (GTK_WIDGET_VISIBLE (child->widget))
{
int w, h;
gtk_widget_size_request (child->widget, &child_requisition);
w = child->width < 0 ? child_requisition.width : child->width;
h = child->height < 0 ? child_requisition.height : child->height;
requisition->height = MAX (requisition->height,
child->y + h);
requisition->width = MAX (requisition->width,
child->x + w);
}
}
requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
}
static void
eclipse_fixed_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GtkAllocation child_allocation;
GtkRequisition child_requisition;
GList *children;
int border_width;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED(widget));
g_return_if_fail (allocation != NULL);
fixed = ECLIPSE_FIXED (widget);
widget->allocation = *allocation;
border_width = GTK_CONTAINER (fixed)->border_width;
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
if (GTK_WIDGET_VISIBLE (child->widget))
{
gtk_widget_get_child_requisition (child->widget, &child_requisition);
child_allocation.x = child->x + border_width;
child_allocation.y = child->y + border_width;
child_allocation.width = child->width < 0 ? child_requisition.width : child->width;
child_allocation.height = child->height < 0 ? child_requisition.height : child->height;
gtk_widget_size_allocate (child->widget, &child_allocation);
}
}
}
static void
eclipse_fixed_paint (GtkWidget *widget,
GdkRectangle *area)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (widget));
g_return_if_fail (area != NULL);
if (GTK_WIDGET_DRAWABLE (widget))
gdk_window_clear_area (widget->window,
area->x, area->y,
area->width, area->height);
}
static void
eclipse_fixed_draw (GtkWidget *widget,
GdkRectangle *area)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GdkRectangle child_area;
GList *children;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (widget));
/* Note that we draw from front of fixed->children to back
* which means the stacking order is supposed to be that
*/
if (GTK_WIDGET_DRAWABLE (widget))
{
fixed = ECLIPSE_FIXED (widget);
eclipse_fixed_paint (widget, area);
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
if (gtk_widget_intersect (child->widget, area, &child_area))
gtk_widget_draw (child->widget, &child_area);
}
}
}
static gint
eclipse_fixed_expose (GtkWidget *widget,
GdkEventExpose *event)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GdkEventExpose child_event;
GList *children;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_ECLIPSE_FIXED (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
if (GTK_WIDGET_DRAWABLE (widget))
{
fixed = ECLIPSE_FIXED (widget);
child_event = *event;
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
if (GTK_WIDGET_NO_WINDOW (child->widget) &
gtk_widget_intersect (child->widget, &event->area,
&child_event.area))
gtk_widget_event (child->widget, (GdkEvent*) &child_event);
}
}
return FALSE;
}
static void
eclipse_fixed_add (GtkContainer *container,
GtkWidget *widget)
{
EclipseFixedChild *child_info;
EclipseFixed *fixed;
g_return_if_fail (container != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (container));
g_return_if_fail (widget != NULL);
fixed = ECLIPSE_FIXED (container);
child_info = g_new (EclipseFixedChild, 1);
child_info->widget = widget;
child_info->x = 0;
child_info->y = 0;
child_info->width = -1;
child_info->height = -1;
gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
/* Add at top of stacking order (append) */
fixed->children = g_list_append (fixed->children, child_info);
if (GTK_WIDGET_REALIZED (fixed))
gtk_widget_realize (widget);
if (GTK_WIDGET_VISIBLE (fixed) && GTK_WIDGET_VISIBLE (widget))
{
if (GTK_WIDGET_MAPPED (fixed))
gtk_widget_map (widget);
gtk_widget_queue_resize (GTK_WIDGET (fixed));
}
}
static void
eclipse_fixed_remove (GtkContainer *container,
GtkWidget *widget)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GList *children;
g_return_if_fail (container != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (container));
g_return_if_fail (widget != NULL);
fixed = ECLIPSE_FIXED (container);
children = fixed->children;
while (children)
{
child = children->data;
if (child->widget == widget)
{
gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
gtk_widget_unparent (widget);
fixed->children = g_list_remove_link (fixed->children, children);
g_list_free (children);
g_free (child);
if (was_visible && GTK_WIDGET_VISIBLE (container))
gtk_widget_queue_resize (GTK_WIDGET (container));
break;
}
children = children->next;
}
}
static void
eclipse_fixed_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data)
{
EclipseFixed *fixed;
EclipseFixedChild *child;
GList *children;
g_return_if_fail (container != NULL);
g_return_if_fail (GTK_IS_ECLIPSE_FIXED (container));
g_return_if_fail (callback != NULL);
fixed = ECLIPSE_FIXED (container);
children = fixed->children;
while (children)
{
child = children->data;
children = children->next;
(* callback) (child->widget, callback_data);
}
}
#include <gdk/gdkx.h>
static void
move_gdk_window_above (GdkWindow *window,
GdkWindow *sibling)
{
XWindowChanges changes;
changes.sibling = GDK_WINDOW_XWINDOW (sibling);
changes.stack_mode = Above;
XConfigureWindow (gdk_display,
GDK_WINDOW_XWINDOW (window),
CWSibling | CWStackMode,
&changes);
}
static void
move_gdk_window_below (GdkWindow *window,
GdkWindow *sibling)
{
XWindowChanges changes;
changes.sibling = GDK_WINDOW_XWINDOW (sibling);
changes.stack_mode = Below;
XConfigureWindow (gdk_display,
GDK_WINDOW_XWINDOW (window),
CWSibling | CWStackMode,
&changes);
}
#if 1
/* Test program
* Compile with:
* gcc `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` -I/opt/IBMvame1.4/ive/bin/include eclipsefixed.c
*/
#include <gtk/gtk.h>
static void
raise_to_top (GtkWidget *button,
GtkWidget *fixed)
{
eclipse_fixed_move_above (ECLIPSE_FIXED (fixed), button, NULL);
}
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *frame;
GtkWidget *fixed;
GtkWidget *button1;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
frame = gtk_frame_new ("Frame");
fixed = eclipse_fixed_new ();
/* Add them in upside-down order */
button1 = gtk_button_new_with_label ("On Top");
gtk_container_add (GTK_CONTAINER (fixed), button1);
eclipse_fixed_set_location (ECLIPSE_FIXED (fixed), button1, 5, 5);
eclipse_fixed_set_size (ECLIPSE_FIXED (fixed), button1, 100, 30);
/* Make clicking buttons restack them */
gtk_signal_connect (GTK_OBJECT (button1), "clicked",
GTK_SIGNAL_FUNC (raise_to_top),
fixed);
gtk_container_add (GTK_CONTAINER (window), frame);
gtk_container_add (GTK_CONTAINER (frame), fixed);
gtk_widget_show_all (window);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit),
NULL);
gtk_main ();
return 0;
}
#endif
/*
* SWT JNI Exports
*/
JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1new
(JNIEnv *env, jclass that)
{
return (jint)eclipse_fixed_new();
}
JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1get_1location
(JNIEnv *env, jclass that, jint fixed, jint child, jintArray loc)
{
EclipseFixedChild *childInfo;
jint *loc1 = NULL;
if (loc) {
loc1 = (*env)->GetIntArrayElements(env, loc, NULL);
childInfo = get_child_info ((EclipseFixed*)fixed, (GtkWidget*) child);
loc1[0] = childInfo->x;
loc1[1] = childInfo->y;
(*env)->ReleaseIntArrayElements(env, loc, loc1, 0);
}
}
JNIEXPORT jboolean JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1get_1size
(JNIEnv *env, jclass that, jint fixed, jint child, jintArray sz)
{
EclipseFixedChild *childInfo;
jint *sz1 = NULL;
if (sz) {
sz1 = (*env)->GetIntArrayElements(env, sz, NULL);
childInfo = get_child_info ((EclipseFixed*)fixed, (GtkWidget*) child);
if (childInfo) {
sz1[0] = childInfo->width;
sz1[1] = childInfo->height;
}
(*env)->ReleaseIntArrayElements(env, sz, sz1, 0);
return (jboolean)(childInfo != 0);
}
}
JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1set_1location
(JNIEnv *env, jclass that, jint fixed, jint child, jint x, jint y)
{
eclipse_fixed_set_location((EclipseFixed*)fixed, (GtkWidget*) child, x, y);
}
JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1set_1size
(JNIEnv *env, jclass that, jint fixed, jint child, jint x, jint y)
{
eclipse_fixed_set_size((EclipseFixed*)fixed, (GtkWidget*) child, x, y);
}
JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1move_1above
(JNIEnv *env, jclass that, jint fixed, jint child, jint sibling)
{
eclipse_fixed_move_above ((EclipseFixed*)fixed, (GtkWidget*) child, (GtkWidget*) sibling);
}
JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_eclipse_1fixed_1move_1below
(JNIEnv *env, jclass that, jint fixed, jint child, jint sibling)
{
eclipse_fixed_move_below ((EclipseFixed*)fixed, (GtkWidget*) child, (GtkWidget*) sibling);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]