summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Pablo Ugarte <juanpablougarte@gmail.com>2012-12-17 22:35:51 -0300
committerJuan Pablo Ugarte <juanpablougarte@gmail.com>2013-01-18 19:56:05 -0300
commitf19314fe1cd81e369145c607a3231a7ddcebf3b5 (patch)
tree3334717660425ee9b4f0c9d841802715fb545574
parentf8151e4584eff38f9392700485961324133aa6c7 (diff)
downloadglade-f19314fe1cd81e369145c607a3231a7ddcebf3b5.tar.gz
Implemented inline Drag and Drop
-rw-r--r--gladeui/glade-design-layout.c262
-rw-r--r--gladeui/glade-design-private.h12
-rw-r--r--gladeui/glade-design-view.c580
-rw-r--r--plugins/gtk+/glade-fixed.c24
-rw-r--r--plugins/gtk+/glade-gtk.c3
5 files changed, 647 insertions, 234 deletions
diff --git a/gladeui/glade-design-layout.c b/gladeui/glade-design-layout.c
index 8a180c10..210555b7 100644
--- a/gladeui/glade-design-layout.c
+++ b/gladeui/glade-design-layout.c
@@ -38,6 +38,7 @@
#define GLADE_DESIGN_LAYOUT_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
GLADE_TYPE_DESIGN_LAYOUT, \
GladeDesignLayoutPrivate))
+#define GLADE_DESIGN_LAYOUT_PRIVATE(object) (((GladeDesignLayout*)object)->priv)
#define OUTLINE_WIDTH 4
#define PADDING 12
@@ -104,6 +105,11 @@ struct _GladeDesignLayoutPrivate
gint new_width; /* user's new requested width */
gint new_height; /* user's new requested height */
+ /* Drag & Drop */
+ GtkWidget *drag_source;
+ GtkWidget *drag_icon;
+ gint drag_x, drag_y;
+
/* Properties */
GladeDesignView *view;
GladeProject *project;
@@ -227,7 +233,7 @@ glade_design_layout_leave_notify_event (GtkWidget *widget, GdkEventCrossing *ev)
ev->window != gtk_widget_get_window (widget))
return FALSE;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
if (priv->activity == ACTIVITY_NONE)
gdl_set_cursor (priv, NULL);
@@ -355,11 +361,23 @@ glade_design_layout_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev)
if ((child = gtk_bin_get_child (GTK_BIN (widget))) == NULL)
return FALSE;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
x = ev->x;
y = ev->y;
+ if (ev->state & GDK_BUTTON1_MASK && priv->drag_source &&
+ gtk_drag_check_threshold (priv->drag_source, priv->drag_x, priv->drag_y, x, y))
+ {
+ static GtkTargetList *target = NULL;
+
+ if (target == NULL)
+ target = gtk_target_list_new (_glade_design_layout_get_dnd_target (), 1);
+
+ gtk_drag_begin (widget, target, GDK_ACTION_COPY, 1, (GdkEvent*)ev);
+ return TRUE;
+ }
+
gtk_widget_get_allocation (child, &allocation);
allocation.x += priv->child_offset;
@@ -573,7 +591,7 @@ glade_design_layout_button_press_event (GtkWidget *widget, GdkEventButton *ev)
(child = gtk_bin_get_child (GTK_BIN (widget))) == NULL)
return FALSE;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
x = ev->x;
y = ev->y;
@@ -695,7 +713,7 @@ glade_design_layout_button_release_event (GtkWidget *widget,
if ((child = gtk_bin_get_child (GTK_BIN (widget))) == NULL)
return FALSE;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
/* Check if margins where edited and execute corresponding glade command */
if (priv->selection && priv->activity == ACTIVITY_MARGINS)
@@ -756,7 +774,7 @@ glade_design_layout_get_preferred_height (GtkWidget *widget,
gint child_height = 0;
guint border_width = 0;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
*minimum = 0;
@@ -889,7 +907,7 @@ glade_design_layout_size_allocate (GtkWidget *widget,
if (child && gtk_widget_get_visible (child))
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
GtkAllocation alloc;
gint height, offset;
@@ -917,7 +935,7 @@ glade_design_layout_size_allocate (GtkWidget *widget,
static void
on_glade_widget_name_notify (GObject *gobject, GParamSpec *pspec, GladeDesignLayout *layout)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
+ GladeDesignLayoutPrivate *priv = layout->priv;
pango_layout_set_text (priv->widget_name, glade_widget_get_name (GLADE_WIDGET (gobject)), -1);
gtk_widget_queue_resize (GTK_WIDGET (layout));
@@ -926,8 +944,8 @@ on_glade_widget_name_notify (GObject *gobject, GParamSpec *pspec, GladeDesignLay
static void
glade_design_layout_add (GtkContainer *container, GtkWidget *widget)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (container);
GladeDesignLayout *layout = GLADE_DESIGN_LAYOUT (container);
+ GladeDesignLayoutPrivate *priv = layout->priv;
GladeWidget *gchild;
layout->priv->current_width = 0;
@@ -1179,7 +1197,7 @@ draw_selection (cairo_t *cr,
cairo_stroke (cr);
}
-#define DIMENSION_OFFSET 10
+#define DIMENSION_OFFSET 9
#define DIMENSION_LINE_OFFSET 4
static void
@@ -1489,7 +1507,7 @@ draw_selection_nodes (cairo_t *cr,
static gboolean
glade_design_layout_draw (GtkWidget *widget, cairo_t *cr)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
GdkWindow *window = gtk_widget_get_window (widget);
if (gtk_cairo_should_draw_window (cr, window))
@@ -1568,7 +1586,7 @@ to_child (GladeDesignLayout *bin,
double *x_out,
double *y_out)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (bin);
+ GladeDesignLayoutPrivate *priv = bin->priv;
*x_out = widget_x - priv->child_offset;
*y_out = widget_y - priv->child_offset;
}
@@ -1580,7 +1598,7 @@ to_parent (GladeDesignLayout *bin,
double *x_out,
double *y_out)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (bin);
+ GladeDesignLayoutPrivate *priv = bin->priv;
*x_out = offscreen_x + priv->child_offset;
*y_out = offscreen_y + priv->child_offset;
}
@@ -1591,7 +1609,7 @@ pick_offscreen_child (GdkWindow *offscreen_window,
double widget_y,
GladeDesignLayout *bin)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (bin);
+ GladeDesignLayoutPrivate *priv = bin->priv;
GtkWidget *child = gtk_bin_get_child (GTK_BIN (bin));
if (child && gtk_widget_get_visible (child))
@@ -1660,12 +1678,11 @@ glade_design_layout_realize (GtkWidget * widget)
{
GladeDesignLayoutPrivate *priv;
GdkWindowAttr attributes;
- GtkWidget *child;
gint attributes_mask, border_width;
GtkAllocation allocation;
GdkDisplay *display;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
gtk_widget_set_realized (widget, TRUE);
@@ -1700,26 +1717,14 @@ glade_design_layout_realize (GtkWidget * widget)
G_CALLBACK (pick_offscreen_child), widget);
/* Offscreen window */
- child = gtk_bin_get_child (GTK_BIN (widget));
attributes.window_type = GDK_WINDOW_OFFSCREEN;
attributes.x = attributes.y = 0;
-
- if (child && gtk_widget_get_visible (child))
- {
- GtkAllocation alloc;
-
- gtk_widget_get_allocation (child, &alloc);
- attributes.width = alloc.width;
- attributes.height = alloc.height;
- }
- else
- attributes.width = attributes.height = 0;
+ attributes.width = attributes.height = 0;
priv->offscreen_window = gdk_window_new (gtk_widget_get_root_window (widget),
&attributes, attributes_mask);
gdk_window_set_user_data (priv->offscreen_window, widget);
- if (child) gtk_widget_set_parent_window (child, priv->offscreen_window);
gdk_offscreen_window_set_embedder (priv->offscreen_window, priv->window);
g_signal_connect (priv->offscreen_window, "to-embedder",
@@ -1756,7 +1761,7 @@ glade_design_layout_unrealize (GtkWidget * widget)
GladeDesignLayoutPrivate *priv;
gint i;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
if (priv->offscreen_window)
{
@@ -1786,26 +1791,6 @@ glade_design_layout_unrealize (GtkWidget * widget)
GTK_WIDGET_CLASS (glade_design_layout_parent_class)->unrealize (widget);
}
-void
-_glade_design_layout_get_colors (GtkStyleContext *context,
- GdkRGBA *c1, GdkRGBA *c2,
- GdkRGBA *c3, GdkRGBA *c4)
-{
- gfloat off;
-
- gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, c1);
- gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, c2);
-
- gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED, c3);
- gtk_style_context_get_color (context, GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED, c4);
-
- off = ((c1->red + c1->green + c1->blue)/3 < .5) ? .16 : -.16;
-
- c1->red += off;
- c1->green += off;
- c1->blue += off;
-}
-
static void
glade_design_layout_style_updated (GtkWidget *widget)
{
@@ -1883,7 +1868,7 @@ glade_design_layout_set_property (GObject *object,
{
case PROP_DESIGN_VIEW:
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (object);
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (object);
priv->view = GLADE_DESIGN_VIEW (g_value_get_object (value));
priv->project = glade_design_view_get_project (priv->view);
g_signal_connect (priv->project, "notify::pointer-mode",
@@ -1907,7 +1892,7 @@ glade_design_layout_get_property (GObject *object,
switch (prop_id)
{
case PROP_DESIGN_VIEW:
- g_value_set_object (value, GLADE_DESIGN_LAYOUT_GET_PRIVATE (object)->view);
+ g_value_set_object (value, GLADE_DESIGN_LAYOUT_PRIVATE (object)->view);
break;
default:
@@ -1919,7 +1904,7 @@ glade_design_layout_get_property (GObject *object,
static void
on_project_selection_changed (GladeProject *project, GladeDesignLayout *layout)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
+ GladeDesignLayoutPrivate *priv = layout->priv;
GladePointerMode mode = glade_project_get_pointer_mode (project);
if (priv->selection)
@@ -1943,7 +1928,7 @@ glade_design_layout_constructor (GType type,
n_construct_params,
construct_params);
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (object);
+ priv = GLADE_DESIGN_LAYOUT_PRIVATE (object);
g_signal_connect (priv->project,
"selection-changed",
@@ -1958,19 +1943,100 @@ glade_design_layout_constructor (GType type,
static void
glade_design_layout_finalize (GObject *object)
{
- GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (object);
+ GladeDesignLayout *layout = GLADE_DESIGN_LAYOUT (object);
+ GladeDesignLayoutPrivate *priv = layout->priv;
g_signal_handlers_disconnect_by_func (priv->project,
on_project_selection_changed,
- GLADE_DESIGN_LAYOUT (object));
+ layout);
g_signal_handlers_disconnect_by_func (priv->project,
on_pointer_mode_notify,
- GLADE_DESIGN_LAYOUT (object));
+ layout);
G_OBJECT_CLASS (glade_design_layout_parent_class)->finalize (object);
}
static void
+glade_design_layout_drag_begin (GtkWidget *widget, GdkDragContext *context)
+{
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
+ cairo_pattern_t *pattern;
+ cairo_surface_t *surface;
+ GtkAllocation alloc;
+ GtkWidget *window;
+ GdkScreen *screen;
+ cairo_t *cr;
+ gint x, y;
+
+ gtk_widget_get_allocation (priv->drag_source, &alloc);
+
+ gtk_widget_translate_coordinates (priv->drag_source, widget,
+ alloc.x, alloc.y,
+ &x, &y);
+
+ screen = gdk_window_get_screen (gdk_drag_context_get_source_window (context));
+ window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
+ gtk_window_set_screen (GTK_WINDOW (window), screen);
+
+ gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+ gtk_widget_set_app_paintable (window, TRUE);
+
+ gtk_widget_set_size_request (window, alloc.width, alloc.height);
+ gtk_widget_realize (window);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, alloc.width, alloc.height);
+ cr = cairo_create (surface);
+
+ gdk_cairo_set_source_window (cr, priv->window, alloc.x - x, alloc.y - y);
+ cairo_paint (cr);
+ cairo_surface_flush (surface);
+
+ pattern = cairo_pattern_create_for_surface (surface);
+
+ gdk_window_set_background_pattern (gtk_widget_get_window (window), pattern);
+
+ gtk_window_set_opacity (GTK_WINDOW (window), .5);
+ gtk_drag_set_icon_widget (context, window, priv->drag_x, priv->drag_y);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (surface);
+
+ priv->drag_icon = g_object_ref_sink (window);
+}
+
+static void
+glade_design_layout_drag_data_get (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *data,
+ guint info,
+ guint time)
+{
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
+
+ if (priv->drag_source)
+ {
+ static GdkAtom type = 0;
+
+ if (!type)
+ type = gdk_atom_intern_static_string (GDL_DND_TARGET_WIDGET);
+
+ gtk_selection_data_set (data, type, sizeof (gpointer),
+ (const guchar *)&priv->drag_source, sizeof (gpointer));
+ }
+}
+
+static void
+glade_design_layout_drag_end (GtkWidget *widget, GdkDragContext *context)
+{
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget);
+
+ g_clear_object (&priv->drag_icon);
+ priv->drag_source = NULL;
+}
+
+static void
glade_design_layout_class_init (GladeDesignLayoutClass * klass)
{
GObjectClass *object_class;
@@ -2002,6 +2068,9 @@ glade_design_layout_class_init (GladeDesignLayoutClass * klass)
widget_class->get_preferred_height_for_width = glade_design_layout_get_preferred_height_for_width;
widget_class->size_allocate = glade_design_layout_size_allocate;
widget_class->style_updated = glade_design_layout_style_updated;
+ widget_class->drag_begin = glade_design_layout_drag_begin;
+ widget_class->drag_end = glade_design_layout_drag_end;
+ widget_class->drag_data_get = glade_design_layout_drag_data_get;
g_object_class_install_property (object_class, PROP_DESIGN_VIEW,
g_param_spec_object ("design-view", _("Design View"),
@@ -2131,6 +2200,60 @@ _glade_design_layout_coords_from_event (GdkWindow *parent,
*y = yy;
}
+void
+_glade_design_layout_get_colors (GtkStyleContext *context,
+ GdkRGBA *c1, GdkRGBA *c2,
+ GdkRGBA *c3, GdkRGBA *c4)
+{
+ gfloat off;
+
+ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, c1);
+ gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, c2);
+
+ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED, c3);
+ gtk_style_context_get_color (context, GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED, c4);
+
+ off = ((c1->red + c1->green + c1->blue)/3 < .5) ? .16 : -.16;
+
+ c1->red += off;
+ c1->green += off;
+ c1->blue += off;
+}
+
+GtkTargetEntry *
+_glade_design_layout_get_dnd_target (void)
+{
+ static GtkTargetEntry target = {GDL_DND_TARGET_WIDGET, GTK_TARGET_SAME_APP, GDL_DND_INFO_WIDGET};
+ return &target;
+}
+
+void
+_glade_design_layout_get_hot_point (GladeDesignLayout *layout,
+ gint *x,
+ gint *y)
+{
+ GladeDesignLayoutPrivate *priv = layout->priv;
+
+ if (x)
+ *x = priv->drag_x;
+
+ if (y)
+ *y = priv->drag_y;
+}
+
+static gboolean
+widget_is_inside_fixed (GladeWidget *widget)
+{
+ while (widget)
+ {
+ if (GTK_IS_FIXED (glade_widget_get_object (widget)))
+ return TRUE;
+ widget = glade_widget_get_parent (widget);
+ }
+
+ return FALSE;
+}
+
/*
* _glade_design_layout_do_event:
* @layout: A #GladeDesignLayout
@@ -2147,15 +2270,38 @@ _glade_design_layout_do_event (GladeDesignLayout *layout, GdkEvent *event)
GtkWidget *widget = GTK_WIDGET (layout);
GladeFindInContainerData data = { widget, 0, };
GladeDesignLayoutPrivate *priv;
+ GladePointerMode mode;
gboolean retval;
GList *l;
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
+ priv = layout->priv;
_glade_design_layout_coords_from_event (priv->window, event, &data.x, &data.y);
+ mode = glade_project_get_pointer_mode (priv->project);
+ glade_design_layout_find_inside_container (widget, &data);
+
+ if (event->type == GDK_BUTTON_PRESS && event->button.button == 1 &&
+ ((event->button.state & GDK_SHIFT_MASK && mode == GLADE_POINTER_SELECT) ||
+ mode == GLADE_POINTER_DRAG_RESIZE))
+ {
+ GObject *source;
+
+ if (data.gwidget && (source = glade_widget_get_object (data.gwidget)) &&
+ (event->button.state & GDK_SHIFT_MASK || !widget_is_inside_fixed (data.gwidget)))
+ {
+ priv->drag_source = GTK_WIDGET (source);
+
+ gtk_widget_translate_coordinates (widget, priv->drag_source,
+ data.x, data.y,
+ &priv->drag_x, &priv->drag_y);
+ return TRUE;
+ }
+ }
+
/* Check if we want to enter in margin edit mode */
if (event->type == GDK_BUTTON_PRESS && event->button.button == 1 &&
+ mode != GLADE_POINTER_DRAG_RESIZE &&
(l = glade_project_selection_get (priv->project)) &&
g_list_next (l) == NULL && GTK_IS_WIDGET (l->data) &&
gtk_widget_is_ancestor (l->data, widget))
@@ -2175,8 +2321,6 @@ _glade_design_layout_do_event (GladeDesignLayout *layout, GdkEvent *event)
}
_glade_design_view_freeze (priv->view);
-
- glade_design_layout_find_inside_container (widget, &data);
/* Try the placeholder first */
if (data.placeholder && gtk_widget_event (data.placeholder, event))
diff --git a/gladeui/glade-design-private.h b/gladeui/glade-design-private.h
index a6babecf..a8046f48 100644
--- a/gladeui/glade-design-private.h
+++ b/gladeui/glade-design-private.h
@@ -25,6 +25,12 @@
#ifndef __GLADE_DESIGN_PRIVATE_H__
#define __GLADE_DESIGN_PRIVATE_H__
+#define GDL_DND_INFO_WIDGET 15956
+#define GDL_DND_TARGET_WIDGET "glade/x-widget"
+
+#include "glade-design-view.h"
+#include "glade-design-layout.h"
+
G_BEGIN_DECLS
void _glade_design_view_freeze (GladeDesignView *view);
@@ -47,6 +53,12 @@ void _glade_design_layout_draw_pushpin (cairo_t *cr,
GdkRGBA *bg,
GdkRGBA *fg);
+void _glade_design_layout_get_hot_point (GladeDesignLayout *layout,
+ gint *x,
+ gint *y);
+
+GtkTargetEntry *_glade_design_layout_get_dnd_target (void);
+
G_END_DECLS
#endif /* __GLADE_DESIGN_PRIVATE_H__ */
diff --git a/gladeui/glade-design-view.c b/gladeui/glade-design-view.c
index aae16ff4..fa931429 100644
--- a/gladeui/glade-design-view.c
+++ b/gladeui/glade-design-view.c
@@ -63,6 +63,8 @@ struct _GladeDesignViewPrivate
GtkToolPalette *palette;
GladeWidgetAdaptor *drag_adaptor;
+ GtkWidget *drag_source;
+ GtkWidget *drag_target;
};
static GtkVBoxClass *parent_class = NULL;
@@ -103,30 +105,36 @@ on_layout_size_allocate (GtkWidget *widget, GtkAllocation *alloc, GladeDesignVie
static void
glade_design_view_selection_changed (GladeProject *project, GladeDesignView *view)
{
- GladeWidget *gwidget, *gtoplevel;
- GObject *toplevel;
- GtkWidget *layout;
GList *selection;
/* Check if its only one widget selected and scroll viewport to show toplevel */
if ((selection = glade_project_selection_get (project)) &&
g_list_next (selection) == NULL &&
- GTK_IS_WIDGET (selection->data) &&
- !GLADE_IS_PLACEHOLDER (selection->data) &&
- (gwidget = glade_widget_get_from_gobject (G_OBJECT (selection->data))) &&
- (gtoplevel = glade_widget_get_toplevel (gwidget)) &&
- (toplevel = glade_widget_get_object (gtoplevel)) &&
- GTK_IS_WIDGET (toplevel) &&
- (layout = gtk_widget_get_parent (GTK_WIDGET (toplevel))) &&
- GLADE_IS_DESIGN_LAYOUT (layout))
+ GTK_IS_WIDGET (selection->data))
{
- GtkAllocation alloc;
- gtk_widget_get_allocation (layout, &alloc);
-
- if (alloc.x < 0)
- g_signal_connect (layout, "size-allocate", G_CALLBACK (on_layout_size_allocate), view);
- else
- glade_design_layout_scroll (view, alloc.x, alloc.y, alloc.width, alloc.height);
+ GladeWidget *gwidget, *gtoplevel;
+ GObject *toplevel;
+
+ if (!GLADE_IS_PLACEHOLDER (selection->data) &&
+ (gwidget = glade_widget_get_from_gobject (G_OBJECT (selection->data))) &&
+ (gtoplevel = glade_widget_get_toplevel (gwidget)) &&
+ (toplevel = glade_widget_get_object (gtoplevel)) &&
+ GTK_IS_WIDGET (toplevel))
+ {
+ GtkWidget *layout;
+
+ if ((layout = gtk_widget_get_parent (GTK_WIDGET (toplevel))) &&
+ GLADE_IS_DESIGN_LAYOUT (layout))
+ {
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (layout, &alloc);
+
+ if (alloc.x < 0)
+ g_signal_connect (layout, "size-allocate", G_CALLBACK (on_layout_size_allocate), view);
+ else
+ glade_design_layout_scroll (view, alloc.x, alloc.y, alloc.width, alloc.height);
+ }
+ }
}
}
@@ -151,8 +159,9 @@ glade_design_view_add_toplevel (GladeDesignView *view, GladeWidget *widget)
if ((toplevels = glade_project_toplevels (view->priv->project)))
gtk_box_reorder_child (GTK_BOX (view->priv->layout_box), layout,
g_list_index (toplevels, GTK_WIDGET (object)));
-
+
gtk_container_add (GTK_CONTAINER (layout), GTK_WIDGET (object));
+
gtk_widget_show (GTK_WIDGET (object));
gtk_widget_show (layout);
}
@@ -326,7 +335,6 @@ glade_design_view_init (GladeDesignView *view)
view->priv->layout_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_valign (view->priv->layout_box, GTK_ALIGN_START);
gtk_container_set_border_width (GTK_CONTAINER (view->priv->layout_box), 0);
- gtk_box_pack_end (GTK_BOX (view->priv->layout_box), gtk_fixed_new (), FALSE, FALSE, 0);
view->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
@@ -354,95 +362,16 @@ glade_design_view_init (GladeDesignView *view)
}
static void
-glade_design_view_class_init (GladeDesignViewClass *klass)
-{
- GObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- parent_class = g_type_class_peek_parent (klass);
- object_class = G_OBJECT_CLASS (klass);
- widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->get_property = glade_design_view_get_property;
- object_class->set_property = glade_design_view_set_property;
-
- widget_class->draw = glade_design_view_draw;
-
- g_object_class_install_property (object_class,
- PROP_PROJECT,
- g_param_spec_object ("project",
- "Project",
- "The project for this view",
- GLADE_TYPE_PROJECT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
- PROP_DRAG_SOURCE,
- g_param_spec_object ("drag-source",
- "Drag Source",
- "A palette to use as the source of drag events for this view",
- GTK_TYPE_TOOL_PALETTE,
- G_PARAM_READWRITE));
-
- g_type_class_add_private (object_class, sizeof (GladeDesignViewPrivate));
-}
-
-/* Private API */
-
-void
-_glade_design_view_freeze (GladeDesignView *view)
-{
- g_return_if_fail (GLADE_IS_DESIGN_VIEW (view));
-
- g_signal_handlers_block_by_func (view->priv->project,
- glade_design_view_selection_changed,
- view);
-}
-
-void
-_glade_design_view_thaw (GladeDesignView *view)
-{
- g_return_if_fail (GLADE_IS_DESIGN_VIEW (view));
-
- g_signal_handlers_unblock_by_func (view->priv->project,
- glade_design_view_selection_changed,
- view);
-}
-
-/* Public API */
-
-GladeProject *
-glade_design_view_get_project (GladeDesignView *view)
-{
- g_return_val_if_fail (GLADE_IS_DESIGN_VIEW (view), NULL);
-
- return view->priv->project;
-
-}
-
-GtkWidget *
-glade_design_view_new (GladeProject *project)
+glade_design_view_finalize (GObject *object)
{
- GladeDesignView *view;
+ GladeDesignView *view = GLADE_DESIGN_VIEW (object);
+ GladeDesignViewPrivate *priv = view->priv;
- g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
-
- view = g_object_new (GLADE_TYPE_DESIGN_VIEW, "project", project, NULL);
-
- return GTK_WIDGET (view);
-}
-
-GladeDesignView *
-glade_design_view_get_from_project (GladeProject *project)
-{
- gpointer p;
-
- g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
-
- p = g_object_get_data (G_OBJECT (project), GLADE_DESIGN_VIEW_KEY);
-
- return (p != NULL) ? GLADE_DESIGN_VIEW (p) : NULL;
+ /* Yup, disconnect every handler that reference this view */
+ g_signal_handlers_disconnect_by_data (priv->project, view);
+ g_signal_handlers_disconnect_by_data (priv->project, priv->scrolled_window);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GtkWidget *
@@ -486,107 +415,419 @@ widget_get_child_from_position (GtkWidget *toplevel, GtkWidget *widget, gint x,
return retval;
}
+static GtkWidget *
+widget_get_gchild_from_position (GtkWidget *toplevel, GtkWidget *widget, gint x, gint y)
+{
+ GtkWidget *retval = widget_get_child_from_position (toplevel, widget, x, y);
+
+ while (retval)
+ {
+ if (retval == toplevel || GLADE_IS_PLACEHOLDER (retval) ||
+ glade_widget_get_from_gobject (retval))
+ return retval;
+
+ retval = gtk_widget_get_parent (retval);
+ }
+
+ return NULL;
+}
+
static gboolean
-widget_is_outside_glade_ancestor (GtkWidget *widget)
+drag_highlight_draw (GtkWidget *widget, cairo_t *cr, GladeDesignView *view)
{
- while (widget)
+ GtkStyleContext *context;
+ gint width, height;
+ GdkRGBA c;
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (view));
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+
+ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED |
+ GTK_STATE_FLAG_FOCUSED, &c);
+
+ if (GLADE_IS_PLACEHOLDER (widget))
{
- if (glade_widget_get_from_gobject (widget))
- return TRUE;
+ cairo_pattern_t *gradient;
+ gdouble w, h;
- widget = gtk_widget_get_parent (widget);
+ w = gtk_widget_get_allocated_width (widget)/2.0;
+ h = gtk_widget_get_allocated_height (widget)/2.0;
+ gradient = cairo_pattern_create_radial (w, h, MIN (width, height)/6,
+ w, h, MAX (w, h));
+ cairo_pattern_add_color_stop_rgba (gradient, 0, c.red, c.green, c.blue, .08);
+ cairo_pattern_add_color_stop_rgba (gradient, 1, c.red, c.green, c.blue, .28);
+
+ cairo_set_source (cr, gradient);
+
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_pattern_destroy (gradient);
+ }
+ else
+ {
+ cairo_set_line_width (cr, 2);
+ gdk_cairo_set_source_rgba (cr, &c);
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ cairo_stroke (cr);
}
return FALSE;
}
+static void
+glade_design_view_drag_highlight (GladeDesignView *view, GtkWidget *widget)
+{
+ g_signal_connect_after (widget, "draw", G_CALLBACK (drag_highlight_draw), view);
+ gtk_widget_queue_draw (widget);
+}
+
+static void
+glade_design_view_drag_unhighlight (GladeDesignView *view, GtkWidget *widget)
+{
+ g_signal_handlers_disconnect_by_func (widget, drag_highlight_draw, view);
+ gtk_widget_queue_draw (widget);
+}
+
static gboolean
-on_drag_motion (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y,
- guint time)
+glade_design_view_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ guint time)
{
GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv;
+ GdkDragAction drag_action = GDK_ACTION_COPY;
GtkWidget *child;
- child = widget_get_child_from_position (widget, widget, x, y);
-
- if (!priv->drag_adaptor)
+ child = widget_get_gchild_from_position (widget, widget, x, y);
+
+ if (!(priv->drag_adaptor || priv->drag_source))
{
GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
- if (!target)
- return FALSE;
+ if (target)
+ gtk_drag_get_data (widget, context, target, time);
+ }
+
+ if (child)
+ {
+ GladeWidget *gwidget;
+
+ if (priv->drag_source &&
+ (priv->drag_source == child || gtk_widget_is_ancestor (child, priv->drag_source) ||
+ (!GLADE_IS_PLACEHOLDER (child) &&
+ !GTK_IS_FIXED (child) &&
+ (glade_widget_get_from_gobject (child) ||
+ ((gwidget = glade_widget_get_from_gobject (priv->drag_source)) &&
+ !glade_widget_get_parent (gwidget)
+ ))
+ )))
+ drag_action = 0;
+
+ if (priv->drag_adaptor &&
+ ((GLADE_IS_PLACEHOLDER (child) && GWA_IS_TOPLEVEL (priv->drag_adaptor)) ||
+ (!GLADE_IS_PLACEHOLDER (child) && !GTK_IS_FIXED (child) &&
+ glade_widget_get_from_gobject (child))))
+ drag_action = 0;
+ }
+ else
+ drag_action = 0;
+
+ gdk_drag_status (context, drag_action, time);
- gtk_drag_get_data (widget, context, target, time);
+ if (priv->drag_target != child)
+ {
+ if (priv->drag_target)
+ {
+ glade_design_view_drag_unhighlight (GLADE_DESIGN_VIEW (widget),
+ priv->drag_target);
+ priv->drag_target = NULL;
+ }
+
+ if (drag_action == GDK_ACTION_COPY)
+ {
+ glade_design_view_drag_highlight (GLADE_DESIGN_VIEW (widget), child);
+ priv->drag_target = child;
+ }
}
- if (child &&
- ((priv->drag_adaptor && GLADE_IS_PLACEHOLDER (child) &&
- GWA_IS_TOPLEVEL (priv->drag_adaptor)) ||
- (!GLADE_IS_PLACEHOLDER (child) &&
- widget_is_outside_glade_ancestor (child)) ))
+ return drag_action != 0;
+}
+
+static void
+glade_design_view_drag_leave (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ guint time)
+{
+ GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv;
+
+ if (priv->drag_target)
{
- gdk_drag_status (context, 0, time);
- return FALSE;
+ glade_design_view_drag_unhighlight (GLADE_DESIGN_VIEW (widget),
+ priv->drag_target);
+ priv->drag_target = NULL;
}
+}
- gdk_drag_status (context, GDK_ACTION_COPY, time);
- return TRUE;
+static void
+on_drag_item_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ GladeDesignView *view)
+{
+ GladeDesignViewPrivate *priv = view->priv;
+
+ priv->drag_adaptor = NULL;
+ priv->drag_source = NULL;
+ priv->drag_target = NULL;
+
+ g_signal_handlers_disconnect_by_func (widget, on_drag_item_drag_end, view);
}
static void
-on_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection,
- guint info,
- guint time)
+glade_design_view_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection,
+ guint info,
+ guint time)
{
GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv;
- GtkWidget *item;
+ GdkAtom target = gtk_selection_data_get_target (selection);
+ const GtkTargetEntry *palette_target;
- item = gtk_tool_palette_get_drag_item (priv->palette, selection);
- g_return_if_fail (item);
+ if (info == GDL_DND_INFO_WIDGET &&
+ g_strcmp0 (gdk_atom_name (target), GDL_DND_TARGET_WIDGET) == 0)
+ {
+ const guchar *data = gtk_selection_data_get_data (selection);
+
+ if (data)
+ priv->drag_source = *((GtkWidget **)data);
+ }
+ else if (priv->palette &&
+ (palette_target = gtk_tool_palette_get_drag_target_item ()) &&
+ palette_target->info == info &&
+ g_strcmp0 (gdk_atom_name (target), palette_target->target) == 0)
+ {
+ GtkWidget *item = gtk_tool_palette_get_drag_item (priv->palette, selection);
- priv->drag_adaptor = g_object_get_data (G_OBJECT (item), "glade-widget-adaptor");
+ if (item)
+ priv->drag_adaptor = g_object_get_data (G_OBJECT (item), "glade-widget-adaptor");
+ }
+ else
+ return;
+
+ g_signal_connect (gtk_drag_get_source_widget (context), "drag-end",
+ G_CALLBACK (on_drag_item_drag_end),
+ GLADE_DESIGN_VIEW (widget));
+}
+
+
+static void
+glade_design_view_fixed_move (GladeWidget *gsource,
+ GtkWidget *widget,
+ GdkDragContext *context,
+ GtkWidget *child,
+ gint x,
+ gint y)
+{
+ GladeProperty *prop_x, *prop_y;
+ gint dx, dy, hx, hy;
+ GtkWidget *layout;
+
+ gtk_widget_translate_coordinates (widget, child, x, y, &dx, &dy);
+
+ prop_x = glade_widget_get_pack_property (gsource, "x");
+ prop_y = glade_widget_get_pack_property (gsource, "y");
+
+ layout = gtk_drag_get_source_widget (context);
+
+ if (layout && GLADE_IS_DESIGN_LAYOUT (layout))
+ _glade_design_layout_get_hot_point (GLADE_DESIGN_LAYOUT (layout), &hx, &hy);
+ else
+ hx = hy = 0;
+
+ glade_command_set_property (prop_x, dx - hx);
+ glade_command_set_property (prop_y, dy - hy);
}
static gboolean
-on_drag_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time)
+glade_design_view_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
{
GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv;
GtkWidget *child;
- if (!priv->drag_adaptor)
- return FALSE;
+ child = widget_get_gchild_from_position (widget, widget, x, y);
- child = widget_get_child_from_position (widget, widget, x, y);
-
- if (child && GLADE_IS_PLACEHOLDER (child))
+ if (priv->drag_source)
{
- GladePlaceholder *placeholder = GLADE_PLACEHOLDER (child);
+ GladeWidget *gsource = glade_widget_get_from_gobject (priv->drag_source);
+ GList widgets = {gsource, NULL, NULL};
- glade_command_create (priv->drag_adaptor,
- glade_placeholder_get_parent (placeholder),
- placeholder,
- priv->project);
+ if (GLADE_IS_PLACEHOLDER (child))
+ {
+ GladePlaceholder *placeholder = GLADE_PLACEHOLDER (child);
+ GladeWidget *parent = glade_placeholder_get_parent (placeholder);
+
+ /* Check for recursive paste */
+ if (parent != gsource)
+ glade_command_dnd (&widgets, parent, placeholder);
+ }
+ else if (GTK_IS_FIXED (child))
+ {
+ GladeWidget *parent = glade_widget_get_from_gobject (child);
+
+ glade_command_push_group ("Drag and Drop");
+ if (parent != glade_widget_get_parent (gsource))
+ glade_command_dnd (&widgets, parent, NULL);
+
+ glade_design_view_fixed_move (gsource, widget, context, child, x, y);
+ glade_command_pop_group ();
+ }
+ else if (!glade_widget_get_from_gobject (child))
+ glade_command_dnd (&widgets, NULL, NULL);
}
- else
+ else if (child && priv->drag_adaptor)
{
- glade_command_create (priv->drag_adaptor, NULL, NULL, priv->project);
+ if (GLADE_IS_PLACEHOLDER (child))
+ {
+ GladePlaceholder *placeholder = GLADE_PLACEHOLDER (child);
+
+ glade_command_create (priv->drag_adaptor,
+ glade_placeholder_get_parent (placeholder),
+ placeholder,
+ priv->project);
+ }
+ else if (GTK_IS_FIXED (child))
+ {
+ GladeWidget *parent = glade_widget_get_from_gobject (child);
+
+ if (parent)
+ {
+ GladeWidget *gsource;
+ glade_command_push_group ("Drag and Drop");
+
+ gsource = glade_command_create (priv->drag_adaptor,
+ parent, NULL,
+ priv->project);
+
+ glade_design_view_fixed_move (gsource, widget, context, child, x, y);
+ glade_command_pop_group ();
+ }
+ }
+ else
+ {
+ glade_command_create (priv->drag_adaptor, NULL, NULL, priv->project);
+ }
}
gtk_drag_finish (context, TRUE, FALSE, time);
- priv->drag_adaptor = NULL;
+
return TRUE;
}
+static void
+glade_design_view_class_init (GladeDesignViewClass *klass)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class = G_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = glade_design_view_finalize;
+ object_class->get_property = glade_design_view_get_property;
+ object_class->set_property = glade_design_view_set_property;
+
+ widget_class->drag_motion = glade_design_view_drag_motion;
+ widget_class->drag_leave = glade_design_view_drag_leave;
+ widget_class->drag_data_received = glade_design_view_drag_data_received;
+ widget_class->drag_drop = glade_design_view_drag_drop;
+ widget_class->draw = glade_design_view_draw;
+
+ g_object_class_install_property (object_class,
+ PROP_PROJECT,
+ g_param_spec_object ("project",
+ "Project",
+ "The project for this view",
+ GLADE_TYPE_PROJECT,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
+ PROP_DRAG_SOURCE,
+ g_param_spec_object ("drag-source",
+ "Drag Source",
+ "A palette to use as the source of drag events for this view",
+ GTK_TYPE_TOOL_PALETTE,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (GladeDesignViewPrivate));
+}
+
+/* Private API */
+
+void
+_glade_design_view_freeze (GladeDesignView *view)
+{
+ g_return_if_fail (GLADE_IS_DESIGN_VIEW (view));
+
+ g_signal_handlers_block_by_func (view->priv->project,
+ glade_design_view_selection_changed,
+ view);
+}
+
+void
+_glade_design_view_thaw (GladeDesignView *view)
+{
+ g_return_if_fail (GLADE_IS_DESIGN_VIEW (view));
+
+ g_signal_handlers_unblock_by_func (view->priv->project,
+ glade_design_view_selection_changed,
+ view);
+}
+
+/* Public API */
+
+GladeProject *
+glade_design_view_get_project (GladeDesignView *view)
+{
+ g_return_val_if_fail (GLADE_IS_DESIGN_VIEW (view), NULL);
+
+ return view->priv->project;
+
+}
+
+GtkWidget *
+glade_design_view_new (GladeProject *project)
+{
+ GladeDesignView *view;
+
+ g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
+
+ view = g_object_new (GLADE_TYPE_DESIGN_VIEW, "project", project, NULL);
+
+ return GTK_WIDGET (view);
+}
+
+GladeDesignView *
+glade_design_view_get_from_project (GladeProject *project)
+{
+ gpointer p;
+
+ g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
+
+ p = g_object_get_data (G_OBJECT (project), GLADE_DESIGN_VIEW_KEY);
+
+ return (p != NULL) ? GLADE_DESIGN_VIEW (p) : NULL;
+
+}
+
void
glade_design_view_set_drag_source (GladeDesignView *view, GtkToolPalette *source)
{
@@ -605,20 +846,23 @@ glade_design_view_set_drag_source (GladeDesignView *view, GtkToolPalette *source
target = GTK_WIDGET (view);
priv->palette = source;
+ gtk_drag_dest_set (target, 0, NULL, 0, GDK_ACTION_COPY);
+
if (priv->palette)
{
- g_signal_connect (target, "drag-motion", G_CALLBACK (on_drag_motion), NULL);
- g_signal_connect (target, "drag-data-received", G_CALLBACK (on_drag_data_received), NULL);
- g_signal_connect (target, "drag-drop", G_CALLBACK (on_drag_drop), NULL);
+ GtkTargetEntry targets[2];
+ GtkTargetList *list;
gtk_tool_palette_add_drag_dest (priv->palette, target, 0,
GTK_TOOL_PALETTE_DRAG_ITEMS,
GDK_ACTION_COPY);
- }
- else
- {
- g_signal_handlers_disconnect_by_func (target, on_drag_motion, NULL);
- g_signal_handlers_disconnect_by_func (target, on_drag_data_received, NULL);
- g_signal_handlers_disconnect_by_func (target, on_drag_drop, NULL);
+
+ targets[0] = *gtk_tool_palette_get_drag_target_item ();
+ targets[1] = *_glade_design_layout_get_dnd_target ();
+
+ list = gtk_target_list_new (targets, 2);
+ gtk_drag_dest_set_target_list (target, list);
+
+ gtk_target_list_unref (list);
}
}
diff --git a/plugins/gtk+/glade-fixed.c b/plugins/gtk+/glade-fixed.c
index 98808519..0362ed04 100644
--- a/plugins/gtk+/glade-fixed.c
+++ b/plugins/gtk+/glade-fixed.c
@@ -280,21 +280,31 @@ glade_fixed_filter_event (GladeFixed *fixed,
static void
glade_fixed_handle_swindow (GladeFixed *fixed, GdkRectangle *area)
{
- GtkWidget *swindow = NULL, *swindow_child = NULL;
+ GtkWidget *swindow = NULL, *swindow_child = NULL, *widget;
GtkAdjustment *hadj, *vadj;
GtkAllocation child_allocation;
GtkWidget *fixed_widget;
+ GladeWidget *gwidget;
gint x, y;
- fixed_widget = GTK_WIDGET (glade_widget_get_object (GLADE_WIDGET (fixed)));
+ widget = fixed_widget = GTK_WIDGET (glade_widget_get_object (GLADE_WIDGET (fixed)));
- swindow_child = swindow = fixed_widget;
- while (swindow && !GTK_IS_SCROLLED_WINDOW (swindow))
+ while (widget && !GTK_IS_SCROLLED_WINDOW (widget) &&
+ (
+ ((gwidget = glade_widget_get_from_gobject (widget)) &&
+ glade_widget_get_parent (gwidget)) ||
+ !gwidget))
{
- if (!GTK_IS_VIEWPORT (swindow))
- swindow_child = swindow;
+ if (!GTK_IS_VIEWPORT (widget))
+ swindow_child = widget;
- swindow = gtk_widget_get_parent (swindow);
+ if (GTK_IS_SCROLLED_WINDOW (widget))
+ {
+ swindow = widget;
+ break;
+ }
+
+ widget = gtk_widget_get_parent (widget);
}
if (swindow)
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index f095994a..9e147aaa 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -3640,6 +3640,9 @@ void
glade_gtk_fixed_layout_post_create (GladeWidgetAdaptor * adaptor,
GObject * object, GladeCreateReason reason)
{
+ /* Set a minimun size so you can actually see it if you added to a box */
+ gtk_widget_set_size_request (GTK_WIDGET (object), 32, 32);
+
/* Sync up size request at project load time */
if (reason == GLADE_CREATE_LOAD)
g_signal_connect_after (object, "realize",