[goffice] Canvas: properly construct items; handle canvas changes for widgets.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [goffice] Canvas: properly construct items; handle canvas changes for widgets.
- Date: Wed, 16 Sep 2009 17:20:30 +0000 (UTC)
commit 5ef9d14975d2a4c5715e1b866894999a9e8b2f76
Author: Morten Welinder <terra gnome org>
Date: Wed Sep 16 13:19:53 2009 -0400
Canvas: properly construct items; handle canvas changes for widgets.
ChangeLog | 14 +++++++++
goffice/canvas/goc-group.c | 18 +++++++++--
goffice/canvas/goc-item.c | 60 ++++++++++++++++++++++++++++++---------
goffice/canvas/goc-text.c | 4 +-
goffice/canvas/goc-widget.c | 66 +++++++++++++++++++++++++++++++++----------
5 files changed, 127 insertions(+), 35 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 83035b7..ea9180d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2009-09-16 Morten Welinder <terra gnome org>
+ * goffice/canvas/goc-widget.c (goc_widget_init,
+ cb_canvas_changed): New functions.
+ (goc_widget_notify_scrolled): Do nothing if we have no parent.
+ (goc_widget_set_widget): Handle the no-canvas-yet case.
+
+ * goffice/canvas/goc-item.c (goc_item_class_init): Add canvas and
+ parent properties.
+ (goc_item_new): Construct the new item with all its properties.
+
+ * goffice/canvas/goc-group.c (goc_group_unrealize,
+ goc_group_realize): Chain.
+ (goc_group_add_child, goc_group_remove_child): Notify item::parent
+ and item::canvas.
+
* goffice/canvas/goc-item.c (goc_item_realize,
goc_item_unrealize): New handlers.
(_goc_item_realize, _goc_item_unrealize): Simplify.
diff --git a/goffice/canvas/goc-group.c b/goffice/canvas/goc-group.c
index d3eaf31..35fc63a 100644
--- a/goffice/canvas/goc-group.c
+++ b/goffice/canvas/goc-group.c
@@ -26,7 +26,7 @@
#include <glib/gi18n-lib.h>
#include <gsf/gsf-impl-utils.h>
-static GObjectClass *parent_klass;
+static GocItemClass *parent_klass;
enum {
GROUP_PROP_0,
@@ -176,10 +176,13 @@ goc_group_realize (GocItem *item)
{
GocGroup *group = GOC_GROUP (item);
GList *l;
+
for (l = g_list_first (group->children); l; l = g_list_next (l)) {
GocItem *child = GOC_ITEM (l->data);
_goc_item_realize (child);
}
+
+ parent_klass->realize (item);
}
static void
@@ -187,6 +190,9 @@ goc_group_unrealize (GocItem *item)
{
GocGroup *group = GOC_GROUP (item);
GList *l;
+
+ parent_klass->unrealize (item);
+
for (l = g_list_first (group->children); l; l = g_list_next (l)) {
GocItem *child = GOC_ITEM (l->data);
_goc_item_unrealize (child);
@@ -211,7 +217,7 @@ goc_group_dispose (GObject *obj)
{
GocGroup *group = GOC_GROUP (obj);
goc_group_clear (group);
- parent_klass->dispose (obj);
+ ((GObjectClass*)parent_klass)->dispose (obj);
}
static void
@@ -297,6 +303,8 @@ goc_group_add_child (GocGroup *group, GocItem *item)
group->children = g_list_append (group->children, item);
item->parent = group;
item->canvas = group->base.canvas;
+ g_object_notify (G_OBJECT (item), "parent");
+ g_object_notify (G_OBJECT (item), "canvas");
if (GOC_ITEM (group)->realized)
_goc_item_realize (item);
goc_item_parent_changed (item);
@@ -311,11 +319,13 @@ goc_group_remove_child (GocGroup *group, GocItem *item)
g_return_if_fail (item->parent == group);
if (item->canvas && item->canvas->last_item == item)
item->canvas->last_item = NULL;
+ if (GOC_ITEM (group)->realized)
+ _goc_item_unrealize (item);
group->children = g_list_remove (group->children, item);
item->parent = NULL;
item->canvas = NULL;
- if (GOC_ITEM (group)->realized)
- _goc_item_unrealize (item);
+ g_object_notify (G_OBJECT (item), "parent");
+ g_object_notify (G_OBJECT (item), "canvas");
goc_item_bounds_changed (GOC_ITEM (group));
}
diff --git a/goffice/canvas/goc-item.c b/goffice/canvas/goc-item.c
index 0b0bfda..c5b886d 100644
--- a/goffice/canvas/goc-item.c
+++ b/goffice/canvas/goc-item.c
@@ -24,6 +24,13 @@
#include <goffice/goffice.h>
#include <gtk/gtk.h>
#include <gsf/gsf-impl-utils.h>
+#include <glib/gi18n-lib.h>
+
+enum {
+ ITEM_PROP_0,
+ ITEM_PROP_CANVAS,
+ ITEM_PROP_PARENT
+};
/**
* GocItemClass:
@@ -142,11 +149,47 @@ goc_item_dispose (GObject *object)
}
static void
+goc_item_get_property (GObject *gobject, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GocItem *item = GOC_ITEM (gobject);
+
+ switch (param_id) {
+ case ITEM_PROP_CANVAS:
+ g_value_set_object (value, item->canvas);
+ break;
+
+ case ITEM_PROP_PARENT:
+ g_value_set_object (value, item->parent);
+ break;
+
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
goc_item_class_init (GocItemClass *item_klass)
{
GObjectClass *obj_klass = (GObjectClass *) item_klass;
item_parent_class = g_type_class_peek_parent (item_klass);
+ obj_klass->dispose = goc_item_dispose;
+ obj_klass->get_property = goc_item_get_property;
+
+ g_object_class_install_property (obj_klass, ITEM_PROP_CANVAS,
+ g_param_spec_object ("canvas",
+ _("Canvas"),
+ _("The canvas object on which the item resides"),
+ GOC_TYPE_CANVAS,
+ GSF_PARAM_STATIC | G_PARAM_READABLE));
+ g_object_class_install_property (obj_klass, ITEM_PROP_PARENT,
+ g_param_spec_object ("parent",
+ _("Parent"),
+ _("The group in which the item resides"),
+ GOC_TYPE_GROUP,
+ GSF_PARAM_STATIC | G_PARAM_READABLE));
+
item_klass->realize = goc_item_realize;
item_klass->unrealize = goc_item_unrealize;
item_klass->button_pressed = goc_item_button_pressed;
@@ -155,8 +198,6 @@ goc_item_class_init (GocItemClass *item_klass)
item_klass->motion = goc_item_motion;
item_klass->enter_notify = goc_item_enter_notify;
item_klass->leave_notify = goc_item_leave_notify;
-
- obj_klass->dispose = goc_item_dispose;
}
static void
@@ -177,21 +218,12 @@ goc_item_new (GocGroup *group, GType type, const gchar *first_arg_name, ...)
g_return_val_if_fail (GOC_IS_GROUP (group), NULL);
- item = GOC_ITEM (g_object_new (type, NULL));
- g_return_val_if_fail ((item != NULL), NULL);
-
- goc_group_add_child (group, item);
-
- /* FIXME: Due to contruction-only arguments, this needs to be
- merged with the g_object_new above. We cannot do this
- right now due to problems in GocWidget. */
va_start (args, first_arg_name);
- g_object_set_valist (G_OBJECT (item), first_arg_name, args);
+ item = GOC_ITEM (g_object_new_valist (type, first_arg_name, args));
va_end (args);
+ g_return_val_if_fail ((item != NULL), NULL);
- /* This is probably a no-op. goc_group_add_child did it. */
- if (GOC_ITEM (group)->realized)
- _goc_item_realize (item);
+ goc_group_add_child (group, item);
return item;
}
diff --git a/goffice/canvas/goc-text.c b/goffice/canvas/goc-text.c
index a3e2da5..87d6770 100644
--- a/goffice/canvas/goc-text.c
+++ b/goffice/canvas/goc-text.c
@@ -43,7 +43,7 @@ static GocItemClass *parent_class;
static void
goc_text_set_property (GObject *gobject, guint param_id,
- GValue const *value, GParamSpec *pspec)
+ GValue const *value, GParamSpec *pspec)
{
GocText *text = GOC_TEXT (gobject);
@@ -113,7 +113,7 @@ goc_text_set_property (GObject *gobject, guint param_id,
static void
goc_text_get_property (GObject *gobject, guint param_id,
- GValue *value, GParamSpec *pspec)
+ GValue *value, GParamSpec *pspec)
{
GocText *text = GOC_TEXT (gobject);
diff --git a/goffice/canvas/goc-widget.c b/goffice/canvas/goc-widget.c
index c29a446..a95968f 100644
--- a/goffice/canvas/goc-widget.c
+++ b/goffice/canvas/goc-widget.c
@@ -27,7 +27,17 @@
#include <math.h>
-static GObjectClass *widget_parent_class;
+static GocItemClass *widget_parent_class;
+
+enum {
+ WIDGET_PROP_0,
+ WIDGET_PROP_WIDGET,
+ WIDGET_PROP_X,
+ WIDGET_PROP_Y,
+ WIDGET_PROP_W,
+ WIDGET_PROP_H
+};
+
static gboolean
enter_notify_cb (G_GNUC_UNUSED GtkWidget *w, GdkEventCrossing *event, GocWidget *item)
@@ -50,14 +60,28 @@ button_press_cb (G_GNUC_UNUSED GtkWidget *w, GdkEventButton *event, GocWidget *i
(event->y + item->y) / item->base.canvas->pixels_per_unit + item->base.canvas->scroll_y1);
}
-enum {
- WIDGET_PROP_0,
- WIDGET_PROP_WIDGET,
- WIDGET_PROP_X,
- WIDGET_PROP_Y,
- WIDGET_PROP_W,
- WIDGET_PROP_H
-};
+static void
+cb_canvas_changed (GocWidget *item, G_GNUC_UNUSED GParamSpec *pspec,
+ G_GNUC_UNUSED gpointer user)
+{
+ GtkWidget *parent, *w = item->widget;
+ GocItem *gitem = (GocItem *)item;
+
+ if (!w)
+ return;
+
+ parent = gtk_widget_get_parent (w);
+ if (parent == (GtkWidget *)gitem->canvas)
+ return;
+
+ g_object_ref (w);
+ if (parent)
+ gtk_container_remove (GTK_CONTAINER (parent), w);
+ if (gitem->canvas)
+ gtk_layout_put (GTK_LAYOUT (gitem->canvas), w,
+ item->x, item->y);
+ g_object_unref (w);
+}
static void
goc_widget_notify_scrolled (GocItem *item)
@@ -67,6 +91,9 @@ goc_widget_notify_scrolled (GocItem *item)
GocWidget *widget = GOC_WIDGET (item);
parent = item->parent;
+ if (!parent)
+ return;
+
if (!item->cached_bounds)
goc_item_update_bounds (GOC_ITEM (item)); /* don't care about const */
x0 = item->x0;
@@ -120,8 +147,9 @@ goc_widget_set_widget (GocWidget *item, GtkWidget *widget)
if (widget) {
g_object_ref (item->widget);
gtk_widget_show (widget);
- gtk_layout_put (GTK_LAYOUT (GOC_ITEM (item)->canvas),
- widget, item->x, item->y);
+ if (GOC_ITEM (item)->canvas)
+ gtk_layout_put (GTK_LAYOUT (GOC_ITEM (item)->canvas),
+ widget, item->x, item->y);
goc_widget_notify_scrolled (GOC_ITEM (item));
/* we need to propagate some signals to the parent item */
g_signal_connect (widget, "enter-notify-event",
@@ -133,7 +161,7 @@ goc_widget_set_widget (GocWidget *item, GtkWidget *widget)
static void
goc_widget_set_property (GObject *obj, guint param_id,
- GValue const *value, GParamSpec *pspec)
+ GValue const *value, GParamSpec *pspec)
{
GocWidget *item = GOC_WIDGET (obj);
@@ -171,7 +199,7 @@ goc_widget_set_property (GObject *obj, guint param_id,
static void
goc_widget_get_property (GObject *obj, guint param_id,
- GValue *value, GParamSpec *pspec)
+ GValue *value, GParamSpec *pspec)
{
GocWidget *item = GOC_WIDGET (obj);
@@ -250,7 +278,15 @@ goc_widget_dispose (GObject *object)
{
GocWidget *item = GOC_WIDGET (object);
goc_widget_set_widget (item, NULL);
- widget_parent_class->dispose (object);
+ ((GObjectClass *)widget_parent_class)->dispose (object);
+}
+
+static void
+goc_widget_init (GocWidget *item)
+{
+ g_signal_connect (item, "notify::canvas",
+ G_CALLBACK (cb_canvas_changed),
+ NULL);
}
static void
@@ -303,7 +339,7 @@ goc_widget_class_init (GocItemClass *item_klass)
}
GSF_CLASS (GocWidget, goc_widget,
- goc_widget_class_init, NULL,
+ goc_widget_class_init, goc_widget_init,
GOC_TYPE_ITEM)
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]