mirror of
https://gitlab.gnome.org/GNOME/glade.git
synced 2025-09-08 00:02:20 -04:00
updated
* doc/tmpl/*: updated * src/glade-fixed.[ch], src/glade-widget.[ch]: Improved, now made replace_child a vfunc... fixed some event related bugs. * src/glade-gtk.c, widgets/gtk+.xml.in: Added free-form placement for GtkTable widget. * src/glade-utils.c: added glade_util_deep_fixed_event(), used to propagate events down to fixed containers that dont have windows.
This commit is contained in:
parent
70b5c89a75
commit
020446e22f
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2006-06-11 Tristan Van Berkom <tvb@gnome.org>
|
||||
|
||||
* doc/tmpl/*: updated
|
||||
|
||||
* src/glade-fixed.[ch], src/glade-widget.[ch]:
|
||||
Improved, now made replace_child a vfunc... fixed some
|
||||
event related bugs.
|
||||
|
||||
* src/glade-gtk.c, widgets/gtk+.xml.in: Added free-form placement
|
||||
for GtkTable widget.
|
||||
|
||||
* src/glade-utils.c: added glade_util_deep_fixed_event(), used to
|
||||
propagate events down to fixed containers that dont have windows.
|
||||
|
||||
2006-06-10 Tristan Van Berkom <tvb@gnome.org>
|
||||
|
||||
* src/glade-fixed.c:
|
||||
|
@ -452,6 +452,7 @@ GladeSupportedChild
|
||||
<FILE>glade-widget</FILE>
|
||||
<TITLE>GladeWidget</TITLE>
|
||||
GladeWidget
|
||||
glade_widget_get_from_gobject
|
||||
glade_widget_add_child
|
||||
glade_widget_remove_child
|
||||
glade_widget_set_name
|
||||
@ -496,7 +497,6 @@ glade_widget_write
|
||||
glade_widget_read
|
||||
glade_widget_has_launcher
|
||||
glade_widget_launch_editor
|
||||
glade_widget_get_from_gobject
|
||||
glade_widget_get_parent
|
||||
glade_widget_set_parent
|
||||
glade_widget_is_dupping
|
||||
|
90
doc/tmpl/glade-fixed.sgml
Normal file
90
doc/tmpl/glade-fixed.sgml
Normal file
@ -0,0 +1,90 @@
|
||||
<!-- ##### SECTION Title ##### -->
|
||||
GladeFixed
|
||||
|
||||
<!-- ##### SECTION Short_Description ##### -->
|
||||
An object wrapper for free-form placement container widgets.
|
||||
|
||||
<!-- ##### SECTION Long_Description ##### -->
|
||||
<para>
|
||||
#GladeFixed is a specialized #GladeWidget to handle free-form child
|
||||
placements in containers that support this, it is designed with properties
|
||||
and signals with flexable integration in mind.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you set the x-prop/y-prop/width-prop/height-prop properties and
|
||||
leave the signals alone, #GladeFixed will assume you are like a
|
||||
GtkFixed/GtkLayout widget and will use pixel counts as units for
|
||||
these properties.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you handle the configure-child/configure-end[/configure-begin] signals
|
||||
and dont let them propagate to the GladeFixed, then the x-prop/y-prop/width-prop/height-prop
|
||||
properties will be completely ignored and it is up to the implementor to play
|
||||
with whatever child packing properties are available to make a closest match
|
||||
for the values passed to configure-child via the #GdkRectangle.
|
||||
</para>
|
||||
|
||||
<!-- ##### SECTION See_Also ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### SECTION Stability_Level ##### -->
|
||||
|
||||
|
||||
<!-- ##### STRUCT GladeFixed ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
|
||||
<!-- ##### SIGNAL GladeFixed::configure-begin ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@gladefixed: the object which received the signal.
|
||||
@arg1:
|
||||
@Returns:
|
||||
|
||||
<!-- ##### SIGNAL GladeFixed::configure-child ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@gladefixed: the object which received the signal.
|
||||
@arg1:
|
||||
@arg2:
|
||||
@Returns:
|
||||
|
||||
<!-- ##### SIGNAL GladeFixed::configure-end ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@gladefixed: the object which received the signal.
|
||||
@arg1:
|
||||
@Returns:
|
||||
|
||||
<!-- ##### ARG GladeFixed:height-prop ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GladeFixed:width-prop ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GladeFixed:x-prop ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GladeFixed:y-prop ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
@ -110,6 +110,17 @@ convenience api for getting and setting properties (mostly from the plugin).
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### FUNCTION glade_widget_get_from_gobject ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@object:
|
||||
@Returns:
|
||||
<!-- # Unused Parameters # -->
|
||||
@w:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION glade_widget_add_child ##### -->
|
||||
<para>
|
||||
|
||||
@ -535,14 +546,6 @@ convenience api for getting and setting properties (mostly from the plugin).
|
||||
@widget:
|
||||
|
||||
|
||||
<!-- ##### MACRO glade_widget_get_from_gobject ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@w:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION glade_widget_get_parent ##### -->
|
||||
<para>
|
||||
|
||||
|
@ -62,28 +62,6 @@ typedef struct {
|
||||
gulong enter_id;
|
||||
} GFSigData;
|
||||
|
||||
/* Convenience macros used in pointer events.
|
||||
*/
|
||||
#define GLADE_FIXED_CURSOR_TOP(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_TOP_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_TOP_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_TOP)
|
||||
|
||||
#define GLADE_FIXED_CURSOR_BOTTOM(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_BOTTOM_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM)
|
||||
|
||||
#define GLADE_FIXED_CURSOR_RIGHT(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_TOP_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_RIGHT)
|
||||
|
||||
#define GLADE_FIXED_CURSOR_LEFT(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_TOP_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_LEFT)
|
||||
|
||||
#define CHILD_WIDTH_MIN 20
|
||||
#define CHILD_HEIGHT_MIN 20
|
||||
#define CHILD_WIDTH_DEF 100
|
||||
@ -237,13 +215,7 @@ glade_fixed_configure_widget (GladeFixed *fixed,
|
||||
|
||||
gdk_window_get_pointer
|
||||
(GTK_WIDGET (gwidget->object)->window, &x, &y, NULL);
|
||||
|
||||
/* I think its safe here to skip the glade-property API */
|
||||
new_area.x = GTK_WIDGET (child->object)->allocation.x;
|
||||
new_area.y = GTK_WIDGET (child->object)->allocation.y;
|
||||
new_area.width = GTK_WIDGET (child->object)->allocation.width;
|
||||
new_area.height = GTK_WIDGET (child->object)->allocation.height;
|
||||
|
||||
|
||||
right = GLADE_FIXED_CURSOR_RIGHT (fixed->operation);
|
||||
left = GLADE_FIXED_CURSOR_LEFT (fixed->operation);
|
||||
top = GLADE_FIXED_CURSOR_TOP (fixed->operation);
|
||||
@ -252,6 +224,11 @@ glade_fixed_configure_widget (GladeFixed *fixed,
|
||||
/* Filter out events that make your widget go out of bounds */
|
||||
glade_fixed_filter_event (fixed, &x, &y, left, right, top, bottom);
|
||||
|
||||
new_area.x = fixed->child_x_origin;
|
||||
new_area.y = fixed->child_y_origin;
|
||||
new_area.width = fixed->child_width_origin;
|
||||
new_area.height = fixed->child_height_origin;
|
||||
|
||||
/* Modify current size.
|
||||
*/
|
||||
if (fixed->operation == GLADE_CURSOR_DRAG)
|
||||
@ -261,6 +238,7 @@ glade_fixed_configure_widget (GladeFixed *fixed,
|
||||
x - fixed->pointer_x_origin;
|
||||
new_area.y = fixed->child_y_origin +
|
||||
y - fixed->pointer_y_origin;
|
||||
|
||||
} else {
|
||||
|
||||
if (bottom)
|
||||
@ -359,7 +337,6 @@ glade_fixed_connect_child (GladeFixed *fixed,
|
||||
data, g_free);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
GladeFixedClass
|
||||
*******************************************************************************/
|
||||
@ -382,7 +359,7 @@ glade_fixed_configure_child_impl (GladeFixed *fixed,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
glade_fixed_configure_end_impl (GladeFixed *fixed,
|
||||
GladeWidget *child)
|
||||
{
|
||||
@ -396,16 +373,15 @@ glade_fixed_configure_end_impl (GladeFixed *fixed,
|
||||
GValue new_height_value = { 0, };
|
||||
GladeProperty *x_prop, *y_prop, *width_prop, *height_prop;
|
||||
|
||||
/* XXX Well... this can be simplified now ... heh */
|
||||
x_prop = glade_widget_get_pack_property (child, fixed->x_prop);
|
||||
y_prop = glade_widget_get_pack_property (child, fixed->y_prop);
|
||||
width_prop = glade_widget_get_property (child, fixed->width_prop);
|
||||
height_prop = glade_widget_get_property (child, fixed->height_prop);
|
||||
|
||||
g_return_if_fail (GLADE_IS_PROPERTY (x_prop));
|
||||
g_return_if_fail (GLADE_IS_PROPERTY (y_prop));
|
||||
g_return_if_fail (GLADE_IS_PROPERTY (width_prop));
|
||||
g_return_if_fail (GLADE_IS_PROPERTY (height_prop));
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (x_prop), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (y_prop), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (width_prop), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (height_prop), FALSE);
|
||||
|
||||
g_value_init (&x_value, G_TYPE_INT);
|
||||
g_value_init (&y_value, G_TYPE_INT);
|
||||
@ -437,6 +413,8 @@ glade_fixed_configure_end_impl (GladeFixed *fixed,
|
||||
g_value_unset (&new_y_value);
|
||||
g_value_unset (&new_width_value);
|
||||
g_value_unset (&new_height_value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -445,9 +423,8 @@ glade_fixed_handle_child_event (GladeFixed *fixed,
|
||||
GtkWidget *event_widget,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GladeWidget *gwidget = GLADE_WIDGET (fixed);
|
||||
gboolean handled = FALSE;
|
||||
gint parent_x, parent_y, child_x, child_y, x, y;
|
||||
gboolean handled = FALSE, sig_handled;
|
||||
gint parent_x, parent_y, x, y;
|
||||
GladeCursorType operation;
|
||||
|
||||
/* Get relative mouse position
|
||||
@ -473,7 +450,7 @@ glade_fixed_handle_child_event (GladeFixed *fixed,
|
||||
{
|
||||
glade_fixed_configure_widget (fixed, child);
|
||||
glade_cursor_set (((GdkEventAny *)event)->window,
|
||||
operation);
|
||||
fixed->operation);
|
||||
handled = TRUE;
|
||||
}
|
||||
gdk_window_get_pointer (GTK_WIDGET (child->object)->window, NULL, NULL, NULL);
|
||||
@ -490,7 +467,7 @@ glade_fixed_handle_child_event (GladeFixed *fixed,
|
||||
|
||||
g_signal_emit (G_OBJECT (fixed),
|
||||
glade_fixed_signals[CONFIGURE_BEGIN],
|
||||
0, child);
|
||||
0, child, &sig_handled);
|
||||
|
||||
handled = TRUE;
|
||||
}
|
||||
@ -505,7 +482,7 @@ glade_fixed_handle_child_event (GladeFixed *fixed,
|
||||
|
||||
g_signal_emit (G_OBJECT (fixed),
|
||||
glade_fixed_signals[CONFIGURE_END],
|
||||
0, child);
|
||||
0, child, &sig_handled);
|
||||
|
||||
fixed->configuring = NULL;
|
||||
handled = TRUE;
|
||||
@ -523,12 +500,14 @@ glade_fixed_child_event (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GladeFixed *fixed)
|
||||
{
|
||||
gdouble x, y;
|
||||
GtkWidget *event_widget;
|
||||
GladeWidget *search, *event_gwidget,
|
||||
*gwidget = glade_widget_get_from_gobject (widget);
|
||||
|
||||
|
||||
/* Get the basic event info... */
|
||||
gdk_window_get_user_data (((GdkEventAny *)event)->window, (gpointer)&event_widget);
|
||||
event_gwidget = glade_widget_event_widget ();
|
||||
|
||||
/* Skip all this choosyness if we're already in a drag/resize
|
||||
*/
|
||||
@ -536,14 +515,6 @@ glade_fixed_child_event (GtkWidget *widget,
|
||||
return glade_fixed_handle_child_event
|
||||
(fixed, fixed->configuring, event_widget, event);
|
||||
|
||||
/* carefull to use the event widget and not the signal widget
|
||||
* to feed to retrieve_from_position
|
||||
*/
|
||||
gdk_event_get_coords (event, &x, &y);
|
||||
event_gwidget =
|
||||
GLADE_WIDGET_GET_KLASS (fixed)->retrieve_from_position
|
||||
(event_widget, (int) (x + 0.5), (int) (y + 0.5));
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_WIDGET (gwidget), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_WIDGET (event_gwidget), FALSE);
|
||||
|
||||
@ -581,7 +552,9 @@ glade_fixed_child_event (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
return glade_fixed_handle_child_event (fixed, gwidget, event_widget, event);
|
||||
return glade_fixed_handle_child_event
|
||||
(fixed, gwidget, event_widget, event);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -663,6 +636,24 @@ glade_fixed_remove_child_impl (GladeWidget *fixed,
|
||||
(GLADE_WIDGET (fixed), child);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_fixed_replace_child_impl (GladeWidget *fixed,
|
||||
GObject *old_object,
|
||||
GObject *new_object)
|
||||
{
|
||||
GladeWidget *gnew_widget = glade_widget_get_from_gobject (new_object);
|
||||
GladeWidget *gold_widget = glade_widget_get_from_gobject (old_object);
|
||||
|
||||
if (gold_widget)
|
||||
glade_fixed_disconnect_child (GLADE_FIXED (fixed), gold_widget);
|
||||
|
||||
/* Chain up for the basic reparenting */
|
||||
GLADE_WIDGET_KLASS (parent_class)->replace_child
|
||||
(GLADE_WIDGET (fixed), old_object, new_object);
|
||||
|
||||
if (gnew_widget)
|
||||
glade_fixed_connect_child (GLADE_FIXED (fixed), gnew_widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_fixed_popup_menu (GtkWidget *widget, gpointer unused_data)
|
||||
@ -701,45 +692,35 @@ glade_fixed_event (GtkWidget *widget,
|
||||
GladeWidgetClass *add_class, *alt_class;
|
||||
GtkWidget *event_widget;
|
||||
gboolean handled = FALSE;
|
||||
GladeWidget *gwidget, *search;
|
||||
gdouble x, y;
|
||||
GladeWidget *event_gwidget, *search;
|
||||
|
||||
add_class = glade_app_get_add_class ();
|
||||
alt_class = glade_app_get_alt_class ();
|
||||
|
||||
gdk_window_get_pointer (widget->window, NULL, NULL, NULL);
|
||||
|
||||
/* Get the event widget and the deep widget */
|
||||
gdk_window_get_user_data (((GdkEventAny *)event)->window, (gpointer)&event_widget);
|
||||
event_gwidget = glade_widget_event_widget ();
|
||||
|
||||
/* Currently ignoring the return value and acting... even if
|
||||
* this was a selection click
|
||||
*/
|
||||
if (GLADE_WIDGET_KLASS (parent_class)->event (widget, event, gwidget_fixed))
|
||||
return TRUE;
|
||||
|
||||
/* Paranoid assertion
|
||||
*/
|
||||
g_assert (glade_widget_get_from_gobject (widget) == gwidget_fixed);
|
||||
|
||||
/* carefull to use the event widget and not the signal widget
|
||||
* to feed to retrieve_from_position
|
||||
*/
|
||||
gdk_event_get_coords (event, &x, &y);
|
||||
gdk_window_get_user_data (((GdkEventAny *)event)->window, (gpointer)&event_widget);
|
||||
gwidget =
|
||||
GLADE_WIDGET_GET_KLASS (fixed)->retrieve_from_position
|
||||
(event_widget, (int) (x + 0.5), (int) (y + 0.5));
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_WIDGET (gwidget), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_WIDGET (event_gwidget), FALSE);
|
||||
|
||||
/* Get the gwidget that is a direct child of 'fixed' */
|
||||
for (search = gwidget;
|
||||
search && search->parent != gwidget_fixed;
|
||||
for (search = event_gwidget;
|
||||
search && GLADE_IS_FIXED (search->parent) == FALSE;
|
||||
search = search->parent);
|
||||
|
||||
/* Igore events that come from other fixed or thier children
|
||||
* deeper in the hierarchy (it happens when they all return
|
||||
* FALSE from thier event handlers).
|
||||
*/
|
||||
if (gwidget != gwidget_fixed &&
|
||||
if (event_gwidget != gwidget_fixed &&
|
||||
(search && search->parent != gwidget_fixed))
|
||||
return FALSE;
|
||||
|
||||
@ -776,7 +757,7 @@ glade_fixed_event (GtkWidget *widget,
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
if (gwidget_fixed == gwidget)
|
||||
if (gwidget_fixed == event_gwidget)
|
||||
{
|
||||
fixed->mouse_x = ((GdkEventButton *)event)->x;
|
||||
fixed->mouse_y = ((GdkEventButton *)event)->y;
|
||||
@ -788,9 +769,9 @@ glade_fixed_event (GtkWidget *widget,
|
||||
(fixed, fixed->configuring,
|
||||
event_widget, event);
|
||||
}
|
||||
else if (gwidget_fixed != gwidget)
|
||||
else if (gwidget_fixed != event_gwidget)
|
||||
{
|
||||
if (search && search == gwidget)
|
||||
if (search && search == event_gwidget)
|
||||
return glade_fixed_handle_child_event
|
||||
(fixed, search, event_widget, event);
|
||||
}
|
||||
@ -850,28 +831,6 @@ glade_fixed_event (GtkWidget *widget,
|
||||
/*******************************************************************************
|
||||
GObjectClass
|
||||
*******************************************************************************/
|
||||
static GObject *
|
||||
glade_fixed_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_properties)
|
||||
{
|
||||
GObject *obj;
|
||||
GladeWidget *gwidget;
|
||||
|
||||
obj = G_OBJECT_CLASS (parent_class)->constructor
|
||||
(type, n_construct_properties, construct_properties);
|
||||
|
||||
gwidget = GLADE_WIDGET (obj);
|
||||
|
||||
/* This is needed at least to set a backing pixmaps
|
||||
* and handle events more consistantly (lets hope all
|
||||
* free-form containers support being created this way).
|
||||
*/
|
||||
GTK_WIDGET_UNSET_FLAGS(gwidget->object, GTK_NO_WINDOW);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
glade_fixed_finalize (GObject *object)
|
||||
{
|
||||
@ -961,7 +920,6 @@ glade_fixed_class_init (GladeFixedClass *fixed_class)
|
||||
G_OBJECT_CLASS
|
||||
(g_type_class_peek_parent (gobject_class));
|
||||
|
||||
gobject_class->constructor = glade_fixed_constructor;
|
||||
gobject_class->finalize = glade_fixed_finalize;
|
||||
gobject_class->set_property = glade_fixed_set_property;
|
||||
gobject_class->get_property = glade_fixed_get_property;
|
||||
@ -970,6 +928,7 @@ glade_fixed_class_init (GladeFixedClass *fixed_class)
|
||||
gwidget_class->event = glade_fixed_event;
|
||||
gwidget_class->add_child = glade_fixed_add_child_impl;
|
||||
gwidget_class->remove_child = glade_fixed_remove_child_impl;
|
||||
gwidget_class->replace_child = glade_fixed_replace_child_impl;
|
||||
|
||||
fixed_class->configure_child = glade_fixed_configure_child_impl;
|
||||
fixed_class->configure_begin = NULL;
|
||||
@ -1032,16 +991,19 @@ glade_fixed_class_init (GladeFixedClass *fixed_class)
|
||||
* @arg1: the child #GladeWidget
|
||||
*
|
||||
* Signals the beginning of a Drag/Resize
|
||||
*
|
||||
* Returns: %TRUE means you have handled the event and cancels the
|
||||
* default handler from being triggered.
|
||||
*/
|
||||
glade_fixed_signals[CONFIGURE_BEGIN] =
|
||||
g_signal_new ("configure-begin",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET
|
||||
(GladeFixedClass, configure_begin),
|
||||
NULL, NULL,
|
||||
glade_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
||||
glade_boolean_handled_accumulator, NULL,
|
||||
glade_marshal_BOOLEAN__OBJECT,
|
||||
G_TYPE_BOOLEAN, 1, G_TYPE_OBJECT);
|
||||
|
||||
/**
|
||||
* GladeFixed::configure-end:
|
||||
@ -1049,16 +1011,19 @@ glade_fixed_class_init (GladeFixedClass *fixed_class)
|
||||
* @arg1: the child #GladeWidget
|
||||
*
|
||||
* Signals the end of a Drag/Resize
|
||||
*
|
||||
* Returns: %TRUE means you have handled the event and cancels the
|
||||
* default handler from being triggered.
|
||||
*/
|
||||
glade_fixed_signals[CONFIGURE_END] =
|
||||
g_signal_new ("configure-end",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET
|
||||
(GladeFixedClass, configure_end),
|
||||
NULL, NULL,
|
||||
glade_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
||||
glade_boolean_handled_accumulator, NULL,
|
||||
glade_marshal_BOOLEAN__OBJECT,
|
||||
G_TYPE_BOOLEAN, 1, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,6 +17,27 @@ G_BEGIN_DECLS
|
||||
#define GLADE_IS_FIXED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_FIXED))
|
||||
#define GLADE_FIXED_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GLADE_FIXED, GladeFixedClass))
|
||||
|
||||
/* Convenience macros used in pointer events.
|
||||
*/
|
||||
#define GLADE_FIXED_CURSOR_TOP(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_TOP_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_TOP_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_TOP)
|
||||
|
||||
#define GLADE_FIXED_CURSOR_BOTTOM(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_BOTTOM_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM)
|
||||
|
||||
#define GLADE_FIXED_CURSOR_RIGHT(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_TOP_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM_RIGHT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_RIGHT)
|
||||
|
||||
#define GLADE_FIXED_CURSOR_LEFT(type) \
|
||||
((type) == GLADE_CURSOR_RESIZE_TOP_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_BOTTOM_LEFT || \
|
||||
(type) == GLADE_CURSOR_RESIZE_LEFT)
|
||||
|
||||
typedef struct _GladeFixed GladeFixed;
|
||||
typedef struct _GladeFixedClass GladeFixedClass;
|
||||
@ -55,8 +76,8 @@ struct _GladeFixedClass {
|
||||
GladeWidgetKlass parent_class;
|
||||
|
||||
gboolean (* configure_child) (GladeFixed *, GladeWidget *, GdkRectangle *);
|
||||
void (* configure_begin) (GladeFixed *, GladeWidget *);
|
||||
void (* configure_end) (GladeFixed *, GladeWidget *);
|
||||
gboolean (* configure_begin) (GladeFixed *, GladeWidget *);
|
||||
gboolean (* configure_end) (GladeFixed *, GladeWidget *);
|
||||
|
||||
/* Signal handler for child widgets
|
||||
*/
|
||||
|
423
src/glade-gtk.c
423
src/glade-gtk.c
@ -574,6 +574,417 @@ glade_gtk_box_remove_child (GObject *object, GObject *child)
|
||||
|
||||
|
||||
/* ----------------------------- GtkTable ------------------------------ */
|
||||
typedef struct {
|
||||
/* comparable part: */
|
||||
GladeWidget *widget;
|
||||
gint left_attach;
|
||||
gint right_attach;
|
||||
gint top_attach;
|
||||
gint bottom_attach;
|
||||
|
||||
gboolean reset;
|
||||
GdkRectangle rect;
|
||||
} GladeGtkTableChild;
|
||||
|
||||
typedef enum {
|
||||
DIR_UP,
|
||||
DIR_DOWN,
|
||||
DIR_LEFT,
|
||||
DIR_RIGHT
|
||||
} GladeTableDir;
|
||||
|
||||
#define TABLE_CHILD_CMP_SIZE (sizeof (GladeWidget *) + (sizeof (gint) * 4))
|
||||
|
||||
static GladeGtkTableChild table_edit = { 0, };
|
||||
static GladeGtkTableChild table_cur_attach = { 0, };
|
||||
|
||||
|
||||
/* Takes a point (x or y depending on 'row') relative to
|
||||
* table, and returns the row or column in which the point
|
||||
* was found.
|
||||
*/
|
||||
static gint
|
||||
glade_gtk_table_get_row_col_from_point (GtkTable *table,
|
||||
gboolean row,
|
||||
gint point)
|
||||
{
|
||||
GtkTableChild *tchild;
|
||||
GList *list;
|
||||
gint span, trans_point, size, base, end;
|
||||
|
||||
for (list = table->children; list; list = list->next)
|
||||
{
|
||||
tchild = list->data;
|
||||
|
||||
if (row)
|
||||
gtk_widget_translate_coordinates
|
||||
(GTK_WIDGET (table), tchild->widget,
|
||||
0, point, NULL, &trans_point);
|
||||
else
|
||||
gtk_widget_translate_coordinates
|
||||
(GTK_WIDGET (table), tchild->widget,
|
||||
point, 0, &trans_point, NULL);
|
||||
|
||||
/* Find any widget in our row/column
|
||||
*/
|
||||
end = row ?
|
||||
tchild->widget->allocation.height :
|
||||
tchild->widget->allocation.width;
|
||||
|
||||
if (trans_point >= 0 &&
|
||||
trans_point <= end)
|
||||
{
|
||||
base = row ? tchild->top_attach : tchild->left_attach;
|
||||
size = row ? (tchild->widget->allocation.height) :
|
||||
(tchild->widget->allocation.width);
|
||||
span = row ? (tchild->bottom_attach - tchild->top_attach) :
|
||||
(tchild->right_attach - tchild->left_attach);
|
||||
|
||||
return base + (trans_point * span / size);
|
||||
}
|
||||
}
|
||||
|
||||
/* g_print ("Failed to find a widget (point %d row %d)! (length %d)\n", */
|
||||
/* point, row, g_list_length (table->children)); */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
glade_gtk_table_point_crosses_threshold (GtkTable *table,
|
||||
gboolean row,
|
||||
gint num,
|
||||
GladeTableDir dir,
|
||||
gint point)
|
||||
{
|
||||
|
||||
GtkTableChild *tchild;
|
||||
GList *list;
|
||||
gint span, trans_point, size;
|
||||
|
||||
for (list = table->children; list; list = list->next)
|
||||
{
|
||||
tchild = list->data;
|
||||
|
||||
|
||||
/* Find any widget in our row/column
|
||||
*/
|
||||
if ((row && num >= tchild->top_attach && num < tchild->bottom_attach) ||
|
||||
(!row && num >= tchild->left_attach && num < tchild->right_attach))
|
||||
{
|
||||
|
||||
if (row)
|
||||
gtk_widget_translate_coordinates
|
||||
(GTK_WIDGET (table), tchild->widget,
|
||||
0, point, NULL, &trans_point);
|
||||
else
|
||||
gtk_widget_translate_coordinates
|
||||
(GTK_WIDGET (table), tchild->widget,
|
||||
point, 0, &trans_point, NULL);
|
||||
|
||||
span = row ? (tchild->bottom_attach - tchild->top_attach) :
|
||||
(tchild->right_attach - tchild->left_attach);
|
||||
size = row ? (tchild->widget->allocation.height) :
|
||||
(tchild->widget->allocation.width);
|
||||
size /= span;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case DIR_UP:
|
||||
case DIR_LEFT:
|
||||
return trans_point <= size - ((size / 3) * 2);
|
||||
case DIR_DOWN:
|
||||
case DIR_RIGHT:
|
||||
return trans_point >= ((size / 3) * 2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* g_print ("Failed to find a widget (point %d row %d)! (length %d)\n", */
|
||||
/* point, row, g_list_length (table->children)); */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_gtk_table_get_attachments (GladeFixed *fixed,
|
||||
GtkTable *table,
|
||||
GdkRectangle *rect,
|
||||
GladeGtkTableChild *configure)
|
||||
{
|
||||
gint center_x, center_y, row, column;
|
||||
center_x = rect->x + (rect->width / 2);
|
||||
center_y = rect->y + (rect->height / 2);
|
||||
|
||||
column = glade_gtk_table_get_row_col_from_point
|
||||
(table, FALSE, center_x);
|
||||
|
||||
row = glade_gtk_table_get_row_col_from_point
|
||||
(table, TRUE, center_y);
|
||||
|
||||
/* its a start, now try to grow when the rect extents
|
||||
* reach at least half way into the next row/column
|
||||
*/
|
||||
configure->left_attach = column;
|
||||
configure->right_attach = column + 1;
|
||||
configure->top_attach = row;
|
||||
configure->bottom_attach = row +1;
|
||||
|
||||
|
||||
|
||||
|
||||
if (column >= 0 && row >= 0)
|
||||
{
|
||||
|
||||
/* Check and expand left
|
||||
*/
|
||||
while (configure->left_attach > 0)
|
||||
{
|
||||
if (rect->x < fixed->child_x_origin &&
|
||||
GLADE_FIXED_CURSOR_LEFT (fixed->operation) == FALSE)
|
||||
break;
|
||||
|
||||
if (glade_gtk_table_point_crosses_threshold
|
||||
(table, FALSE, configure->left_attach -1,
|
||||
DIR_LEFT, rect->x) == FALSE)
|
||||
break;
|
||||
|
||||
configure->left_attach--;
|
||||
}
|
||||
|
||||
/* Check and expand right
|
||||
*/
|
||||
while (configure->right_attach < (table->ncols))
|
||||
{
|
||||
if (rect->x + rect->width >
|
||||
fixed->child_x_origin + fixed->child_width_origin &&
|
||||
GLADE_FIXED_CURSOR_RIGHT (fixed->operation) == FALSE)
|
||||
break;
|
||||
|
||||
if (glade_gtk_table_point_crosses_threshold
|
||||
(table, FALSE, configure->right_attach,
|
||||
DIR_RIGHT, rect->x + rect->width) == FALSE)
|
||||
break;
|
||||
|
||||
configure->right_attach++;
|
||||
}
|
||||
|
||||
/* Check and expand top
|
||||
*/
|
||||
while (configure->top_attach > 0)
|
||||
{
|
||||
if (rect->y < fixed->child_y_origin &&
|
||||
GLADE_FIXED_CURSOR_TOP (fixed->operation) == FALSE)
|
||||
break;
|
||||
|
||||
if (glade_gtk_table_point_crosses_threshold
|
||||
(table, TRUE, configure->top_attach -1,
|
||||
DIR_UP, rect->y) == FALSE)
|
||||
break;
|
||||
|
||||
configure->top_attach--;
|
||||
}
|
||||
|
||||
/* Check and expand bottom
|
||||
*/
|
||||
while (configure->bottom_attach < (table->nrows))
|
||||
{
|
||||
if (rect->y + rect->height >
|
||||
fixed->child_y_origin + fixed->child_height_origin &&
|
||||
GLADE_FIXED_CURSOR_BOTTOM (fixed->operation) == FALSE)
|
||||
break;
|
||||
|
||||
if (glade_gtk_table_point_crosses_threshold
|
||||
(table, TRUE, configure->bottom_attach,
|
||||
DIR_DOWN, rect->y + rect->height) == FALSE)
|
||||
break;
|
||||
|
||||
configure->bottom_attach++;
|
||||
}
|
||||
}
|
||||
|
||||
return column >= 0 && row >= 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_gtk_table_configure_child (GladeFixed *fixed,
|
||||
GladeWidget *child,
|
||||
GdkRectangle *rect,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *table = GTK_WIDGET (GLADE_WIDGET (fixed)->object);
|
||||
GladeGtkTableChild configure = { child, };
|
||||
|
||||
if (table_edit.reset)
|
||||
{
|
||||
memcpy (&table_edit.rect, rect, sizeof (GdkRectangle));
|
||||
table_edit.reset = FALSE;
|
||||
}
|
||||
|
||||
/* Sometimes we are unable to find a widget in the appropriate column,
|
||||
* usually because a placeholder hasnt had its size allocation yet.
|
||||
*/
|
||||
if (glade_gtk_table_get_attachments (fixed, GTK_TABLE (table), rect, &configure))
|
||||
{
|
||||
if (memcmp (&configure, &table_cur_attach, TABLE_CHILD_CMP_SIZE) != 0)
|
||||
{
|
||||
if (configure.left_attach < table_cur_attach.left_attach)
|
||||
{
|
||||
glade_widget_pack_property_set (child, "left-attach",
|
||||
configure.left_attach);
|
||||
glade_widget_pack_property_set (child, "right-attach",
|
||||
configure.right_attach);
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_widget_pack_property_set (child, "right-attach",
|
||||
configure.right_attach);
|
||||
glade_widget_pack_property_set (child, "left-attach",
|
||||
configure.left_attach);
|
||||
}
|
||||
|
||||
if (configure.top_attach < table_cur_attach.top_attach)
|
||||
{
|
||||
glade_widget_pack_property_set (child, "top-attach",
|
||||
configure.top_attach);
|
||||
glade_widget_pack_property_set (child, "bottom-attach",
|
||||
configure.bottom_attach);
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_widget_pack_property_set (child, "bottom-attach",
|
||||
configure.bottom_attach);
|
||||
glade_widget_pack_property_set (child, "top-attach",
|
||||
configure.top_attach);
|
||||
}
|
||||
memcpy (&table_cur_attach, &configure, TABLE_CHILD_CMP_SIZE);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
glade_gtk_table_configure_begin (GladeFixed *fixed,
|
||||
GladeWidget *child,
|
||||
gpointer unused)
|
||||
{
|
||||
|
||||
table_edit.widget = child;
|
||||
table_edit.reset = TRUE;
|
||||
|
||||
glade_widget_pack_property_get (child, "left-attach",
|
||||
&table_edit.left_attach);
|
||||
glade_widget_pack_property_get (child, "right-attach",
|
||||
&table_edit.right_attach);
|
||||
glade_widget_pack_property_get (child, "top-attach",
|
||||
&table_edit.top_attach);
|
||||
glade_widget_pack_property_get (child, "bottom-attach",
|
||||
&table_edit.bottom_attach);
|
||||
|
||||
memcpy (&table_cur_attach, &table_edit, TABLE_CHILD_CMP_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_gtk_table_configure_end (GladeFixed *fixed,
|
||||
GladeWidget *child,
|
||||
gpointer unused)
|
||||
{
|
||||
GladeGtkTableChild new = { child, };
|
||||
|
||||
glade_widget_pack_property_get (child, "left-attach",
|
||||
&new.left_attach);
|
||||
glade_widget_pack_property_get (child, "right-attach",
|
||||
&new.right_attach);
|
||||
glade_widget_pack_property_get (child, "top-attach",
|
||||
&new.top_attach);
|
||||
glade_widget_pack_property_get (child, "bottom-attach",
|
||||
&new.bottom_attach);
|
||||
|
||||
/* Compare the meaningfull part of the current edit. */
|
||||
if (memcmp (&new, &table_edit, TABLE_CHILD_CMP_SIZE) != 0)
|
||||
{
|
||||
GValue left_attach_value = { 0, };
|
||||
GValue right_attach_value = { 0, };
|
||||
GValue top_attach_value = { 0, };
|
||||
GValue bottom_attach_value = { 0, };
|
||||
|
||||
GValue new_left_attach_value = { 0, };
|
||||
GValue new_right_attach_value = { 0, };
|
||||
GValue new_top_attach_value = { 0, };
|
||||
GValue new_bottom_attach_value = { 0, };
|
||||
|
||||
GladeProperty *left_attach_prop, *right_attach_prop,
|
||||
*top_attach_prop, *bottom_attach_prop;
|
||||
|
||||
left_attach_prop = glade_widget_get_pack_property (child, "left-attach");
|
||||
right_attach_prop = glade_widget_get_pack_property (child, "right-attach");
|
||||
top_attach_prop = glade_widget_get_pack_property (child, "top-attach");
|
||||
bottom_attach_prop = glade_widget_get_pack_property (child, "bottom-attach");
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (left_attach_prop), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (right_attach_prop), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (top_attach_prop), FALSE);
|
||||
g_return_val_if_fail (GLADE_IS_PROPERTY (bottom_attach_prop), FALSE);
|
||||
|
||||
glade_property_get_value (left_attach_prop, &new_left_attach_value);
|
||||
glade_property_get_value (right_attach_prop, &new_right_attach_value);
|
||||
glade_property_get_value (top_attach_prop, &new_top_attach_value);
|
||||
glade_property_get_value (bottom_attach_prop, &new_bottom_attach_value);
|
||||
|
||||
|
||||
g_value_init (&left_attach_value, G_TYPE_UINT);
|
||||
g_value_init (&right_attach_value, G_TYPE_UINT);
|
||||
g_value_init (&top_attach_value, G_TYPE_UINT);
|
||||
g_value_init (&bottom_attach_value, G_TYPE_UINT);
|
||||
|
||||
g_value_set_uint (&left_attach_value, table_edit.left_attach);
|
||||
g_value_set_uint (&right_attach_value, table_edit.right_attach);
|
||||
g_value_set_uint (&top_attach_value, table_edit.top_attach);
|
||||
g_value_set_uint (&bottom_attach_value, table_edit.bottom_attach);
|
||||
|
||||
/* whew, all that for this call !
|
||||
*/
|
||||
glade_command_set_properties
|
||||
(left_attach_prop, &left_attach_value, &new_left_attach_value,
|
||||
right_attach_prop, &right_attach_value, &new_right_attach_value,
|
||||
top_attach_prop, &top_attach_value, &new_top_attach_value,
|
||||
bottom_attach_prop, &bottom_attach_value, &new_bottom_attach_value,
|
||||
NULL);
|
||||
|
||||
g_value_unset (&left_attach_value);
|
||||
g_value_unset (&right_attach_value);
|
||||
g_value_unset (&top_attach_value);
|
||||
g_value_unset (&bottom_attach_value);
|
||||
g_value_unset (&new_left_attach_value);
|
||||
g_value_unset (&new_right_attach_value);
|
||||
g_value_unset (&new_top_attach_value);
|
||||
g_value_unset (&new_bottom_attach_value);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
glade_gtk_table_post_create (GObject *container, GladeCreateReason reason)
|
||||
{
|
||||
GladeWidget *gwidget =
|
||||
glade_widget_get_from_gobject (container);
|
||||
|
||||
g_signal_connect (G_OBJECT (gwidget), "configure-child",
|
||||
G_CALLBACK (glade_gtk_table_configure_child), NULL);
|
||||
|
||||
g_signal_connect (G_OBJECT (gwidget), "configure-begin",
|
||||
G_CALLBACK (glade_gtk_table_configure_begin), NULL);
|
||||
|
||||
g_signal_connect (G_OBJECT (gwidget), "configure-end",
|
||||
G_CALLBACK (glade_gtk_table_configure_end), NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_gtk_table_has_child (GtkTable *table, guint left_attach, guint top_attach)
|
||||
{
|
||||
@ -610,7 +1021,7 @@ glade_gtk_table_refresh_placeholders (GtkTable *table)
|
||||
{
|
||||
GList *list, *toremove = NULL;
|
||||
gint i, j;
|
||||
|
||||
|
||||
for (list = table->children; list && list->data; list = list->next)
|
||||
{
|
||||
GtkTableChild *child = list->data;
|
||||
@ -633,8 +1044,11 @@ glade_gtk_table_refresh_placeholders (GtkTable *table)
|
||||
gtk_table_attach_defaults (table,
|
||||
glade_placeholder_new (),
|
||||
i, i + 1, j, j + 1);
|
||||
|
||||
gtk_container_check_resize (GTK_CONTAINER (table));
|
||||
}
|
||||
|
||||
|
||||
void GLADEGTK_API
|
||||
glade_gtk_table_add_child (GObject *object, GObject *child)
|
||||
{
|
||||
@ -642,6 +1056,7 @@ glade_gtk_table_add_child (GObject *object, GObject *child)
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
|
||||
|
||||
glade_gtk_table_refresh_placeholders (GTK_TABLE (object));
|
||||
}
|
||||
|
||||
@ -864,7 +1279,8 @@ glade_gtk_table_verify_left_top_attach (GObject *object,
|
||||
parent_prop, &parent_val))
|
||||
return FALSE;
|
||||
|
||||
if (val >= parent_val || val >= prop_val) return FALSE;
|
||||
if (val >= parent_val || val >= prop_val)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -882,7 +1298,8 @@ glade_gtk_table_verify_right_bottom_attach (GObject *object,
|
||||
parent_prop, &parent_val))
|
||||
return FALSE;
|
||||
|
||||
if (val <= prop_val || val > parent_val) return FALSE;
|
||||
if (val <= prop_val || val > parent_val)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "glade-property.h"
|
||||
#include "glade-property-class.h"
|
||||
#include "glade-clipboard.h"
|
||||
#include "glade-fixed.h"
|
||||
|
||||
#define GLADE_UTIL_SELECTION_NODE_SIZE 7
|
||||
#define GLADE_UTIL_COPY_BUFFSIZE 1024
|
||||
@ -1695,10 +1696,6 @@ glade_util_search_devhelp (const gchar *book,
|
||||
const gchar *page,
|
||||
const gchar *search)
|
||||
{
|
||||
/* XXX
|
||||
* g_spawn_command_line_somethingorother.
|
||||
*/
|
||||
|
||||
GError *error = NULL;
|
||||
gchar *book_comm = NULL, *page_comm = NULL;
|
||||
gchar *string;
|
||||
@ -1723,3 +1720,24 @@ glade_util_search_devhelp (const gchar *book,
|
||||
if (book_comm) g_free (book_comm);
|
||||
if (page_comm) g_free (page_comm);
|
||||
}
|
||||
|
||||
gboolean
|
||||
glade_util_deep_fixed_event (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GladeWidget *gwidget)
|
||||
{
|
||||
GladeWidget *event_widget, *search;
|
||||
|
||||
event_widget = glade_widget_event_widget ();
|
||||
|
||||
/* Look for a child GladeFixed
|
||||
*/
|
||||
for (search = event_widget;
|
||||
search && search != gwidget && GLADE_IS_FIXED (search) == FALSE;
|
||||
search = search->parent);
|
||||
|
||||
if (search && GLADE_IS_FIXED (search) && search != gwidget)
|
||||
return GLADE_WIDGET_GET_KLASS (search)->event (widget, event, search);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -138,6 +138,12 @@ LIBGLADEUI_API
|
||||
void glade_util_search_devhelp (const gchar *book,
|
||||
const gchar *page,
|
||||
const gchar *search);
|
||||
|
||||
LIBGLADEUI_API
|
||||
gboolean glade_util_deep_fixed_event (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GladeWidget *gwidget);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GLADE_UTILS_H__ */
|
||||
|
@ -1604,7 +1604,8 @@ glade_widget_class_create_widget_real (gboolean query,
|
||||
{
|
||||
g_critical ("No class found in glade_widget_class_create_widget_real args");
|
||||
va_end (vl_copy);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (widget_class->fixed)
|
||||
gwidget_type = GLADE_TYPE_FIXED;
|
||||
@ -1612,9 +1613,9 @@ glade_widget_class_create_widget_real (gboolean query,
|
||||
gwidget_type = GLADE_TYPE_WIDGET;
|
||||
|
||||
|
||||
gwidget = g_object_new_valist (gwidget_type,
|
||||
first_property,
|
||||
(va_list) vl_copy);
|
||||
gwidget = (GladeWidget *)g_object_new_valist (gwidget_type,
|
||||
first_property,
|
||||
(va_list) vl_copy);
|
||||
va_end (vl_copy);
|
||||
|
||||
if (query && glade_widget_class_query (widget_class))
|
||||
|
@ -86,14 +86,20 @@ enum
|
||||
PROP_REASON
|
||||
};
|
||||
|
||||
static guint glade_widget_signals[LAST_SIGNAL] = {0};
|
||||
static guint glade_widget_signals[LAST_SIGNAL] = {0};
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
/* Sometimes we need to use the project deep in the loading code,
|
||||
* this is just a shortcut way to get the project.
|
||||
*/
|
||||
static GladeProject *loading_project = NULL;
|
||||
static gboolean glade_widget_dupping = FALSE;
|
||||
static gboolean glade_widget_dupping = FALSE;
|
||||
static GQuark glade_widget_name_quark = 0;
|
||||
|
||||
/* An optimization to avoid looking up the deepest
|
||||
* widget more than once in an event.
|
||||
*/
|
||||
static GladeWidget *deep_event_widget = NULL;
|
||||
|
||||
/*******************************************************************************
|
||||
GladeWidget class methods
|
||||
@ -123,6 +129,25 @@ glade_widget_remove_child_impl (GladeWidget *widget,
|
||||
(widget->widget_class, widget->object, child->object);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_widget_replace_child_impl (GladeWidget *widget,
|
||||
GObject *old_object,
|
||||
GObject *new_object)
|
||||
{
|
||||
GladeWidget *gnew_widget = glade_widget_get_from_gobject (new_object);
|
||||
GladeWidget *gold_widget = glade_widget_get_from_gobject (old_object);
|
||||
|
||||
if (gnew_widget) gnew_widget->parent = widget;
|
||||
if (gold_widget) gold_widget->parent = NULL;
|
||||
|
||||
glade_widget_class_container_replace_child
|
||||
(widget->widget_class, widget->object,
|
||||
old_object, new_object);
|
||||
|
||||
if (gnew_widget)
|
||||
glade_widget_set_packing_properties (gnew_widget, widget);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_widget_add_signal_handler_impl (GladeWidget *widget, GladeSignal *signal_handler)
|
||||
{
|
||||
@ -296,8 +321,8 @@ glade_widget_find_deepest_child_at_position (GtkContainer *toplevel,
|
||||
* event and returns the real #GladeWidget that was clicked
|
||||
*
|
||||
*/
|
||||
static GladeWidget *
|
||||
glade_widget_retrieve_from_position_impl (GtkWidget *base, int x, int y)
|
||||
GladeWidget *
|
||||
glade_widget_retrieve_from_position (GtkWidget *base, int x, int y)
|
||||
{
|
||||
GladeWidget *lookup;
|
||||
GtkWidget *widget;
|
||||
@ -323,17 +348,12 @@ glade_widget_button_press (GtkWidget *widget,
|
||||
{
|
||||
GladeWidget *glade_widget;
|
||||
GtkWidget *event_widget;
|
||||
gint x = (gint) (event->x + 0.5);
|
||||
gint y = (gint) (event->y + 0.5);
|
||||
gboolean handled = FALSE;
|
||||
|
||||
/* Carefull to use the event widget and not the signal widget
|
||||
* to feed to retrieve_from_position
|
||||
/* Get event widget and event glade_widget
|
||||
*/
|
||||
gdk_window_get_user_data (event->window, (gpointer)&event_widget);
|
||||
if ((glade_widget =
|
||||
GLADE_WIDGET_GET_KLASS
|
||||
(gwidget)->retrieve_from_position (event_widget, x, y)) == NULL)
|
||||
if ((glade_widget = deep_event_widget) == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* make sure to grab focus, since we may stop default handlers */
|
||||
@ -402,8 +422,11 @@ glade_widget_setup_events (GladeWidget *gwidget,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_add_events (widget,
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK);
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK);
|
||||
|
||||
if (GTK_WIDGET_TOPLEVEL (widget))
|
||||
g_signal_connect (G_OBJECT (widget), "delete_event",
|
||||
@ -425,6 +448,7 @@ glade_widget_event (GtkWidget *widget,
|
||||
case GDK_BUTTON_PRESS:
|
||||
return glade_widget_button_press (widget, (GdkEventButton*) event, gwidget);
|
||||
case GDK_EXPOSE:
|
||||
case GDK_CONFIGURE:
|
||||
glade_util_queue_draw_nodes (((GdkEventExpose*) event)->window);
|
||||
break;
|
||||
default:
|
||||
@ -434,6 +458,61 @@ glade_widget_event (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_widget_event_private (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GladeWidget *gwidget)
|
||||
{
|
||||
GtkWidget *event_widget;
|
||||
gdouble x, y;
|
||||
|
||||
/* Get the widget at moust position before anything else
|
||||
*/
|
||||
gdk_event_get_coords (event, &x, &y);
|
||||
gdk_window_get_user_data (((GdkEventAny *)event)->window, (gpointer)&event_widget);
|
||||
gdk_window_get_pointer (((GdkEventAny *)event)->window, NULL, NULL, NULL);
|
||||
|
||||
deep_event_widget =
|
||||
glade_widget_retrieve_from_position
|
||||
(event_widget, (int) (x + 0.5), (int) (y + 0.5));
|
||||
|
||||
|
||||
/* Check if there are deep fixed widgets without windows
|
||||
* that need to be processed first.
|
||||
*/
|
||||
if (glade_util_deep_fixed_event (widget, event, gwidget) == FALSE)
|
||||
{
|
||||
gboolean handled;
|
||||
|
||||
/* Run the real class handler now.
|
||||
*/
|
||||
handled = GLADE_WIDGET_GET_KLASS (gwidget)->event (widget, event, gwidget);
|
||||
|
||||
#if 0
|
||||
g_print ("event widget '%s' handled '%d'\n",
|
||||
deep_event_widget->name, handled);
|
||||
#endif
|
||||
return handled;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
#if 0
|
||||
g_print ("Forwarded the button event to a fixed widget "
|
||||
"(event widget '%s')\n",
|
||||
deep_event_widget->name);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
GObjectClass & Object Construction
|
||||
*******************************************************************************/
|
||||
@ -874,6 +953,10 @@ glade_widget_class_init (GladeWidgetKlass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
if (glade_widget_name_quark == 0)
|
||||
glade_widget_name_quark =
|
||||
g_quark_from_static_string ("GladeWidgetDataTag");
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
@ -885,12 +968,11 @@ glade_widget_class_init (GladeWidgetKlass *klass)
|
||||
|
||||
klass->add_child = glade_widget_add_child_impl;
|
||||
klass->remove_child = glade_widget_remove_child_impl;
|
||||
|
||||
klass->replace_child = glade_widget_replace_child_impl;
|
||||
klass->add_signal_handler = glade_widget_add_signal_handler_impl;
|
||||
klass->remove_signal_handler = glade_widget_remove_signal_handler_impl;
|
||||
klass->change_signal_handler = glade_widget_change_signal_handler_impl;
|
||||
|
||||
klass->retrieve_from_position = glade_widget_retrieve_from_position_impl;
|
||||
klass->setup_events = glade_widget_setup_events;
|
||||
klass->event = glade_widget_event;
|
||||
|
||||
@ -1795,6 +1877,14 @@ glade_widget_info_params (GladeWidgetClass *widget_class,
|
||||
/*******************************************************************************
|
||||
API
|
||||
*******************************************************************************/
|
||||
GladeWidget *
|
||||
glade_widget_get_from_gobject (gpointer object)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
|
||||
|
||||
return g_object_get_qdata (G_OBJECT (object), glade_widget_name_quark);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_widget_debug_real (GladeWidget *widget, int indent)
|
||||
{
|
||||
@ -2764,8 +2854,7 @@ glade_widget_set_object (GladeWidget *gwidget, GObject *new_object)
|
||||
|
||||
glade_widget_connect_signal_handlers
|
||||
(GTK_WIDGET(new_object),
|
||||
G_CALLBACK
|
||||
(GLADE_WIDGET_GET_KLASS (gwidget)->event),
|
||||
G_CALLBACK (glade_widget_event_private),
|
||||
gwidget);
|
||||
}
|
||||
|
||||
@ -2931,6 +3020,25 @@ glade_widget_has_decendant (GladeWidget *widget, GType type)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* glade_widget_event_widget:
|
||||
*
|
||||
* During events, this function returns the deepest
|
||||
* project widget at moust position, or %NULL if it is
|
||||
* not a mouse event.
|
||||
*
|
||||
* Handle with care, you must be in an event for
|
||||
* the return value to be meaningfull
|
||||
*
|
||||
* Returns a #GladeWidget
|
||||
*/
|
||||
GladeWidget *
|
||||
glade_widget_event_widget (void)
|
||||
{
|
||||
return deep_event_widget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* glade_widget_replace:
|
||||
* @old_object: a #GObject
|
||||
@ -2944,24 +3052,10 @@ glade_widget_has_decendant (GladeWidget *widget, GType type)
|
||||
void
|
||||
glade_widget_replace (GladeWidget *parent, GObject *old_object, GObject *new_object)
|
||||
{
|
||||
GladeWidget *gnew_widget = NULL;
|
||||
GladeWidget *gold_widget = NULL;
|
||||
|
||||
g_return_if_fail (G_IS_OBJECT (old_object));
|
||||
g_return_if_fail (G_IS_OBJECT (new_object));
|
||||
|
||||
gnew_widget = glade_widget_get_from_gobject (new_object);
|
||||
gold_widget = glade_widget_get_from_gobject (old_object);
|
||||
|
||||
if (gnew_widget) gnew_widget->parent = parent;
|
||||
if (gold_widget) gold_widget->parent = NULL;
|
||||
|
||||
glade_widget_class_container_replace_child
|
||||
(parent->widget_class, parent->object,
|
||||
old_object, new_object);
|
||||
|
||||
if (gnew_widget)
|
||||
glade_widget_set_packing_properties (gnew_widget, parent);
|
||||
GLADE_WIDGET_GET_KLASS (parent)->replace_child (parent, old_object, new_object);
|
||||
}
|
||||
|
||||
/* XML Serialization */
|
||||
|
@ -18,8 +18,6 @@ G_BEGIN_DECLS
|
||||
#define GLADE_IS_WIDGET_KLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_WIDGET))
|
||||
#define GLADE_WIDGET_GET_KLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_WIDGET, GladeWidgetKlass))
|
||||
|
||||
#define glade_widget_get_from_gobject(w) g_object_get_data (G_OBJECT (w), "GladeWidgetDataTag")
|
||||
|
||||
typedef struct _GladeWidgetKlass GladeWidgetKlass;
|
||||
|
||||
struct _GladeWidget
|
||||
@ -103,6 +101,7 @@ struct _GladeWidgetKlass
|
||||
|
||||
void (*add_child) (GladeWidget *, GladeWidget *, gboolean);
|
||||
void (*remove_child) (GladeWidget *, GladeWidget *);
|
||||
void (*replace_child) (GladeWidget *, GObject *, GObject *);
|
||||
|
||||
void (*add_signal_handler) (GladeWidget *, GladeSignal *);
|
||||
void (*remove_signal_handler) (GladeWidget *, GladeSignal *);
|
||||
@ -111,8 +110,6 @@ struct _GladeWidgetKlass
|
||||
void (*setup_events) (GladeWidget *, GtkWidget *);
|
||||
gboolean (*event) (GtkWidget *, GdkEvent *, GladeWidget *);
|
||||
|
||||
GladeWidget *(*retrieve_from_position) (GtkWidget *, int, int);
|
||||
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
@ -121,6 +118,8 @@ struct _GladeWidgetKlass
|
||||
LIBGLADEUI_API
|
||||
GType glade_widget_get_type (void);
|
||||
LIBGLADEUI_API
|
||||
GladeWidget *glade_widget_get_from_gobject (gpointer object);
|
||||
LIBGLADEUI_API
|
||||
void glade_widget_add_child (GladeWidget *parent,
|
||||
GladeWidget *child,
|
||||
gboolean at_mouse);
|
||||
@ -179,9 +178,10 @@ LIBGLADEUI_API
|
||||
void glade_widget_launch_editor (GladeWidget *widget);
|
||||
|
||||
LIBGLADEUI_API
|
||||
gboolean glade_widget_has_decendant (GladeWidget *widget,
|
||||
GType type);
|
||||
|
||||
gboolean glade_widget_has_decendant (GladeWidget *widget,
|
||||
GType type);
|
||||
LIBGLADEUI_API
|
||||
GladeWidget *glade_widget_event_widget (void);
|
||||
/*******************************************************************************
|
||||
Project, object property references
|
||||
*******************************************************************************/
|
||||
|
@ -44,7 +44,7 @@ typedef struct _GladeProject GladeProject;
|
||||
#include "glade-utils.h"
|
||||
#include "glade-builtins.h"
|
||||
#include "glade-xml-utils.h"
|
||||
|
||||
#include "glade-fixed.h"
|
||||
|
||||
#define GLADE_TAG_FALSE "False"
|
||||
#define GLADE_TAG_TRUE "True"
|
||||
|
@ -748,8 +748,8 @@
|
||||
<glade-widget-class name="GtkHBox" generic-name="hbox" _title="Horizontal Box"/>
|
||||
<glade-widget-class name="GtkVBox" generic-name="vbox" _title="Vertical Box"/>
|
||||
|
||||
<glade-widget-class name="GtkTable" generic-name="table" _title="Table">
|
||||
<post-create-function>empty</post-create-function>
|
||||
<glade-widget-class name="GtkTable" generic-name="table" _title="Table" fixed="True">
|
||||
<post-create-function>glade_gtk_table_post_create</post-create-function>
|
||||
<properties>
|
||||
<property id="n-rows" default="3" query="True">
|
||||
<set-function>glade_gtk_table_set_n_rows</set-function>
|
||||
|
Loading…
x
Reference in New Issue
Block a user