forked from AuroraMiddleware/gtk
f37a0627fc
2001-08-07 Havoc Pennington <hp@pobox.com> * gtk/gtkfilesel.c (open_ref_dir): fix a typo. * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink; some fixage is needed here, but nothing simple. Owen understands it. ;-) * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window sizing and positioning. Also, fix bug in compute_geometry_hints (width/height confusion for setting min size). (gtk_window_move): new function (gtk_window_resize): new function (gtk_window_get_size): new function (gtk_window_get_position): new function (gtk_window_parse_geometry): new function * gtk/gtkwidget.c (gtk_widget_set_size_request): new function (gtk_widget_get_size_request): new function (gtk_widget_get_usize): delete, that was a short-lived function ;-) (gtk_widget_set_usize): deprecate (gtk_widget_set_uposition): deprecate, make it a trivial gtk_window_move() wrapper (gtk_widget_class_init): remove x/y/width/height properties, add width_request height_request * demos/*: update to avoid deprecated functions * gtk/gtklayout.c: add x/y child properties * gtk/gtkfixed.c: add x/y child properties, and get rid of uses of "gint16" * tests/testgtk.c (create_window_sizing): lots of tweaks to window sizing test * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that configure events on toplevel windows are always in root window coordinates, following ICCCM spec that all synthetic events are in root window coords already, while real events are in parent window coords. Previously the code assumed that coords of 0,0 were parent window coords, which was really broken. * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix warning * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS and GDK_HINT_USER_SIZE so we can set USSize and USPosition hints in gtk_window_parse_geometry() * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support new USER_POS USER_SIZE hints
516 lines
14 KiB
C
516 lines
14 KiB
C
/* 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 Lesser 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser 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-2000. 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 ftp://ftp.gtk.org/pub/gtk/.
|
|
*/
|
|
|
|
#include "gtkfixed.h"
|
|
#include "gtkintl.h"
|
|
|
|
enum {
|
|
CHILD_PROP_0,
|
|
CHILD_PROP_X,
|
|
CHILD_PROP_Y
|
|
};
|
|
|
|
static void gtk_fixed_class_init (GtkFixedClass *klass);
|
|
static void gtk_fixed_init (GtkFixed *fixed);
|
|
static void gtk_fixed_realize (GtkWidget *widget);
|
|
static void gtk_fixed_size_request (GtkWidget *widget,
|
|
GtkRequisition *requisition);
|
|
static void gtk_fixed_size_allocate (GtkWidget *widget,
|
|
GtkAllocation *allocation);
|
|
static void gtk_fixed_add (GtkContainer *container,
|
|
GtkWidget *widget);
|
|
static void gtk_fixed_remove (GtkContainer *container,
|
|
GtkWidget *widget);
|
|
static void gtk_fixed_forall (GtkContainer *container,
|
|
gboolean include_internals,
|
|
GtkCallback callback,
|
|
gpointer callback_data);
|
|
static GtkType gtk_fixed_child_type (GtkContainer *container);
|
|
|
|
static void gtk_fixed_set_child_property (GtkContainer *container,
|
|
GtkWidget *child,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec);
|
|
static void gtk_fixed_get_child_property (GtkContainer *container,
|
|
GtkWidget *child,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec);
|
|
|
|
static GtkContainerClass *parent_class = NULL;
|
|
|
|
|
|
GtkType
|
|
gtk_fixed_get_type (void)
|
|
{
|
|
static GtkType fixed_type = 0;
|
|
|
|
if (!fixed_type)
|
|
{
|
|
static const GtkTypeInfo fixed_info =
|
|
{
|
|
"GtkFixed",
|
|
sizeof (GtkFixed),
|
|
sizeof (GtkFixedClass),
|
|
(GtkClassInitFunc) gtk_fixed_class_init,
|
|
(GtkObjectInitFunc) gtk_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
|
|
gtk_fixed_class_init (GtkFixedClass *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 = gtk_fixed_realize;
|
|
widget_class->size_request = gtk_fixed_size_request;
|
|
widget_class->size_allocate = gtk_fixed_size_allocate;
|
|
|
|
container_class->add = gtk_fixed_add;
|
|
container_class->remove = gtk_fixed_remove;
|
|
container_class->forall = gtk_fixed_forall;
|
|
container_class->child_type = gtk_fixed_child_type;
|
|
|
|
container_class->set_child_property = gtk_fixed_set_child_property;
|
|
container_class->get_child_property = gtk_fixed_get_child_property;
|
|
|
|
gtk_container_class_install_child_property (container_class,
|
|
CHILD_PROP_X,
|
|
g_param_spec_int ("x",
|
|
_("X position"),
|
|
_("X position of child widget"),
|
|
G_MININT,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE));
|
|
|
|
gtk_container_class_install_child_property (container_class,
|
|
CHILD_PROP_Y,
|
|
g_param_spec_int ("y",
|
|
_("Y position"),
|
|
_("Y position of child widget"),
|
|
G_MININT,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE));
|
|
}
|
|
|
|
static GtkType
|
|
gtk_fixed_child_type (GtkContainer *container)
|
|
{
|
|
return GTK_TYPE_WIDGET;
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_init (GtkFixed *fixed)
|
|
{
|
|
GTK_WIDGET_UNSET_FLAGS (fixed, GTK_NO_WINDOW);
|
|
|
|
fixed->children = NULL;
|
|
}
|
|
|
|
GtkWidget*
|
|
gtk_fixed_new (void)
|
|
{
|
|
GtkFixed *fixed;
|
|
|
|
fixed = gtk_type_new (GTK_TYPE_FIXED);
|
|
return GTK_WIDGET (fixed);
|
|
}
|
|
|
|
static GtkFixedChild*
|
|
get_child (GtkFixed *fixed,
|
|
GtkWidget *widget)
|
|
{
|
|
GList *children;
|
|
|
|
children = fixed->children;
|
|
while (children)
|
|
{
|
|
GtkFixedChild *child;
|
|
|
|
child = children->data;
|
|
children = children->next;
|
|
|
|
if (child->widget == widget)
|
|
return child;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
gtk_fixed_put (GtkFixed *fixed,
|
|
GtkWidget *widget,
|
|
gint x,
|
|
gint y)
|
|
{
|
|
GtkFixedChild *child_info;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED (fixed));
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
child_info = g_new (GtkFixedChild, 1);
|
|
child_info->widget = widget;
|
|
child_info->x = x;
|
|
child_info->y = y;
|
|
|
|
gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
|
|
|
|
fixed->children = g_list_append (fixed->children, child_info);
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_move_internal (GtkFixed *fixed,
|
|
GtkWidget *widget,
|
|
gboolean change_x,
|
|
gint x,
|
|
gboolean change_y,
|
|
gint y)
|
|
{
|
|
GtkFixedChild *child;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED (fixed));
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
|
|
|
|
child = get_child (fixed, widget);
|
|
|
|
g_assert (child);
|
|
|
|
gtk_widget_freeze_child_notify (widget);
|
|
|
|
if (change_x)
|
|
{
|
|
child->x = x;
|
|
gtk_widget_child_notify (widget, "x");
|
|
}
|
|
|
|
if (change_y)
|
|
{
|
|
child->y = y;
|
|
gtk_widget_child_notify (widget, "y");
|
|
}
|
|
|
|
gtk_widget_thaw_child_notify (widget);
|
|
|
|
if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
|
|
gtk_widget_queue_resize (GTK_WIDGET (fixed));
|
|
}
|
|
|
|
void
|
|
gtk_fixed_move (GtkFixed *fixed,
|
|
GtkWidget *widget,
|
|
gint x,
|
|
gint y)
|
|
{
|
|
g_return_if_fail (GTK_IS_FIXED (fixed));
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
|
|
|
|
gtk_fixed_move_internal (fixed, widget, TRUE, x, TRUE, y);
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_set_child_property (GtkContainer *container,
|
|
GtkWidget *child,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id)
|
|
{
|
|
case CHILD_PROP_X:
|
|
gtk_fixed_move_internal (GTK_FIXED (container),
|
|
child,
|
|
TRUE, g_value_get_int (value),
|
|
FALSE, 0);
|
|
break;
|
|
case CHILD_PROP_Y:
|
|
gtk_fixed_move_internal (GTK_FIXED (container),
|
|
child,
|
|
FALSE, 0,
|
|
TRUE, g_value_get_int (value));
|
|
break;
|
|
default:
|
|
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_get_child_property (GtkContainer *container,
|
|
GtkWidget *child,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GtkFixedChild *fixed_child;
|
|
|
|
fixed_child = get_child (GTK_FIXED (container), child);
|
|
|
|
switch (property_id)
|
|
{
|
|
case CHILD_PROP_X:
|
|
g_value_set_int (value, fixed_child->x);
|
|
break;
|
|
case CHILD_PROP_Y:
|
|
g_value_set_int (value, fixed_child->y);
|
|
break;
|
|
default:
|
|
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_map (GtkWidget *widget)
|
|
{
|
|
GtkFixed *fixed;
|
|
GtkFixedChild *child;
|
|
GList *children;
|
|
|
|
GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
|
|
fixed = GTK_FIXED (widget);
|
|
|
|
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);
|
|
}
|
|
|
|
gdk_window_show (widget->window);
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_realize (GtkWidget *widget)
|
|
{
|
|
GdkWindowAttr attributes;
|
|
gint attributes_mask;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED (widget));
|
|
|
|
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);
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_size_request (GtkWidget *widget,
|
|
GtkRequisition *requisition)
|
|
{
|
|
GtkFixed *fixed;
|
|
GtkFixedChild *child;
|
|
GList *children;
|
|
GtkRequisition child_requisition;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED (widget));
|
|
g_return_if_fail (requisition != NULL);
|
|
|
|
fixed = GTK_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))
|
|
{
|
|
gtk_widget_size_request (child->widget, &child_requisition);
|
|
|
|
requisition->height = MAX (requisition->height,
|
|
child->y +
|
|
child_requisition.height);
|
|
requisition->width = MAX (requisition->width,
|
|
child->x +
|
|
child_requisition.width);
|
|
}
|
|
}
|
|
|
|
requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
|
|
requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_size_allocate (GtkWidget *widget,
|
|
GtkAllocation *allocation)
|
|
{
|
|
GtkFixed *fixed;
|
|
GtkFixedChild *child;
|
|
GtkAllocation child_allocation;
|
|
GtkRequisition child_requisition;
|
|
GList *children;
|
|
guint16 border_width;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED(widget));
|
|
g_return_if_fail (allocation != NULL);
|
|
|
|
fixed = GTK_FIXED (widget);
|
|
|
|
widget->allocation = *allocation;
|
|
if (GTK_WIDGET_REALIZED (widget))
|
|
gdk_window_move_resize (widget->window,
|
|
allocation->x,
|
|
allocation->y,
|
|
allocation->width,
|
|
allocation->height);
|
|
|
|
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_requisition.width;
|
|
child_allocation.height = child_requisition.height;
|
|
gtk_widget_size_allocate (child->widget, &child_allocation);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_add (GtkContainer *container,
|
|
GtkWidget *widget)
|
|
{
|
|
g_return_if_fail (GTK_IS_FIXED (container));
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
gtk_fixed_put (GTK_FIXED (container), widget, 0, 0);
|
|
}
|
|
|
|
static void
|
|
gtk_fixed_remove (GtkContainer *container,
|
|
GtkWidget *widget)
|
|
{
|
|
GtkFixed *fixed;
|
|
GtkFixedChild *child;
|
|
GList *children;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED (container));
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
fixed = GTK_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
|
|
gtk_fixed_forall (GtkContainer *container,
|
|
gboolean include_internals,
|
|
GtkCallback callback,
|
|
gpointer callback_data)
|
|
{
|
|
GtkFixed *fixed;
|
|
GtkFixedChild *child;
|
|
GList *children;
|
|
|
|
g_return_if_fail (GTK_IS_FIXED (container));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
fixed = GTK_FIXED (container);
|
|
|
|
children = fixed->children;
|
|
while (children)
|
|
{
|
|
child = children->data;
|
|
children = children->next;
|
|
|
|
(* callback) (child->widget, callback_data);
|
|
}
|
|
}
|