/* vi:set ts=8 sts=4 sw=4:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
/*
* (C) 1998,1999 by Marcin Dalecki <martin@dalecki.de>
*
* Support for GTK+ 2 was added by:
*
* (C) 2002,2003 Jason Hildebrand <jason@peaceworks.ca>
* Daniel Elstner <daniel.elstner@gmx.net>
*
* This is a special purspose container widget, which manages arbitrary childs
* at arbitrary positions width arbitrary sizes. This finally puts an end on
* our resizement problems with which we where struggling for such a long time.
*/
#include "vim.h"
#include <gtk/gtk.h> /* without this it compiles, but gives errors at
runtime! */
#include "gui_gtk_f.h"
#include <gtk/gtksignal.h>
#ifdef WIN3264
# include <gdk/gdkwin32.h>
#else
# include <gdk/gdkx.h>
#endif
typedef struct _GtkFormChild GtkFormChild;
struct _GtkFormChild
{
GtkWidget *widget;
GdkWindow *window;
gint x; /* relative subwidget x position */
gint y; /* relative subwidget y position */
gint mapped;
};
static void gtk_form_class_init(GtkFormClass *klass);
static void gtk_form_init(GtkForm *form);
static void gtk_form_realize(GtkWidget *widget);
static void gtk_form_unrealize(GtkWidget *widget);
static void gtk_form_map(GtkWidget *widget);
static void gtk_form_size_request(GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_form_size_allocate(GtkWidget *widget,
GtkAllocation *allocation);
#ifndef HAVE_GTK2 /* this isn't needed in gtk2 */
static void gtk_form_draw(GtkWidget *widget,
GdkRectangle *area);
#endif
static gint gtk_form_expose(GtkWidget *widget,
GdkEventExpose *event);
static void gtk_form_remove(GtkContainer *container,
GtkWidget *widget);
static void gtk_form_forall(GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static void gtk_form_attach_child_window(GtkForm *form,
GtkFormChild *child);
static void gtk_form_realize_child(GtkForm *form,
GtkFormChild *child);
static void gtk_form_position_child(GtkForm *form,
GtkFormChild *child,
gboolean force_allocate);
static void gtk_form_position_children(GtkForm *form);
static GdkFilterReturn gtk_form_filter(GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
static GdkFilterReturn gtk_form_main_filter(GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
static void gtk_form_set_static_gravity(GdkWindow *window,
gboolean use_static);
static void gtk_form_send_configure(GtkForm *form);
static void gtk_form_child_map(GtkWidget *widget, gpointer user_data);
static void gtk_form_child_unmap(GtkWidget *widget, gpointer user_data);
static GtkWidgetClass *parent_class = NULL;
/* Public interface
*/
GtkWidget *
gtk_form_new(void)
{
GtkForm *form;
form = gtk_type_new(gtk_form_get_type());
return GTK_WIDGET(form);
}
void
gtk_form_put(GtkForm *form,
GtkWidget *child_widget,
gint x,
gint y)
{
GtkFormChild *child;
g_return_if_fail(GTK_IS_FORM(form));
child = g_new(GtkFormChild, 1);
child->widget = child_widget;
child->window = NULL;
child->x = x;
child->y = y;
child->widget->requisition.width = 0;
child->widget->requisition.height = 0;
child->mapped = FALSE;
form->children = g_list_append(form->children, child);
/* child->window must be created and attached to the widget _before_
* it has been realized, or else things will break with GTK2. Note
* that gtk_widget_set_parent() realizes the widget if it's visible
* and its parent is mapped.
*/
if (GTK_WIDGET_REALIZED(form))
gtk_form_attach_child_window(form, child);
gtk_widget_set_parent(child_widget, GTK_WIDGET(form));
gtk_widget_size_request(child->widget, NULL);
if (GTK_WIDGET_REALIZED(form) && !GTK_WIDGET_REALIZED(child_widget))
gtk_form_realize_child(form, child);
gtk_form_position_child(form, child, TRUE);
}
void
gtk_form_move(GtkForm *form,
GtkWidget *child_widget,
gint x,
gint y)
{
GList *tmp_list;
GtkFormChild *child;
g_return_if_fail(GTK_IS_FORM(form));
for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
{
child = tmp_list->data;
if (child->widget == child_widget)
{
child->x = x;
child->y = y;
gtk_form_position_child(form, child, TRUE);
return;
}
}
}
void
gtk_form_set_size(GtkForm *form, guint width, guint height)
{
g_return_if_fail(GTK_IS_FORM(form));
/* prevent unneccessary calls */
if (form->width == width && form->height == height)
return;
form->width =