summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Pablo Ugarte <jp@synctv.com>2011-01-31 19:35:14 -0300
committerJuan Pablo Ugarte <jp@synctv.com>2011-01-31 19:35:14 -0300
commit25d476f11177faefcf48cc71da054cb41ea58426 (patch)
tree19aa0edfefb79d66933395183b70a8ba14368364
parente11251119a384c0e2f3700af9148664bd896bc16 (diff)
parent4d271ff317f13790274fea5edf015e92ebd5b7f5 (diff)
downloadglade-25d476f11177faefcf48cc71da054cb41ea58426.tar.gz
Merge branch 'multiple-toplevels'
-rw-r--r--gladeui/Makefile.am5
-rw-r--r--gladeui/glade-app.c3
-rw-r--r--gladeui/glade-design-layout.c476
-rw-r--r--gladeui/glade-design-layout.h12
-rw-r--r--gladeui/glade-design-private.h35
-rw-r--r--gladeui/glade-design-view.c202
-rw-r--r--gladeui/glade-design-view.h4
-rw-r--r--gladeui/glade-project.c47
-rw-r--r--gladeui/glade-project.h102
-rw-r--r--gladeui/glade-widget.c84
-rw-r--r--gladeui/glade.h1
-rw-r--r--plugins/gtk+/Makefile.am3
12 files changed, 659 insertions, 315 deletions
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am
index 6210af1b..e8c840ce 100644
--- a/gladeui/Makefile.am
+++ b/gladeui/Makefile.am
@@ -119,7 +119,6 @@ libgladeuiinclude_HEADERS = \
glade-editor-property.h \
glade-signal-editor.h \
glade-palette.h \
- glade-design-layout.h \
glade-design-view.h \
glade-widget.h \
glade-widget-adaptor.h \
@@ -144,7 +143,9 @@ libgladeuiinclude_HEADERS = \
glade-cell-renderer-icon.h \
glade-signal-model.h
-
+noinst_HEADERS = \
+ glade-design-layout.h \
+ glade-design-private.h
if PLATFORM_WIN32
libgladeui_2_la_LDFLAGS += -no-undefined
diff --git a/gladeui/glade-app.c b/gladeui/glade-app.c
index 1f21d4b2..ef75c6f3 100644
--- a/gladeui/glade-app.c
+++ b/gladeui/glade-app.c
@@ -36,6 +36,7 @@
#include "glade-cursor.h"
#include "glade-catalog.h"
#include "glade-design-view.h"
+#include "glade-design-layout.h"
#include "glade-marshallers.h"
#include "glade-accumulators.h"
@@ -391,7 +392,7 @@ glade_app_do_event (GdkEvent *event)
*/
if (widget && IS_GLADE_WIDGET_EVENT (event->type) &&
(layout = gtk_widget_get_ancestor (widget, GLADE_TYPE_DESIGN_LAYOUT)))
- return glade_design_layout_do_event (GLADE_DESIGN_LAYOUT (layout), event);
+ return _glade_design_layout_do_event (GLADE_DESIGN_LAYOUT (layout), event);
return FALSE;
}
diff --git a/gladeui/glade-design-layout.c b/gladeui/glade-design-layout.c
index 71535e74..93d54833 100644
--- a/gladeui/glade-design-layout.c
+++ b/gladeui/glade-design-layout.c
@@ -2,6 +2,7 @@
* glade-design-layout.c
*
* Copyright (C) 2006-2007 Vincent Geddes
+ * 2011 Juan Pablo Ugarte
*
* Authors:
* Vincent Geddes <vgeddes@gnome.org>
@@ -27,9 +28,11 @@
#include "glade.h"
#include "glade-design-layout.h"
+#include "glade-design-private.h"
#include "glade-accumulators.h"
#include "glade-marshallers.h"
+#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#define GLADE_DESIGN_LAYOUT_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
@@ -37,7 +40,7 @@
GladeDesignLayoutPrivate))
#define OUTLINE_WIDTH 4
-#define PADDING 12
+#define PADDING 10
typedef enum
{
@@ -51,11 +54,11 @@ struct _GladeDesignLayoutPrivate
{
GdkWindow *window, *offscreen_window;
- GList *selection;
-
gint child_offset;
GdkRectangle east, south, south_east;
GdkCursor *cursors[sizeof (Activity)];
+
+ PangoLayout *widget_name;
/* state machine */
Activity activity; /* the current activity */
@@ -65,6 +68,15 @@ struct _GladeDesignLayoutPrivate
gint dy; /* child.height - event.pointer.y */
gint new_width; /* user's new requested width */
gint new_height; /* user's new requested height */
+
+ /* Properties */
+ GladeDesignView *view;
+};
+
+enum
+{
+ PROP_0,
+ PROP_DESIGN_VIEW
};
G_DEFINE_TYPE (GladeDesignLayout, glade_design_layout, GTK_TYPE_BIN)
@@ -72,7 +84,7 @@ G_DEFINE_TYPE (GladeDesignLayout, glade_design_layout, GTK_TYPE_BIN)
#define RECTANGLE_POINT_IN(rect,x,y) (x >= rect.x && x <= (rect.x + rect.width) && y >= rect.y && y <= (rect.y + rect.height))
static Activity
-gdl_get_activity_from_pointer (GladeDesignLayout * layout, gint x, gint y)
+gdl_get_activity_from_pointer (GladeDesignLayout *layout, gint x, gint y)
{
GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
@@ -86,8 +98,7 @@ gdl_get_activity_from_pointer (GladeDesignLayout * layout, gint x, gint y)
}
static gboolean
-glade_design_layout_leave_notify_event (GtkWidget * widget,
- GdkEventCrossing * ev)
+glade_design_layout_leave_notify_event (GtkWidget *widget, GdkEventCrossing *ev)
{
GtkWidget *child;
GladeDesignLayoutPrivate *priv;
@@ -104,10 +115,10 @@ glade_design_layout_leave_notify_event (GtkWidget * widget,
return FALSE;
}
-
static void
-glade_design_layout_update_child (GladeDesignLayout * layout,
- GtkWidget * child, GtkAllocation * allocation)
+glade_design_layout_update_child (GladeDesignLayout *layout,
+ GtkWidget *child,
+ GtkAllocation *allocation)
{
GladeDesignLayoutPrivate *priv;
GladeWidget *gchild;
@@ -124,8 +135,7 @@ glade_design_layout_update_child (GladeDesignLayout * layout,
}
static gboolean
-glade_design_layout_motion_notify_event (GtkWidget * widget,
- GdkEventMotion * ev)
+glade_design_layout_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev)
{
GtkWidget *child;
GladeDesignLayoutPrivate *priv;
@@ -199,8 +209,8 @@ typedef struct
} GladeFindInContainerData;
static void
-glade_design_layout_find_inside_container (GtkWidget * widget,
- GladeFindInContainerData * data)
+glade_design_layout_find_inside_container (GtkWidget *widget,
+ GladeFindInContainerData *data)
{
GtkAllocation allocation;
gint x;
@@ -231,14 +241,28 @@ glade_design_layout_find_inside_container (GtkWidget * widget,
}
static gboolean
-glade_design_layout_button_press_event (GtkWidget * widget, GdkEventButton * ev)
+glade_project_is_toplevel_active (GladeProject *project, GtkWidget *toplevel)
+{
+ GList *l;
+
+ for (l = glade_project_selection_get (project); l; l = g_list_next (l))
+ {
+ if (gtk_widget_is_ancestor (l->data, toplevel)) return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+glade_design_layout_button_press_event (GtkWidget *widget, GdkEventButton *ev)
{
GtkWidget *child;
GtkAllocation child_allocation;
GladeDesignLayoutPrivate *priv;
gint x, y;
- if ((child = gtk_bin_get_child (GTK_BIN (widget))) == NULL)
+ if (ev->button != 1 ||
+ (child = gtk_bin_get_child (GTK_BIN (widget))) == NULL)
return FALSE;
priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (widget);
@@ -246,15 +270,60 @@ glade_design_layout_button_press_event (GtkWidget * widget, GdkEventButton * ev)
x = ev->x;
y = ev->y;
-
- if (ev->button == 1)
+ if (ev->type == GDK_BUTTON_PRESS)
{
+ GladeWidget *gchild;
+
gtk_widget_get_allocation (child, &child_allocation);
priv->dx = x - (child_allocation.x + child_allocation.width);
priv->dy = y - (child_allocation.y + child_allocation.height);
priv->activity = gdl_get_activity_from_pointer (GLADE_DESIGN_LAYOUT (widget), x, y);
gdk_window_set_cursor (priv->window, priv->cursors[priv->activity]);
+
+ if (priv->activity != ACTIVITY_NONE &&
+ (gchild = glade_widget_get_from_gobject (G_OBJECT (child))))
+ {
+ GladeProject *project = glade_widget_get_project (gchild);
+
+ if (project && !glade_project_is_toplevel_active (project, child))
+ {
+ _glade_design_view_freeze (priv->view);
+ glade_project_selection_set (project, G_OBJECT (gtk_bin_get_child (GTK_BIN (widget))), TRUE);
+ _glade_design_view_thaw (priv->view);
+ }
+ }
+ }
+ else if (ev->type == GDK_2BUTTON_PRESS)
+ {
+ GtkAdjustment *vadj, *hadj;
+ GtkAllocation alloc;
+ GtkWidget *win;
+ gint height;
+
+ if (priv->widget_name)
+ pango_layout_get_pixel_size (priv->widget_name, NULL, &height);
+ else
+ height = PADDING;
+
+ win = gtk_widget_get_ancestor (widget, GTK_TYPE_SCROLLED_WINDOW);
+ vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (win));
+ hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (win));
+
+ gtk_widget_get_allocation (widget, &alloc);
+ alloc.width = gtk_adjustment_get_page_size (hadj) - priv->child_offset * 2;
+ alloc.height = gtk_adjustment_get_page_size (vadj) - (PADDING + height + 3 * OUTLINE_WIDTH);
+
+ /* Maximize */
+ glade_design_layout_update_child (GLADE_DESIGN_LAYOUT (widget),
+ child, &alloc);
+
+ /* give a chance for widget to realocate */
+ while (gtk_events_pending ()) gtk_main_iteration_do (FALSE);
+
+ /* Position layout */
+ gtk_adjustment_set_value (hadj, 0);
+ gtk_adjustment_set_value (vadj, alloc.y);
}
return FALSE;
@@ -297,6 +366,8 @@ glade_design_layout_get_preferred_height (GtkWidget * widget,
if (child && gtk_widget_get_visible (child))
{
+ gint height;
+
gchild = glade_widget_get_from_gobject (child);
g_assert (gchild);
@@ -306,8 +377,13 @@ glade_design_layout_get_preferred_height (GtkWidget * widget,
child_height = MAX (child_height, *minimum);
- *minimum = MAX (*minimum, 2 * PADDING + child_height + 2 * OUTLINE_WIDTH);
- *natural = MAX (*natural, 2 * PADDING + child_height + 2 * OUTLINE_WIDTH);
+ if (priv->widget_name)
+ pango_layout_get_pixel_size (priv->widget_name, NULL, &height);
+ else
+ height = PADDING;
+
+ *minimum = MAX (*minimum, PADDING + 2.5 * OUTLINE_WIDTH + child_height + height);
+ *natural = MAX (*natural, PADDING + 2.5 * OUTLINE_WIDTH + child_height + height);
}
*minimum += border_width * 2;
@@ -342,8 +418,8 @@ glade_design_layout_get_preferred_width (GtkWidget * widget,
child_width = MAX (child_width, *minimum);
- *minimum = MAX (*minimum, 2 * PADDING + child_width + 2 * OUTLINE_WIDTH);
- *natural = MAX (*natural, 2 * PADDING + child_width + 2 * OUTLINE_WIDTH);
+ *minimum = MAX (*minimum, PADDING + child_width + 3 * OUTLINE_WIDTH);
+ *natural = MAX (*natural, PADDING + child_width + 3 * OUTLINE_WIDTH);
}
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
@@ -352,6 +428,24 @@ glade_design_layout_get_preferred_width (GtkWidget * widget,
}
static void
+glade_design_layout_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ glade_design_layout_get_preferred_width (widget, minimum_width, natural_width);
+}
+
+static void
+glade_design_layout_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ glade_design_layout_get_preferred_height (widget, minimum_height, natural_height);
+}
+
+static void
glade_design_layout_size_allocate (GtkWidget * widget,
GtkAllocation * allocation)
{
@@ -393,6 +487,14 @@ glade_design_layout_size_allocate (GtkWidget * widget,
child_allocation.width = MAX (requisition.width, child_width);
child_allocation.height = MAX (requisition.height, child_height);
+ if (priv->widget_name)
+ {
+ gint width;
+ pango_layout_get_pixel_size (priv->widget_name, &width, NULL);
+
+ child_allocation.width = MAX (width, child_allocation.width);
+ }
+
if (gtk_widget_get_realized (widget))
gdk_window_move_resize (priv->offscreen_window,
0, 0,
@@ -404,6 +506,41 @@ glade_design_layout_size_allocate (GtkWidget * widget,
}
static void
+update_south_east_rectangle (GladeDesignLayoutPrivate *priv, GtkAllocation *alloc)
+{
+ GdkRectangle *rect = &priv->south_east;
+ gint width, height;
+
+ pango_layout_get_pixel_size (priv->widget_name, &width, &height);
+
+ rect->x = alloc->x + priv->child_offset + alloc->width - width - OUTLINE_WIDTH/2;
+ rect->y = alloc->y + priv->child_offset + alloc->height + OUTLINE_WIDTH/2;
+ rect->width = width + (OUTLINE_WIDTH*2);
+ rect->height = height + OUTLINE_WIDTH;
+
+ /* Update south rectangle width */
+ priv->south.width = rect->x - priv->south.x;
+}
+
+static void
+on_glade_widget_name_notify (GObject *gobject, GParamSpec *pspec, GladeDesignLayout *layout)
+{
+ GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (layout));
+ GtkAllocation alloc;
+
+ if (child == NULL) return;
+
+ pango_layout_set_text (priv->widget_name, glade_widget_get_name (GLADE_WIDGET (gobject)), -1);
+
+ gtk_widget_get_allocation (child, &alloc);
+
+ update_south_east_rectangle (priv, &alloc);
+
+ gtk_widget_queue_resize (GTK_WIDGET (layout));
+}
+
+static void
on_child_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GladeDesignLayout *layout)
{
GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
@@ -417,9 +554,7 @@ on_child_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GladeDesig
priv->south.y = allocation->height + priv->child_offset;
priv->south.width = allocation->width;
- priv->south_east.x = allocation->width;
- priv->south_east.y = allocation->height;
- priv->south_east.width = priv->south_east.height = priv->child_offset * 2;
+ update_south_east_rectangle (priv, allocation);
}
static void
@@ -427,6 +562,7 @@ glade_design_layout_add (GtkContainer * container, GtkWidget * widget)
{
GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (container);
GladeDesignLayout *layout = GLADE_DESIGN_LAYOUT (container);
+ GladeWidget *gchild;
layout->priv->current_width = 0;
layout->priv->current_height = 0;
@@ -440,14 +576,27 @@ glade_design_layout_add (GtkContainer * container, GtkWidget * widget)
G_CALLBACK (on_child_size_allocate),
GLADE_DESIGN_LAYOUT (container));
- gtk_widget_queue_draw (GTK_WIDGET (container));
+ if ((gchild = glade_widget_get_from_gobject (G_OBJECT (widget))))
+ {
+ on_glade_widget_name_notify (G_OBJECT (gchild), NULL, layout);
+ g_signal_connect (gchild, "notify::name", G_CALLBACK (on_glade_widget_name_notify), layout);
+ }
+
+ gtk_widget_queue_draw (GTK_WIDGET (container));
}
static void
glade_design_layout_remove (GtkContainer * container, GtkWidget * widget)
{
+ GladeWidget *gchild;
+
g_signal_handlers_disconnect_by_func (widget, on_child_size_allocate,
GLADE_DESIGN_LAYOUT (container));
+
+ if ((gchild = glade_widget_get_from_gobject (G_OBJECT (widget))))
+ g_signal_handlers_disconnect_by_func (gchild, on_glade_widget_name_notify,
+ GLADE_DESIGN_LAYOUT (container));
+
GTK_CONTAINER_CLASS (glade_design_layout_parent_class)->remove (container, widget);
gtk_widget_queue_draw (GTK_WIDGET (container));
}
@@ -455,9 +604,6 @@ glade_design_layout_remove (GtkContainer * container, GtkWidget * widget)
static void
glade_design_layout_finalize (GObject * object)
{
- /* Free selection list */
- glade_design_layout_selection_set (GLADE_DESIGN_LAYOUT (object), NULL);
-
G_OBJECT_CLASS (glade_design_layout_parent_class)->finalize (object);
}
@@ -469,20 +615,46 @@ glade_design_layout_damage (GtkWidget *widget, GdkEventExpose *event)
}
static inline void
-draw_frame (GtkWidget * widget, cairo_t * cr, int x, int y, int w, int h)
+draw_frame (cairo_t * cr, GladeDesignLayoutPrivate *priv, GtkStyle *style, GtkStateType state, int x, int y, int w, int h)
{
cairo_save (cr);
+
cairo_set_line_width (cr, OUTLINE_WIDTH);
+
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
- gdk_cairo_set_source_color (cr,
- &gtk_widget_get_style (widget)->
- bg[GTK_STATE_SELECTED]);
+ gdk_cairo_set_source_color (cr, &style->bg[state]);
/* rectangle */
cairo_rectangle (cr, x, y, w, h);
cairo_stroke (cr);
+
+ if (priv->widget_name)
+ {
+ GdkRectangle *rect = &priv->south_east;
+ gint xx, yy;
+
+ xx = rect->x + rect->width;
+ yy = rect->y + rect->height;
+
+ /* Draw tab */
+ cairo_move_to (cr, rect->x, rect->y);
+ cairo_line_to (cr, xx, rect->y);
+ cairo_line_to (cr, xx, yy-8);
+ cairo_curve_to (cr, xx, yy, xx, yy, xx-8, yy);
+ cairo_line_to (cr, rect->x+8, yy);
+ cairo_curve_to (cr, rect->x, yy, rect->x, yy, rect->x, yy-8);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ /* Draw widget name */
+ gdk_cairo_set_source_color (cr, &style->text[state]);
+ cairo_move_to (cr, priv->south_east.x + OUTLINE_WIDTH,
+ priv->south_east.y + OUTLINE_WIDTH);
+ pango_cairo_show_layout (cr, priv->widget_name);
+ }
+
cairo_restore (cr);
}
@@ -496,6 +668,9 @@ draw_selection (cairo_t *cr, GtkWidget *parent, GtkWidget *widget,
gint x, y;
gtk_widget_get_allocation (widget, &alloc);
+
+ if (alloc.x < 0 || alloc.y < 0) return;
+
gtk_widget_translate_coordinates (widget, parent, offset, offset, &x, &y);
cx = x + alloc.width/2;
@@ -523,64 +698,69 @@ glade_design_layout_draw (GtkWidget * widget, cairo_t * cr)
if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
{
+ GladeProject *project;
+ GladeWidget *gchild;
GtkStyle *style;
GtkWidget *child;
- GdkWindow *window;
- gint border_width;
- gint width, height;
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
- window = gtk_widget_get_window (widget);
+
style = gtk_widget_get_style (widget);
- width = gtk_widget_get_allocated_width (widget);
- height = gtk_widget_get_allocated_height (widget);
-
- child = gtk_bin_get_child (GTK_BIN (widget));
/* draw a white widget background */
- glade_utils_cairo_draw_rectangle (cr,
- &style->
- base[gtk_widget_get_state (widget)],
- TRUE, border_width, border_width,
- width - 2 * border_width,
- height - 2 * border_width);
-
- if (child && gtk_widget_get_visible (child))
+ gdk_cairo_set_source_color (cr, &style->base[gtk_widget_get_state (widget)]);
+ cairo_paint (cr);
+
+ if ((child = gtk_bin_get_child (GTK_BIN (widget))) &&
+ gtk_widget_get_visible (child) &&
+ (gchild = glade_widget_get_from_gobject (G_OBJECT (child))) &&
+ (project = glade_widget_get_project (gchild)))
{
const GdkColor *color = &gtk_widget_get_style (widget)->bg[GTK_STATE_SELECTED];
+ gint border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
GtkAllocation child_allocation;
+ gboolean selected = FALSE;
gfloat r, g, b;
GList *l;
gtk_widget_get_allocation (child, &child_allocation);
- /* draw frame */
- draw_frame (widget, cr,
- border_width + PADDING,
- border_width + PADDING,
- child_allocation.width + 2 * OUTLINE_WIDTH,
- child_allocation.height + 2 * OUTLINE_WIDTH);
-
/* draw offscreen widgets */
- gdk_cairo_set_source_window (cr, priv->offscreen_window, priv->child_offset, priv->child_offset);
- cairo_rectangle (cr,
- priv->child_offset, priv->child_offset,
- child_allocation.width,
- child_allocation.height);
+ gdk_cairo_set_source_window (cr, priv->offscreen_window,
+ priv->child_offset, priv->child_offset);
+ cairo_rectangle (cr, priv->child_offset, priv->child_offset,
+ child_allocation.width, child_allocation.height);
cairo_fill (cr);
/* Draw selection */
r = color->red/65535.;
g = color->green/65535.;
b = color->blue/65535.;
+ cairo_set_line_width (cr, OUTLINE_WIDTH/2);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
- for (l = priv->selection; l; l = g_list_next (l))
+ for (l = glade_project_selection_get (project); l; l = g_list_next (l))
{
- if (child != l->data)
- draw_selection (cr, child, l->data, priv->child_offset, r, g, b);
+ GtkWidget *selection = l->data;
+
+ /* Dont draw selection on toplevels */
+ if (child != selection)
+ {
+ if (gtk_widget_is_ancestor (selection, child))
+ {
+ draw_selection (cr, child, selection, priv->child_offset, r, g, b);
+ selected = TRUE;
+ }
+ }
+ else
+ selected = TRUE;
}
+
+ /* draw frame */
+ draw_frame (cr, priv, style,
+ (selected) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL,
+ border_width + PADDING,
+ border_width + PADDING,
+ child_allocation.width + 2 * OUTLINE_WIDTH,
+ child_allocation.height + 2 * OUTLINE_WIDTH);
}
}
else if (gtk_cairo_should_draw_window (cr, priv->offscreen_window))
@@ -754,6 +934,8 @@ glade_design_layout_realize (GtkWidget * widget)
priv->cursors[ACTIVITY_RESIZE_HEIGHT] = gdk_cursor_new_for_display (display, GDK_BOTTOM_SIDE);
priv->cursors[ACTIVITY_RESIZE_WIDTH] = gdk_cursor_new_for_display (display, GDK_RIGHT_SIDE);
priv->cursors[ACTIVITY_RESIZE_WIDTH_AND_HEIGHT] = gdk_cursor_new_for_display (display, GDK_BOTTOM_RIGHT_CORNER);
+
+ priv->widget_name = pango_layout_new (gtk_widget_get_pango_context (widget));
}
static void
@@ -786,6 +968,12 @@ glade_design_layout_unrealize (GtkWidget * widget)
priv->cursors[ACTIVITY_RESIZE_WIDTH_AND_HEIGHT] = NULL;
}
+ if (priv->widget_name)
+ {
+ g_object_unref (priv->widget_name);
+ priv->widget_name = NULL;
+ }
+
GTK_WIDGET_CLASS (glade_design_layout_parent_class)->unrealize (widget);
}
@@ -806,16 +994,50 @@ glade_design_layout_init (GladeDesignLayout * layout)
priv->new_width = -1;
priv->new_height = -1;
- priv->selection = NULL;
-
/* setup static member of rectangles */
priv->east.width = PADDING + OUTLINE_WIDTH;
priv->south.height = PADDING + OUTLINE_WIDTH;
-
+
gtk_widget_set_has_window (GTK_WIDGET (layout), TRUE);
}
static void
+glade_design_layout_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_DESIGN_VIEW:
+ GLADE_DESIGN_LAYOUT_GET_PRIVATE (object)->view = GLADE_DESIGN_VIEW (g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+glade_design_layout_get_property (GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_DESIGN_VIEW:
+ g_value_set_object (value, GLADE_DESIGN_LAYOUT_GET_PRIVATE (object)->view);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
glade_design_layout_class_init (GladeDesignLayoutClass * klass)
{
GObjectClass *object_class;
@@ -827,7 +1049,9 @@ glade_design_layout_class_init (GladeDesignLayoutClass * klass)
container_class = GTK_CONTAINER_CLASS (klass);
object_class->finalize = glade_design_layout_finalize;
-
+ object_class->set_property = glade_design_layout_set_property;
+ object_class->get_property = glade_design_layout_get_property;
+
container_class->add = glade_design_layout_add;
container_class->remove = glade_design_layout_remove;
@@ -840,8 +1064,16 @@ glade_design_layout_class_init (GladeDesignLayoutClass * klass)
widget_class->draw = glade_design_layout_draw;
widget_class->get_preferred_height = glade_design_layout_get_preferred_height;
widget_class->get_preferred_width = glade_design_layout_get_preferred_width;
+ widget_class->get_preferred_width_for_height = glade_design_layout_get_preferred_width_for_height;
+ widget_class->get_preferred_height_for_width = glade_design_layout_get_preferred_height_for_width;
widget_class->size_allocate = glade_design_layout_size_allocate;
+ g_object_class_install_property (object_class, PROP_DESIGN_VIEW,
+ g_param_spec_object ("design-view", _("Design View"),
+ _("The GladeDesignView that contains this layout"),
+ GLADE_TYPE_DESIGN_VIEW,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET),
GLADE_TYPE_DESIGN_LAYOUT,
g_cclosure_new (G_CALLBACK (glade_design_layout_damage),
@@ -850,93 +1082,16 @@ glade_design_layout_class_init (GladeDesignLayoutClass * klass)
g_type_class_add_private (object_class, sizeof (GladeDesignLayoutPrivate));
}
-/* Public API */
+/* Internal API */
GtkWidget *
-glade_design_layout_new (void)
+_glade_design_layout_new (GladeDesignView *view)
{
- return g_object_new (GLADE_TYPE_DESIGN_LAYOUT, NULL);
+ return g_object_new (GLADE_TYPE_DESIGN_LAYOUT, "design-view", view, NULL);
}
-static void
-on_selected_child_parent_set (GtkWidget *widget,
- GtkWidget *old_parent,
- GladeDesignLayout * layout)
-{
- GladeDesignLayoutPrivate *priv;
- GladeWidget *layout_gchild, *gtoplevel, *gwidget;
- GtkWidget *child;
-
- if ((child = gtk_bin_get_child (GTK_BIN (layout))) == NULL) return;
-
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
-
- layout_gchild = glade_widget_get_from_gobject (G_OBJECT (child));
-
- if ((gwidget = glade_widget_get_from_gobject (G_OBJECT (widget))) &&
- (gtoplevel = glade_widget_get_toplevel (gwidget)) &&
- gtoplevel != layout_gchild)
- {
- glade_design_layout_selection_set (layout, NULL);
- }
-}
-
-/**
- * glade_design_layout_selection_set:
- * @layout: A #GladeDesignLayout
- * @selection: A list of selected widgets.
- *
- * Set the widget selection list or NULL.
- *
- */
-void
-glade_design_layout_selection_set (GladeDesignLayout * layout, GList *selection)
-{
- GladeDesignLayoutPrivate *priv;
- GladeWidget *layout_gchild;
- GtkWidget *child;
- GList *l;
-
- g_return_if_fail (GLADE_IS_DESIGN_LAYOUT (layout));
-
- if ((child = gtk_bin_get_child (GTK_BIN (layout))) == NULL) return;
-
- priv = GLADE_DESIGN_LAYOUT_GET_PRIVATE (layout);
-
- /* Disconnect handlers */
- for (l = priv->selection; l; l = g_list_next (l))
- g_signal_handlers_block_by_func (l->data, on_selected_child_parent_set, layout);
-
- /* Free list */
- g_list_free (priv->selection);
- priv->selection = NULL;
-
- layout_gchild = glade_widget_get_from_gobject (G_OBJECT (child));
-
- for (l = selection; l; l = g_list_next (l))
- {
- GladeWidget *gtoplevel, *gwidget;
-
- if ((gwidget = glade_widget_get_from_gobject (G_OBJECT (l->data))) &&
- (gtoplevel = glade_widget_get_toplevel (gwidget)) &&
- gtoplevel == layout_gchild)
- {
- /* its a descendant, prepend to list */
- priv->selection = g_list_prepend (priv->selection, l->data);
-
- /* we unset the whole selection list if one of the widgets is
- * removed or reparented since Glade Project will take care
- * of update it properly
- */
- g_signal_connect (l->data, "parent-set", G_CALLBACK (on_selected_child_parent_set), layout);
- }
- }
-
- gtk_widget_queue_draw (GTK_WIDGET (layout));
-}
-
-/**
- * glade_design_layout_do_event:
+/*
+ * _glade_design_layout_do_event:
* @layout: A #GladeDesignLayout
* @event: an event to process
*
@@ -946,11 +1101,12 @@ glade_design_layout_selection_set (GladeDesignLayout * layout, GList *selection)
* Returns: true if the event was handled.
*/
gboolean
-glade_design_layout_do_event (GladeDesignLayout * layout, GdkEvent * event)
+_glade_design_layout_do_event (GladeDesignLayout * layout, GdkEvent * event)
{
GladeFindInContainerData data = { 0, };
GladeDesignLayoutPrivate *priv;
GtkWidget *child;
+ gboolean retval;
if ((child = gtk_bin_get_child (GTK_BIN (layout))) == NULL)
return FALSE;
@@ -962,11 +1118,17 @@ glade_design_layout_do_event (GladeDesignLayout * layout, GdkEvent * event)
glade_design_layout_find_inside_container (child, &data);
+ _glade_design_view_freeze (priv->view);
+
/* Try the placeholder first */
- if (data.placeholder && gtk_widget_event (data.placeholder, event)) return TRUE;
+ if (data.placeholder && gtk_widget_event (data.placeholder, event))
+ retval = TRUE;
+ else if (data.gwidget) /* Then we try a GladeWidget */
+ retval = glade_widget_event (data.gwidget, event);
+ else
+ retval = FALSE;
- /* Then we try a GladeWidget */
- if (data.gwidget) return glade_widget_event (data.gwidget, event);
+ _glade_design_view_thaw (priv->view);
- return FALSE;
+ return retval;
}
diff --git a/gladeui/glade-design-layout.h b/gladeui/glade-design-layout.h
index 7e67bad5..f88f71ad 100644
--- a/gladeui/glade-design-layout.h
+++ b/gladeui/glade-design-layout.h
@@ -26,6 +26,7 @@
#define __GLADE_DESIGN_LAYOUT_H__
#include <gtk/gtk.h>
+#include "glade-design-view.h"
G_BEGIN_DECLS
@@ -59,15 +60,12 @@ struct _GladeDesignLayoutClass
};
-GType glade_design_layout_get_type (void) G_GNUC_CONST;
+GType glade_design_layout_get_type (void) G_GNUC_CONST;
-GtkWidget *glade_design_layout_new (void);
+GtkWidget *_glade_design_layout_new (GladeDesignView *view);
-void glade_design_layout_selection_set (GladeDesignLayout * layout,
- GList * selection);
-
-gboolean glade_design_layout_do_event (GladeDesignLayout * layout,
- GdkEvent * event);
+gboolean _glade_design_layout_do_event (GladeDesignLayout *layout,
+ GdkEvent *event);
G_END_DECLS
diff --git a/gladeui/glade-design-private.h b/gladeui/glade-design-private.h
new file mode 100644
index 00000000..adcd1e45
--- /dev/null
+++ b/gladeui/glade-design-private.h
@@ -0,0 +1,35 @@
+/*
+ * glade-design-private.h
+ *
+ * Copyright (C) 2011 Juan Pablo Ugarte
+ *
+ * Authors:
+ * Juan Pablo Ugarte <juanpablougarte@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANDESIGN_VIEWILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __GLADE_DESIGN_PRIVATE_H__
+#define __GLADE_DESIGN_PRIVATE_H__
+
+G_BEGIN_DECLS
+
+void _glade_design_view_freeze (GladeDesignView *view);
+void _glade_design_view_thaw (GladeDesignView *view);
+
+G_END_DECLS
+
+#endif /* __GLADE_DESIGN_PRIVATE_H__ */
diff --git a/gladeui/glade-design-view.c b/gladeui/glade-design-view.c
index 0f9d0df1..dd5f0c67 100644
--- a/gladeui/glade-design-view.c
+++ b/gladeui/glade-design-view.c
@@ -2,9 +2,11 @@
* glade-design-view.c
*
* Copyright (C) 2006 Vincent Geddes
+ * 2011 Juan Pablo Ugarte
*
* Authors:
* Vincent Geddes <vincent.geddes@gmail.com>
+ * Juan Pablo Ugarte <juanpablougarte@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +29,7 @@
* @Title: GladeDesignView
* @Short_Description: A widget to embed the workspace.
*
- * Use this widget to embed the currently active #GtkWindow
- * in a given #GladeProject.
+ * Use this widget to embed toplevel widgets in a given #GladeProject.
*/
#include "config.h"
@@ -37,6 +38,7 @@
#include "glade-utils.h"
#include "glade-design-view.h"
#include "glade-design-layout.h"
+#include "glade-design-private.h"
#include <glib.h>
#include <glib/gi18n.h>
@@ -53,7 +55,7 @@ enum
struct _GladeDesignViewPrivate
{
- GtkWidget *layout;
+ GtkWidget *layout_box;
GladeProject *project;
@@ -91,12 +93,10 @@ glade_design_view_load_progress (GladeProject * project,
gchar *path;
gchar *str;
- path =
- glade_utils_replace_home_dir_with_tilde (glade_project_get_path
- (project));
- str =
- g_strdup_printf (_("Loading %s: loaded %d of %d objects"), path, step,
- total);
+ path = glade_utils_replace_home_dir_with_tilde (glade_project_get_path (project));
+ str = g_strdup_printf (_("Loading %s: loaded %d of %d objects"),
+ path, step, total);
+
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (view->priv->progress), str);
g_free (str);
g_free (path);
@@ -106,10 +106,128 @@ glade_design_view_load_progress (GladeProject * project,
}
static void
-glade_design_view_selection_changed (GladeProject * project, GladeDesignView * view)
+glade_design_layout_scroll (GladeDesignView *view, gint x, gint y, gint w, gint h)
+{
+ gdouble vadj_val, hadj_val, vpage_end, hpage_end;
+ GtkAdjustment *vadj, *hadj;
+
+ vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (view->priv->scrolled_window));
+ hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (view->priv->scrolled_window));
+
+ vadj_val = gtk_adjustment_get_value (vadj);
+ hadj_val = gtk_adjustment_get_value (hadj);
+ vpage_end = gtk_adjustment_get_page_size (vadj) + vadj_val;
+ hpage_end = gtk_adjustment_get_page_size (hadj) + hadj_val;
+
+ /* TODO: we could set this value in increments in a timeout callback
+ * to make it look like its scrolling instead of jumping.
+ */
+ if (y < vadj_val || y > vpage_end || (y + h) > vpage_end)
+ gtk_adjustment_set_value (vadj, y);
+
+ if (x < hadj_val || x > hpage_end || (x + w) > hpage_end)
+ gtk_adjustment_set_value (hadj, x);
+}
+
+static void
+on_layout_size_allocate (GtkWidget *widget, GtkAllocation *alloc, GladeDesignView *view)
+{
+ glade_design_layout_scroll (view, alloc->x, alloc->y, alloc->width, alloc->height);
+ g_signal_handlers_disconnect_by_func (widget, on_layout_size_allocate, view);
+}
+
+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))
+ {
+ 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);
+ }
+}
+
+static void
+glade_design_view_add_toplevel (GladeDesignView *view, GladeWidget *widget)
{
- GladeDesignLayout *layout = glade_design_view_get_layout (view);
- glade_design_layout_selection_set (layout, glade_project_selection_get (project));
+ GtkWidget *layout;
+ GObject *object;
+
+ if (glade_widget_get_parent (widget) ||
+ (object = glade_widget_get_object (widget)) == NULL ||
+ !GTK_IS_WIDGET (object) ||
+ gtk_widget_get_parent (GTK_WIDGET (object)))
+ return;
+
+ /* Create a GladeDesignLayout and add the toplevel widget to the view */
+ layout = _glade_design_layout_new (view);
+ gtk_box_pack_start (GTK_BOX (view->priv->layout_box), layout, FALSE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (layout), GTK_WIDGET (object));
+ gtk_widget_show (GTK_WIDGET (object));
+ gtk_widget_show (layout);
+}
+
+static void
+glade_design_view_remove_toplevel (GladeDesignView *view, GladeWidget *widget)
+{
+ GtkWidget *layout;
+ GObject *object;
+
+ if (glade_widget_get_parent (widget) ||
+ (object = glade_widget_get_object (widget)) == NULL ||
+ !GTK_IS_WIDGET (object)) return;
+
+ /* Remove toplevel widget from the view */
+ if ((layout = gtk_widget_get_parent (GTK_WIDGET (object))) &&
+ gtk_widget_is_ancestor (layout, GTK_WIDGET (view)))
+ {
+ gtk_container_remove (GTK_CONTAINER (layout), GTK_WIDGET (object));
+ gtk_container_remove (GTK_CONTAINER (view->priv->layout_box), layout);
+ }
+}
+
+static void
+glade_design_view_widget_visibility_changed (GladeProject *project,
+ GladeWidget *widget,
+ gboolean visible,
+ GladeDesignView *view)
+{
+ if (visible)
+ glade_design_view_add_toplevel (view, widget);
+ else
+ glade_design_view_remove_toplevel (view, widget);
+}
+
+static void
+on_project_add_widget (GladeProject *project, GladeWidget *widget, GladeDesignView *view)
+{
+ glade_design_view_add_toplevel (view, widget);
+}
+
+static void
+on_project_remove_widget (GladeProject *project, GladeWidget *widget, GladeDesignView *view)
+{
+ glade_design_view_remove_toplevel (view, widget);
}
static void
@@ -119,6 +237,10 @@ glade_design_view_set_project (GladeDesignView * view, GladeProject * project)
view->priv->project = project;
+ g_signal_connect (project, "add-widget",
+ G_CALLBACK (on_project_add_widget), view);
+ g_signal_connect (project, "remove-widget",
+ G_CALLBACK (on_project_remove_widget), view);
g_signal_connect (project, "parse-began",
G_CALLBACK (glade_design_view_parse_began), view);
g_signal_connect (project, "parse-finished",
@@ -127,9 +249,10 @@ glade_design_view_set_project (GladeDesignView * view, GladeProject * project)
G_CALLBACK (glade_design_view_load_progress), view);
g_signal_connect (project, "selection-changed",
G_CALLBACK (glade_design_view_selection_changed), view);
+ g_signal_connect (project, "widget-visibility-changed",
+ G_CALLBACK (glade_design_view_widget_visibility_changed), view);
- g_object_set_data (G_OBJECT (view->priv->project), GLADE_DESIGN_VIEW_KEY,
- view);
+ g_object_set_data (G_OBJECT (project), GLADE_DESIGN_VIEW_KEY, view);
}
static void
@@ -165,6 +288,17 @@ glade_design_view_get_property (GObject * object,
}
}
+static gboolean
+on_viewport_draw (GtkWidget * widget, cairo_t * cr)
+{
+ GtkStyle *style = gtk_widget_get_style (widget);
+
+ gdk_cairo_set_source_color (cr, &style->base[gtk_widget_get_state (widget)]);
+ cairo_paint (cr);
+
+ return TRUE;
+}
+
static void
glade_design_view_init (GladeDesignView * view)
{
@@ -175,7 +309,9 @@ glade_design_view_init (GladeDesignView * view)
gtk_widget_set_no_show_all (GTK_WIDGET (view), TRUE);
view->priv->project = NULL;
- view->priv->layout = glade_design_layout_new ();
+ view->priv->layout_box = gtk_vbox_new (FALSE, 0);
+ 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
@@ -186,13 +322,15 @@ glade_design_view_init (GladeDesignView * view)
GTK_SHADOW_IN);
viewport = gtk_viewport_new (NULL, NULL);
+ gtk_widget_set_app_paintable (viewport, TRUE);
+ g_signal_connect (viewport, "draw", G_CALLBACK (on_viewport_draw), NULL);
gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
- gtk_container_add (GTK_CONTAINER (viewport), view->priv->layout);
+ gtk_container_add (GTK_CONTAINER (viewport), view->priv->layout_box);
gtk_container_add (GTK_CONTAINER (view->priv->scrolled_window), viewport);
gtk_widget_show (view->priv->scrolled_window);
gtk_widget_show (viewport);
- gtk_widget_show (view->priv->layout);
+ gtk_widget_show_all (view->priv->layout_box);
gtk_box_pack_start (GTK_BOX (view), view->priv->scrolled_window, TRUE, TRUE,
0);
@@ -252,6 +390,30 @@ glade_design_view_class_init (GladeDesignViewClass * klass)
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)
{
@@ -285,9 +447,3 @@ glade_design_view_get_from_project (GladeProject * project)
return (p != NULL) ? GLADE_DESIGN_VIEW (p) : NULL;
}
-
-GladeDesignLayout *
-glade_design_view_get_layout (GladeDesignView * view)
-{
- return GLADE_DESIGN_LAYOUT (view->priv->layout);
-}
diff --git a/gladeui/glade-design-view.h b/gladeui/glade-design-view.h
index 105c3843..3a653be1 100644
--- a/gladeui/glade-design-view.h
+++ b/gladeui/glade-design-view.h
@@ -27,7 +27,6 @@
#include <gladeui/glade.h>
#include <gladeui/glade-project.h>
-#include <gladeui/glade-design-layout.h>
#include <gtk/gtk.h>
@@ -70,9 +69,6 @@ GladeProject *glade_design_view_get_project (GladeDesignView *view);
GladeDesignView *glade_design_view_get_from_project (GladeProject *project);
-GladeDesignLayout *glade_design_view_get_layout (GladeDesignView *view);
-
-
G_END_DECLS
#endif /* __GLADE_DESIGN_VIEW_H__ */
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 5a36957a..d65d0954 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -64,6 +64,7 @@ enum
PARSE_FINISHED,
TARGETS_CHANGED,
LOAD_PROGRESS,
+ WIDGET_VISIBILITY_CHANGED,
LAST_SIGNAL
};
@@ -960,6 +961,22 @@ glade_project_class_init (GladeProjectClass * klass)
glade_marshal_VOID__INT_INT,
G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+ /**
+ * GladeProject::widget-visibility-changed:
+ * @gladeproject: the #GladeProject which received the signal.
+ * @widget: the widget that its visibity changed
+ * @visible: the current visiblity of the widget
+ *
+ * Emitted when the visivility of a widget changed
+ */
+ glade_project_signals[WIDGET_VISIBILITY_CHANGED] =
+ g_signal_new ("widget-visibility-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ glade_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2, GLADE_TYPE_WIDGET, G_TYPE_BOOLEAN);
+
g_object_class_install_property (object_class,
PROP_MODIFIED,
g_param_spec_boolean ("modified",
@@ -2972,15 +2989,6 @@ glade_project_selection_changed (GladeProject * project)
g_signal_emit (G_OBJECT (project),
glade_project_signals[SELECTION_CHANGED], 0);
- if (g_list_length (project->priv->selection) == 1 &&
- !GLADE_IS_PLACEHOLDER (project->priv->selection->data))
- {
- GladeWidget *gwidget =
- glade_widget_get_from_gobject (G_OBJECT (project->priv->selection->data));
-
- glade_widget_show (gwidget);
- }
-
/* Cancel any idle we have */
if (project->priv->selection_changed_id > 0)
project->priv->selection_changed_id =
@@ -3508,6 +3516,27 @@ glade_project_resource_fullpath (GladeProject * project, const gchar * resource)
return fullpath;
}
+/**
+ * glade_project_widget_visibility_changed:
+ * @project: The #GladeProject.
+ * @widget: The widget which visibility changed
+ * @visible: widget visibility value
+ *
+ * Emmits GladeProject::widget-visibility-changed signal
+ *
+ */
+void
+glade_project_widget_visibility_changed (GladeProject *project,
+ GladeWidget *widget,
+ gboolean visible)
+{
+ g_return_if_fail (GLADE_IS_PROJECT (project));
+ g_return_if_fail (project == glade_widget_get_project (widget));
+
+ g_signal_emit (project, glade_project_signals[WIDGET_VISIBILITY_CHANGED], 0,
+ widget, visible);
+}
+
const gchar *
glade_project_get_path (GladeProject * project)
{
diff --git a/gladeui/glade-project.h b/gladeui/glade-project.h
index 22896ba2..5305147f 100644
--- a/gladeui/glade-project.h
+++ b/gladeui/glade-project.h
@@ -78,28 +78,28 @@ struct _GladeProjectClass
GObjectClass parent_class;
void (*add_object) (GladeProject *project,
- GladeWidget *widget);
+ GladeWidget *widget);
void (*remove_object) (GladeProject *project,
- GladeWidget *widget);
+ GladeWidget *widget);
void (*undo) (GladeProject *project);
void (*redo) (GladeProject *project);
GladeCommand *(*next_undo_item) (GladeProject *project);
GladeCommand *(*next_redo_item) (GladeProject *project);
void (*push_undo) (GladeProject *project,
- GladeCommand *command);
+ GladeCommand *command);
void (*changed) (GladeProject *project,
- GladeCommand *command,
- gboolean forward);
+ GladeCommand *command,
+ gboolean forward);
void (*widget_name_changed) (GladeProject *project,
- GladeWidget *widget);
+ GladeWidget *widget);
void (*selection_changed) (GladeProject *project);
void (*close) (GladeProject *project);
void (*parse_finished) (GladeProject *project);
-
+
void (* glade_reserved1) (void);
void (* glade_reserved2) (void);
void (* glade_reserved3) (void);
@@ -117,68 +117,72 @@ GType glade_project_get_type (void) G_GNUC_CONST;
GladeProject *glade_project_new (void);
GladeProject *glade_project_load (const gchar *path);
gboolean glade_project_load_from_file (GladeProject *project,
- const gchar *path);
+ const gchar *path);
gboolean glade_project_save (GladeProject *project,
- const gchar *path,
- GError **error);
+ const gchar *path,
+ GError **error);
void glade_project_push_progress (GladeProject *project);
gboolean glade_project_load_cancelled (GladeProject *project);
void glade_project_cancel_load (GladeProject *project);
void glade_project_preview (GladeProject *project,
- GladeWidget *gwidget);
+ GladeWidget *gwidget);
void glade_project_properties (GladeProject *project);
gchar *glade_project_resource_fullpath (GladeProject *project,
- const gchar *resource);
+ const gchar *resource);
+
+void glade_project_widget_visibility_changed (GladeProject *project,
+ GladeWidget *widget,
+ gboolean visible);
/* Commands */
void glade_project_undo (GladeProject *project);
void glade_project_redo (GladeProject *project);
GladeCommand *glade_project_next_undo_item (GladeProject *project);
GladeCommand *glade_project_next_redo_item (GladeProject *project);
-void glade_project_push_undo (GladeProject *project,
- GladeCommand *cmd);
+void glade_project_push_undo (GladeProject *project,
+ GladeCommand *cmd);
GtkWidget *glade_project_undo_items (GladeProject *project);
GtkWidget *glade_project_redo_items (GladeProject *project);
/* Add/Remove Objects */
const GList *glade_project_get_objects (GladeProject *project);
-void glade_project_add_object (GladeProject *project,
- GObject *object);
-void glade_project_remove_object (GladeProject *project,
- GObject *object);
-gboolean glade_project_has_object (GladeProject *project,
- GObject *object);
+void glade_project_add_object (GladeProject *project,
+ GObject *object);
+void glade_project_remove_object (GladeProject *project,
+ GObject *object);
+gboolean glade_project_has_object (GladeProject *project,
+ GObject *object);
void glade_project_widget_changed (GladeProject *project,
- GladeWidget *gwidget);
+ GladeWidget *gwidget);
/* Widget names */
-GladeWidget *glade_project_get_widget_by_name (GladeProject *project,
- const gchar *name);
-void glade_project_set_widget_name (GladeProject *project,
- GladeWidget *widget,
- const gchar *name);
-gchar *glade_project_new_widget_name (GladeProject *project,
- GladeWidget *widget,
- const gchar *base_name);
-gboolean glade_project_available_widget_name(GladeProject *project,
- GladeWidget *widget,
+GladeWidget *glade_project_get_widget_by_name (GladeProject *project,
+ const gchar *name);
+void glade_project_set_widget_name (GladeProject *project,
+ GladeWidget *widget,
const gchar *name);
+gchar *glade_project_new_widget_name (GladeProject *project,
+ GladeWidget *widget,
+ const gchar *base_name);
+gboolean glade_project_available_widget_name(GladeProject *project,
+ GladeWidget *widget,
+ const gchar *name);
/* Selection */
gboolean glade_project_is_selected (GladeProject *project,
- GObject *object);
+ GObject *object);
void glade_project_selection_set (GladeProject *project,
- GObject *object,
- gboolean emit_signal);
+ GObject *object,
+ gboolean emit_signal);
void glade_project_selection_add (GladeProject *project,
- GObject *object,
- gboolean emit_signal);
+ GObject *object,
+ gboolean emit_signal);
void glade_project_selection_remove (GladeProject *project,
- GObject *object,
- gboolean emit_signal);
+ GObject *object,
+ gboolean emit_signal);
void glade_project_selection_clear (GladeProject *project,
- gboolean emit_signal);
+ gboolean emit_signal);
void glade_project_selection_changed (GladeProject *project);
void glade_project_queue_selection_changed (GladeProject *project);
GList *glade_project_selection_get (GladeProject *project);
@@ -193,31 +197,31 @@ time_t glade_project_get_file_mtime (GladeProject *proj
gboolean glade_project_get_readonly (GladeProject *project);
gboolean glade_project_get_modified (GladeProject *project);
void glade_project_set_pointer_mode (GladeProject *project,
- GladePointerMode mode);
+ GladePointerMode mode);
GladePointerMode glade_project_get_pointer_mode (GladeProject *project);
void glade_project_set_add_item (GladeProject *project,
- GladeWidgetAdaptor *adaptor);
+ GladeWidgetAdaptor *adaptor);
GladeWidgetAdaptor *glade_project_get_add_item (GladeProject *project);
void glade_project_get_target_version (GladeProject *project,
- const gchar *catalog,
- gint *major,
- gint *minor);
+ const gchar *catalog,
+ gint *major,
+ gint *minor);
GList *glade_project_required_libs (GladeProject *project);
gchar *glade_project_display_dependencies (GladeProject *project);
/* Verifications */
gchar *glade_project_verify_widget_adaptor(GladeProject *project,
- GladeWidgetAdaptor *adaptor,
- GladeSupportMask *mask);
+ GladeWidgetAdaptor *adaptor,
+ GladeSupportMask *mask);
void glade_project_verify_property (GladeProperty *property);
void glade_project_verify_signal (GladeWidget *widget,
- GladeSignal *signal);
+ GladeSignal *signal);
/* General selection driven commands */
void glade_project_copy_selection (GladeProject *project);
void glade_project_command_cut (GladeProject *project);
-void glade_project_command_paste (GladeProject *project,
- GladePlaceholder *placeholder);
+void glade_project_command_paste (GladeProject *project,
+ GladePlaceholder *placeholder);
void glade_project_command_delete (GladeProject *project);
G_END_DECLS
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index e8d983e5..d84418ff 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -190,7 +190,8 @@ enum
PROP_REASON,
PROP_TOPLEVEL_WIDTH,
PROP_TOPLEVEL_HEIGHT,
- PROP_SUPPORT_WARNING
+ PROP_SUPPORT_WARNING,
+ PROP_VISIBLE
};
static guint glade_widget_signals[LAST_SIGNAL] = { 0 };
@@ -1136,6 +1137,9 @@ glade_widget_get_real_property (GObject * object,
case PROP_SUPPORT_WARNING:
g_value_set_string (value, widget->priv->support_warning);
break;
+ case PROP_VISIBLE:
+ g_value_set_boolean (value, widget->priv->visible);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1302,6 +1306,12 @@ glade_widget_class_init (GladeWidgetClass * klass)
_("A warning string about version mismatches"),
NULL, G_PARAM_READABLE));
+ g_object_class_install_property
+ (object_class, PROP_VISIBLE,
+ g_param_spec_boolean ("visible", _("Visible"),
+ _("Wether the widget is visible or not"),
+ FALSE, G_PARAM_READABLE));
+
/**
* GladeWidget::add-signal-handler:
* @gladewidget: the #GladeWidget which received the signal.
@@ -1941,20 +1951,6 @@ glade_widget_get_from_gobject (gpointer object)
return g_object_get_qdata (G_OBJECT (object), glade_widget_name_quark);
}
-static void
-glade_widget_add_to_layout (GladeWidget * widget, GtkWidget * layout)
-{
- if (gtk_bin_get_child (GTK_BIN (layout)) != GTK_WIDGET (widget->priv->object))
- {
- if (gtk_bin_get_child (GTK_BIN (layout)) != NULL)
- gtk_container_remove (GTK_CONTAINER (layout),
- gtk_bin_get_child (GTK_BIN (layout)));
-
- gtk_container_add (GTK_CONTAINER (layout), GTK_WIDGET (widget->priv->object));
- gtk_widget_show_all (GTK_WIDGET (widget->priv->object));
- }
-}
-
/**
* glade_widget_show:
* @widget: A #GladeWidget
@@ -1962,10 +1958,8 @@ glade_widget_add_to_layout (GladeWidget * widget, GtkWidget * layout)
* Display @widget in it's project's GladeDesignView
*/
void
-glade_widget_show (GladeWidget * widget)
+glade_widget_show (GladeWidget *widget)
{
- GladeDesignView *view = NULL;
- GtkWidget *layout;
GladeProperty *property;
GladeProject *project;
@@ -1982,27 +1976,6 @@ glade_widget_show (GladeWidget * widget)
glade_widget_show (glade_property_get_widget (property));
return;
}
-
- project = glade_widget_get_project (widget);
- if (project)
- view = glade_design_view_get_from_project (project);
-
- if (!view)
- return;
-
- layout = GTK_WIDGET (glade_design_view_get_layout (view));
-
- if (!layout)
- return;
-
- if (gtk_widget_get_realized (layout))
- glade_widget_add_to_layout (widget, layout);
- else
- g_signal_connect_data (G_OBJECT (layout), "map",
- G_CALLBACK (glade_widget_add_to_layout),
- widget, NULL,
- G_CONNECT_AFTER | G_CONNECT_SWAPPED);
-
}
else if (GTK_IS_WIDGET (widget->priv->object))
{
@@ -2010,7 +1983,12 @@ glade_widget_show (GladeWidget * widget)
if (toplevel != widget)
glade_widget_show (toplevel);
}
+
+ if (widget->priv->visible) return;
+
widget->priv->visible = TRUE;
+ if ((project = glade_widget_get_project (widget)))
+ glade_project_widget_visibility_changed (project, widget, TRUE);
}
/**
@@ -2020,31 +1998,17 @@ glade_widget_show (GladeWidget * widget)
* Hide @widget
*/
void
-glade_widget_hide (GladeWidget * widget)
+glade_widget_hide (GladeWidget *widget)
{
- g_return_if_fail (GLADE_IS_WIDGET (widget));
-
- if (GTK_IS_WIDGET (widget->priv->object))
- {
- GladeDesignView *view;
- GladeProject *project;
- GtkWidget *layout;
-
- project = glade_widget_get_project (widget);
-
- if (project &&
- (view = glade_design_view_get_from_project (project)) != NULL)
- {
- GtkWidget *child;
+ GladeProject *project;
- layout = GTK_WIDGET (glade_design_view_get_layout (view));
- child = gtk_bin_get_child (GTK_BIN (layout));
+ g_return_if_fail (GLADE_IS_WIDGET (widget));
- if (child == GTK_WIDGET (widget->priv->object))
- gtk_container_remove (GTK_CONTAINER (layout), child);
- }
- }
+ if (!widget->priv->visible) return;
+
widget->priv->visible = FALSE;
+ if ((project = glade_widget_get_project (widget)))
+ glade_project_widget_visibility_changed (project, widget, FALSE);
}
/**
diff --git a/gladeui/glade.h b/gladeui/glade.h
index 75665464..ee54dc81 100644
--- a/gladeui/glade.h
+++ b/gladeui/glade.h
@@ -32,7 +32,6 @@
#include <gladeui/glade-app.h>
#include <gladeui/glade-base-editor.h>
#include <gladeui/glade-command.h>
-#include <gladeui/glade-design-layout.h>
#include <gladeui/glade-design-view.h>
#include <gladeui/glade-editor.h>
#include <gladeui/glade-editor-property.h>
diff --git a/plugins/gtk+/Makefile.am b/plugins/gtk+/Makefile.am
index 8d45ef50..f11eb898 100644
--- a/plugins/gtk+/Makefile.am
+++ b/plugins/gtk+/Makefile.am
@@ -30,8 +30,7 @@ libgladegtk_la_SOURCES = glade-gtk.c glade-fixed.c glade-accels.c glade-attr
libgladegtk_la_LDFLAGS = -module -avoid-version $(AM_LDFLAGS)
libgladegtk_la_LIBADD = $(libgladeui) $(GTK_LIBS)
-libgladegtkincludedir= $(includedir)/libgladeui-2.0/gladeui
-libgladegtkinclude_HEADERS = glade-gtk.h glade-accels.h glade-attributes.h glade-column-types.h glade-model-data.h \
+noinst_HEADERS = glade-gtk.h glade-accels.h glade-attributes.h glade-column-types.h glade-model-data.h \
glade-text-button.h glade-icon-sources.h glade-button-editor.h \
glade-tool-button-editor.h glade-image-editor.h glade-image-item-editor.h glade-icon-factory-editor.h \
glade-store-editor.h glade-label-editor.h glade-cell-renderer-editor.h glade-treeview-editor.h \