Commit ee1d4392 authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

Added layout widget for scrolling arbitrarily big areas. Added plug/socket

Mon Nov 23 22:10:09 1998  Owen Taylor  <otaylor@redhat.com>

	* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
	gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:

	Added layout widget for scrolling arbitrarily big areas.
	Added plug/socket widgets for interprocess embedding.

	These widgets still, at some point, need to be
	made more pure in their use of GDK, as opposed
	to raw X.

	* gtk/testgtk.c: Added test for layout widget.
parent 42faec17
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
Mon Nov 23 22:10:09 1998 Owen Taylor <otaylor@redhat.com>
* gtk/Makefile.am gtk/gtk.h gtk/gtklayout.[ch]
gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/gtk.h:
Added layout widget for scrolling arbitrarily big areas.
Added plug/socket widgets for interprocess embedding.
These widgets still, at some point, need to be
made more pure in their use of GDK, as opposed
to raw X.
* gtk/testgtk.c: Added test for layout widget.
1998-11-23 Jeff Garzik <jgarzik@pobox.com>
* gtk/gtkclist.c: (gtk_clist_swap_rows): Bugfix from
......
......@@ -3,7 +3,7 @@
SRC_SUBDIRS = gdk gtk
SUBDIRS = $(SRC_SUBDIRS) docs
bin_SCRIPTS = gtk-config
bbin_SCRIPTS = gtk-config
EXTRA_DIST = \
HACKING \
......
......@@ -110,10 +110,6 @@ Additions:
gtk_widget_dnd_data_set (should be guchar * with a copy?
shouldn't be there at all...)
* gtk_rc_add_[name/class]_style are broken for bg pixmaps, because
styles are broken for bg pixmaps, and RC styles only hack around
that.
* Try to rationally deal with someone else deleting one of our
windows??? This would mean keeping track of our window heirarchy
ourselves, for one thing, and will never be safe, because of
......
......@@ -55,6 +55,7 @@ static_sources = \
gtkitem.c \
gtkitemfactory.c \
gtklabel.c \
gtklayout.c \
gtklist.c \
gtklistitem.c \
gtkmain.c \
......@@ -70,6 +71,7 @@ static_sources = \
gtkpacker.c \
gtkpaned.c \
gtkpixmap.c \
gtkplug.c \
gtkpreview.c \
gtkprogress.c \
gtkprogressbar.c \
......@@ -84,6 +86,7 @@ static_sources = \
gtkselection.c \
gtkseparator.c \
gtksignal.c \
gtksocket.c \
gtkspinbutton.c \
gtkstyle.c \
gtkstatusbar.c \
......@@ -169,6 +172,7 @@ source_headers = \
gtkitem.h \
gtkitemfactory.h \
gtklabel.h \
gtklayout.h \
gtklist.h \
gtklistitem.h \
gtkmain.h \
......@@ -184,6 +188,7 @@ source_headers = \
gtkpacker.h \
gtkpaned.h \
gtkpixmap.h \
gtkplug.h \
gtkpreview.h \
gtkprivate.h \
gtkprogress.h \
......@@ -199,6 +204,7 @@ source_headers = \
gtkselection.h \
gtkseparator.h \
gtksignal.h \
gtksocket.h \
gtkspinbutton.h \
gtkstyle.h \
gtkstatusbar.h \
......
......@@ -71,6 +71,7 @@
#include <gtk/gtkitem.h>
#include <gtk/gtkitemfactory.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklayout.h>
#include <gtk/gtklist.h>
#include <gtk/gtklistitem.h>
#include <gtk/gtkmain.h>
......@@ -86,6 +87,7 @@
#include <gtk/gtkpacker.h>
#include <gtk/gtkpaned.h>
#include <gtk/gtkpixmap.h>
#include <gtk/gtkplug.h>
#include <gtk/gtkpreview.h>
#include <gtk/gtkprogress.h>
#include <gtk/gtkprogressbar.h>
......@@ -100,6 +102,7 @@
#include <gtk/gtkselection.h>
#include <gtk/gtkseparator.h>
#include <gtk/gtksignal.h>
#include <gtk/gtksocket.h>
#include <gtk/gtkspinbutton.h>
#include <gtk/gtkstyle.h>
#include <gtk/gtkstatusbar.h>
......
/* Copyright Owen Taylor, 1998
*
* This file may be distributed under either the terms of the
* Netscape Public License, or the GNU Library General Public License
*
* Note: No GTK+ or Mozilla code should be added to this file.
* The coding style should be that of the the GTK core.
*/
#include "gtklayout.h"
#include "gtksignal.h"
#include "gdk/gdkx.h"
static void gtk_layout_class_init (GtkLayoutClass *class);
static void gtk_layout_init (GtkLayout *layout);
static void gtk_layout_realize (GtkWidget *widget);
static void gtk_layout_unrealize (GtkWidget *widget);
static void gtk_layout_map (GtkWidget *widget);
static void gtk_layout_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_layout_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_layout_draw (GtkWidget *widget,
GdkRectangle *area);
static gint gtk_layout_expose (GtkWidget *widget,
GdkEventExpose *event);
static void gtk_layout_remove (GtkContainer *container,
GtkWidget *widget);
static void gtk_layout_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static void gtk_layout_set_adjustments (GtkLayout *layout,
GtkAdjustment *hadj,
GtkAdjustment *vadj);
static void gtk_layout_realize_child (GtkLayout *layout,
GtkLayoutChild *child);
static void gtk_layout_position_child (GtkLayout *layout,
GtkLayoutChild *child,
gboolean force_allocate);
static void gtk_layout_position_children (GtkLayout *layout);
static void gtk_layout_expose_area (GtkLayout *layout,
gint x,
gint y,
gint width,
gint height);
static void gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
GtkLayout *layout);
static GdkFilterReturn gtk_layout_filter (GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
static GdkFilterReturn gtk_layout_main_filter (GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
static gboolean gtk_layout_gravity_works (void);
static void gtk_layout_set_static_gravity (GdkWindow *win,
gboolean op);
static GtkWidgetClass *parent_class = NULL;
static gboolean gravity_works;
/* Public interface
*/
GtkWidget*
gtk_layout_new (GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment)
{
GtkLayout *layout;
layout = gtk_type_new (gtk_layout_get_type());
gtk_layout_set_hadjustment (layout, hadjustment);
gtk_layout_set_vadjustment (layout, vadjustment);
return GTK_WIDGET (layout);
}
GtkAdjustment*
gtk_layout_get_hadjustment (GtkLayout *layout)
{
g_return_val_if_fail (layout != NULL, NULL);
g_return_val_if_fail (GTK_IS_LAYOUT (layout), NULL);
return layout->hadjustment;
}
GtkAdjustment*
gtk_layout_get_vadjustment (GtkLayout *layout)
{
g_return_val_if_fail (layout != NULL, NULL);
g_return_val_if_fail (GTK_IS_LAYOUT (layout), NULL);
return layout->vadjustment;
}
static void
gtk_layout_set_adjustments (GtkLayout *layout,
GtkAdjustment *hadj,
GtkAdjustment *vadj)
{
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
if (hadj)
g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
else
hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
if (vadj)
g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
else
vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
if (layout->hadjustment && (layout->hadjustment != hadj))
{
gtk_signal_disconnect_by_data (GTK_OBJECT (layout->hadjustment), layout);
gtk_object_unref (GTK_OBJECT (layout->hadjustment));
}
if (layout->vadjustment && (layout->vadjustment != vadj))
{
gtk_signal_disconnect_by_data (GTK_OBJECT (layout->vadjustment), layout);
gtk_object_unref (GTK_OBJECT (layout->vadjustment));
}
if (layout->hadjustment != hadj)
{
layout->hadjustment = hadj;
gtk_object_ref (GTK_OBJECT (layout->hadjustment));
gtk_object_sink (GTK_OBJECT (layout->hadjustment));
gtk_signal_connect (GTK_OBJECT (layout->hadjustment), "value_changed",
(GtkSignalFunc) gtk_layout_adjustment_changed,
layout);
gtk_layout_adjustment_changed (hadj, layout);
}
if (layout->vadjustment != vadj)
{
layout->vadjustment = vadj;
gtk_object_ref (GTK_OBJECT (layout->vadjustment));
gtk_object_sink (GTK_OBJECT (layout->vadjustment));
gtk_signal_connect (GTK_OBJECT (layout->vadjustment), "value_changed",
(GtkSignalFunc) gtk_layout_adjustment_changed,
layout);
gtk_layout_adjustment_changed (vadj, layout);
}
}
void
gtk_layout_set_hadjustment (GtkLayout *layout,
GtkAdjustment *adjustment)
{
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
if (layout->hadjustment)
gtk_object_unref (GTK_OBJECT (layout->hadjustment));
if (!adjustment)
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 10.0, 0.0, 0.0));
else
gtk_object_ref (GTK_OBJECT (adjustment));
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gtk_layout_adjustment_changed),
layout);
layout->hadjustment = adjustment;
}
void
gtk_layout_set_vadjustment (GtkLayout *layout,
GtkAdjustment *adjustment)
{
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
if (layout->vadjustment)
gtk_object_unref (GTK_OBJECT (layout->hadjustment));
if (!adjustment)
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 10.0, 0.0, 0.0));
else
gtk_object_ref (GTK_OBJECT (adjustment));
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (gtk_layout_adjustment_changed),
layout);
layout->vadjustment = adjustment;
}
void
gtk_layout_put (GtkLayout *layout,
GtkWidget *child_widget,
gint x,
gint y)
{
GtkLayoutChild *child;
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
child = g_new (GtkLayoutChild, 1);
child->widget = child_widget;
child->window = NULL;
child->x = x;
child->y = y;
child->widget->requisition.width = 0;
child->widget->requisition.height = 0;
layout->children = g_list_append (layout->children, child);
gtk_widget_set_parent (child_widget, GTK_WIDGET (layout));
gtk_widget_size_request (child->widget, &child->widget->requisition);
if (GTK_WIDGET_REALIZED (layout) &&
!GTK_WIDGET_REALIZED (child_widget))
gtk_layout_realize_child (layout, child);
gtk_layout_position_child (layout, child, TRUE);
}
void
gtk_layout_move (GtkLayout *layout,
GtkWidget *child_widget,
gint x,
gint y)
{
GList *tmp_list;
GtkLayoutChild *child;
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
tmp_list = layout->children;
while (tmp_list)
{
child = tmp_list->data;
if (child->widget == child_widget)
{
child->x = x;
child->y = y;
gtk_layout_position_child (layout, child, TRUE);
return;
}
tmp_list = tmp_list->next;
}
}
void
gtk_layout_set_size (GtkLayout *layout,
guint width,
guint height)
{
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
layout->width = width;
layout->height = height;
layout->hadjustment->upper = layout->width;
gtk_signal_emit_by_name (GTK_OBJECT (layout->hadjustment), "changed");
layout->vadjustment->upper = layout->height;
gtk_signal_emit_by_name (GTK_OBJECT (layout->vadjustment), "changed");
}
void
gtk_layout_freeze (GtkLayout *layout)
{
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
layout->frozen = TRUE;
}
void
gtk_layout_thaw (GtkLayout *layout)
{
g_return_if_fail (layout != NULL);
g_return_if_fail (GTK_IS_LAYOUT (layout));
if (!layout->frozen)
return;
layout->frozen = FALSE;
gtk_layout_position_children (layout);
gtk_widget_draw (GTK_WIDGET (layout), NULL);
}
/* Basic Object handling procedures
*/
guint
gtk_layout_get_type (void)
{
static guint layout_type = 0;
if (!layout_type)
{
GtkTypeInfo layout_info =
{
"GtkLayout",
sizeof (GtkLayout),
sizeof (GtkLayoutClass),
(GtkClassInitFunc) gtk_layout_class_init,
(GtkObjectInitFunc) gtk_layout_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL,
};
layout_type = gtk_type_unique (gtk_container_get_type (), &layout_info);
}
return layout_type;
}
static void
gtk_layout_class_init (GtkLayoutClass *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_container_get_type ());
widget_class->realize = gtk_layout_realize;
widget_class->unrealize = gtk_layout_unrealize;
widget_class->map = gtk_layout_map;
widget_class->size_request = gtk_layout_size_request;
widget_class->size_allocate = gtk_layout_size_allocate;
widget_class->draw = gtk_layout_draw;
widget_class->expose_event = gtk_layout_expose;
widget_class->scroll_adjustments_signal =
gtk_signal_new ("scroll_adjustments",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkLayoutClass, scroll_adjustments),
gtk_marshal_NONE__POINTER_POINTER,
GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
gravity_works = gtk_layout_gravity_works ();
container_class->remove = gtk_layout_remove;
container_class->forall = gtk_layout_forall;
class->scroll_adjustments = gtk_layout_set_adjustments;
}
static void
gtk_layout_init (GtkLayout *layout)
{
layout->children = NULL;
layout->width = 100;
layout->height = 100;
layout->hadjustment = NULL;
layout->vadjustment = NULL;
layout->bin_window = NULL;
layout->configure_serial = 0;
layout->scroll_x = 0;
layout->scroll_y = 0;
layout->visibility = GDK_VISIBILITY_PARTIAL;
}
/* Widget methods
*/
static void
gtk_layout_realize (GtkWidget *widget)
{
GList *tmp_list;
GtkLayout *layout;
GdkWindowAttr attributes;
gint attributes_mask;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_LAYOUT (widget));
layout = GTK_LAYOUT (widget);
GTK_WIDGET_SET_FLAGS (layout, 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 = GDK_VISIBILITY_NOTIFY_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);
attributes.x = 0;
attributes.y = 0;
attributes.event_mask = gtk_widget_get_events (widget);
layout->bin_window = gdk_window_new (widget->window,
&attributes, attributes_mask);
gdk_window_set_user_data (layout->bin_window, widget);
if (gravity_works)
gtk_layout_set_static_gravity (layout->bin_window, TRUE);
widget->style = gtk_style_attach (widget->style, widget->window);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
gtk_style_set_background (widget->style, layout->bin_window, GTK_STATE_NORMAL);
gdk_window_add_filter (widget->window, gtk_layout_main_filter, layout);
gdk_window_add_filter (layout->bin_window, gtk_layout_filter, layout);
tmp_list = layout->children;
while (tmp_list)
{
GtkLayoutChild *child = tmp_list->data;
if (GTK_WIDGET_VISIBLE (child->widget))
gtk_layout_realize_child (layout, child);
tmp_list = tmp_list->next;
}
}
static void
gtk_layout_map (GtkWidget *widget)
{
GList *tmp_list;
GtkLayout *layout;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_LAYOUT (widget));
layout = GTK_LAYOUT (widget);
GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
gdk_window_show (widget->window);
gdk_window_show (layout->bin_window);
tmp_list = layout->children;
while (tmp_list)
{
GtkLayoutChild *child = tmp_list->data;
if (GTK_WIDGET_VISIBLE (child->widget) &&
!GTK_WIDGET_MAPPED (child->widget))
gtk_widget_map (child->widget);
if (child->window)
gdk_window_show (child->window);
tmp_list = tmp_list->next;
}
}
static void
gtk_layout_unrealize (GtkWidget *widget)
{
GList *tmp_list;
GtkLayout *layout;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_LAYOUT (widget));
layout = GTK_LAYOUT (widget);
tmp_list = layout->children;
gdk_window_set_user_data (layout->bin_window, NULL);
gdk_window_destroy (layout->bin_window);
layout->bin_window = NULL;
while (tmp_list)
{
GtkLayoutChild *child = tmp_list->data;
if (child->window)
{
gdk_window_set_user_data (child->window, NULL);
gdk_window_destroy (child->window);
}
tmp_list = tmp_list->next;
}
}
static void
gtk_layout_draw (GtkWidget *widget, GdkRectangle *area)
{
GtkLayout *layout;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_LAYOUT (widget));
layout = GTK_LAYOUT (widget);
}
static void
gtk_layout_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
GList *tmp_list;
GtkLayout *layout;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_LAYOUT (widget));
layout = GTK_LAYOUT (widget);
tmp_list = layout->children;
while (tmp_list)