diff options
author | Christopher James Lahey <clahey@helixcode.com> | 2000-03-11 08:32:15 +0800 |
---|---|---|
committer | Chris Lahey <clahey@src.gnome.org> | 2000-03-11 08:32:15 +0800 |
commit | 0a908b7fe481dd3bf216021fd8e04489f5f2aa66 (patch) | |
tree | cd22b484c729a21684ef46b6c99483847c43dae2 /e-util/e-canvas.c | |
parent | 8c65f8861bd16321eeafac1d827d1fb4a557247c (diff) | |
download | gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.gz gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.bz2 gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.lz gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.xz gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.zst gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.zip |
Designed a new system for doing hierarchical displays in the canvas. Adds
2000-03-10 Christopher James Lahey <clahey@helixcode.com>
* e-util/e-canvas.c, e-util/e-canvas.h: Designed a new system for
doing hierarchical displays in the canvas. Adds an extra idle
loop to the canvas system.
* widgets/e-minicard/e-minicard.c,
widgets/e-minicard/e-minicard-label.c,
widgets/e-minicard/e-minicard-label.h,
widgets/e-minicard/e-reflow.c, widgets/e-minicard/test-reflow.c,
widgets/e-text/e-text.c, widgets/e-text/e-text.h: Adapted to use
the new e-canvas reflow system.
svn path=/trunk/; revision=2096
Diffstat (limited to 'e-util/e-canvas.c')
-rw-r--r-- | e-util/e-canvas.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/e-util/e-canvas.c b/e-util/e-canvas.c index 850e438386..68f1b0f9f3 100644 --- a/e-util/e-canvas.c +++ b/e-util/e-canvas.c @@ -36,6 +36,13 @@ static int emit_event (GnomeCanvas *canvas, GdkEvent *event); static GnomeCanvasClass *parent_class = NULL; +enum { + REFLOW, + LAST_SIGNAL +}; + +static guint e_canvas_signals [LAST_SIGNAL] = { 0, }; + GtkType e_canvas_get_type (void) { @@ -78,6 +85,18 @@ e_canvas_class_init (ECanvasClass *klass) widget_class->key_release_event = e_canvas_key; widget_class->focus_in_event = e_canvas_focus_in; widget_class->focus_out_event = e_canvas_focus_out; + + klass->reflow = NULL; + + e_canvas_signals [REFLOW] = + gtk_signal_new ("reflow", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ECanvasClass, reflow), + gtk_marshal_NONE__INT_INT, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, e_canvas_signals, LAST_SIGNAL); } static void @@ -299,3 +318,101 @@ e_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event) else return FALSE; } + + +static void +e_canvas_item_invoke_update (GnomeCanvasItem *item, int flags) +{ + GnomeCanvasGroup *group; + GList *list; + GnomeCanvasItem *child; + if ( ! gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow") ) + return; + + if ( GNOME_IS_CANVAS_GROUP( item ) ) { + group = GNOME_CANVAS_GROUP( item ); + for ( list = group->item_list; list; list = list->next ) { + child = GNOME_CANVAS_ITEM(list->data); + e_canvas_item_invoke_update(child, flags); + } + } + + if ( gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::needs_reflow") ) { + ECanvasItemReflowFunc func = gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::reflow_callback"); + if ( func ) + func(item, flags); + } + + gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::needs_reflow", (gpointer) 0); + gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow", (gpointer) 0); +} + +static void +do_update (ECanvas *canvas) +{ + e_canvas_item_invoke_update (GNOME_CANVAS(canvas)->root, 0); +} + +/* Idle handler for the canvas. It deals with pending updates and redraws. */ +static gint +idle_handler (gpointer data) +{ + ECanvas *canvas; + + GDK_THREADS_ENTER (); + + canvas = E_CANVAS (data); + do_update (canvas); + + /* Reset idle id */ + canvas->idle_id = 0; + + gtk_signal_emit (GTK_OBJECT (canvas), + e_canvas_signals [REFLOW]); + + GDK_THREADS_LEAVE (); + + return FALSE; +} + +/* Convenience function to add an idle handler to a canvas */ +static void +add_idle (ECanvas *canvas) +{ + if (canvas->idle_id != 0) + return; + + canvas->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_handler, (gpointer) canvas, NULL); +} + +static void +e_canvas_item_descendent_needs_reflow (GnomeCanvasItem *item) +{ + if ( gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow") ) + return; + gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow", (gpointer) 1); + if ( item->parent ) + e_canvas_item_descendent_needs_reflow(item->parent); +} + +void +e_canvas_item_request_reflow (GnomeCanvasItem *item) +{ + gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::needs_reflow", (gpointer) 1); + e_canvas_item_descendent_needs_reflow(item); + add_idle(E_CANVAS(item->canvas)); +} + +void +e_canvas_item_request_parent_reflow (GnomeCanvasItem *item) +{ + g_return_if_fail(item != NULL); + g_return_if_fail(GNOME_IS_CANVAS_ITEM(item)); + e_canvas_item_request_reflow(item->parent); +} + +void +e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, ECanvasItemReflowFunc func) +{ + gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::reflow_callback", (gpointer) func); +} |