diff options
author | Juan Pablo Ugarte <jp@synctv.com> | 2011-01-31 19:35:14 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <jp@synctv.com> | 2011-01-31 19:35:14 -0300 |
commit | 25d476f11177faefcf48cc71da054cb41ea58426 (patch) | |
tree | 19aa0edfefb79d66933395183b70a8ba14368364 | |
parent | e11251119a384c0e2f3700af9148664bd896bc16 (diff) | |
parent | 4d271ff317f13790274fea5edf015e92ebd5b7f5 (diff) | |
download | glade-25d476f11177faefcf48cc71da054cb41ea58426.tar.gz |
Merge branch 'multiple-toplevels'
-rw-r--r-- | gladeui/Makefile.am | 5 | ||||
-rw-r--r-- | gladeui/glade-app.c | 3 | ||||
-rw-r--r-- | gladeui/glade-design-layout.c | 476 | ||||
-rw-r--r-- | gladeui/glade-design-layout.h | 12 | ||||
-rw-r--r-- | gladeui/glade-design-private.h | 35 | ||||
-rw-r--r-- | gladeui/glade-design-view.c | 202 | ||||
-rw-r--r-- | gladeui/glade-design-view.h | 4 | ||||
-rw-r--r-- | gladeui/glade-project.c | 47 | ||||
-rw-r--r-- | gladeui/glade-project.h | 102 | ||||
-rw-r--r-- | gladeui/glade-widget.c | 84 | ||||
-rw-r--r-- | gladeui/glade.h | 1 | ||||
-rw-r--r-- | plugins/gtk+/Makefile.am | 3 |
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, - >k_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 = >k_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 \ |