goocanvas r21 - in trunk: . demo docs src
- From: damon svn gnome org
- To: svn-commits-list gnome org
- Subject: goocanvas r21 - in trunk: . demo docs src
- Date: Fri, 31 Oct 2008 16:50:17 +0000 (UTC)
Author: damon
Date: Fri Oct 31 16:50:17 2008
New Revision: 21
URL: http://svn.gnome.org/viewvc/goocanvas?rev=21&view=rev
Log:
2008-10-31 Damon Chaplin <damon gnome org>
* src/goocanvas.h:
(goo_canvas_get_static_root_item): new function to get static root item.
(goo_canvas_set_static_root_item): new function to set static root item.
(goo_canvas_get_static_root_item_model): new function to get static
root item model.
(goo_canvas_set_static_root_item_model): new function to set static
root item model.
(goo_canvas_request_item_redraw): new function to request a redraw of
an item either in device space or in the static item space.
* src/goocanvasitem.h (struct _GooCanvasItemIface): added
get_is_static() and set_is_static() interface methods.
* src/goocanvasitemsimple.h (struct _GooCanvasItemSimpleData): removed
one bit from cache_setting and used it for is_static. Hopefully that
won't break binary compatibility.
* src/goocanvas.c (struct _GooCanvasPrivate): added new private struct
with static root item & model and current window position.
(goo_canvas_init): init private struct and create static root item.
(goo_canvas_dispose): free static root item & model.
(goo_canvas_update_internal): update static items.
(goo_canvas_get_item_at): check static items as well.
(goo_canvas_get_items_at): check static items as well.
(goo_canvas_realize): store original window position in private struct.
(request_static_redraw): new function to request a redraw in static
coordinate space.
(request_all_static_redraws): new function to request a redraw of all
static items.
(paint_static_items): new function to paint the static items.
(goo_canvas_expose_event): call paint_static_items().
(goo_canvas_convert_to_static_item_space): new function to convert
coords to static space.
(goo_canvas_adjustment_value_changed): redraw the static items before
the window is scrolled, but in their new position. We do this so we
don't see them being dragged along when scrolling.
Redraw them again after the window has been moved. Hopefully we can
optimize this a bit in future to avoid the flickering.
* src/goocanvasitem.c (goo_canvas_item_get_is_static)
(goo_canvas_item_set_is_static): new functions to call the interface
methods if they are implemented. The default behavior allows old code
to work without crashing (but old items can't be static).
* src/goocanvasitemsimple.c (goo_canvas_item_simple_get_is_static)
(goo_canvas_item_simple_set_is_static): implemented new interface
functions - just get/set the bit-flag.
* src/goocanvasgroup.c (goo_canvas_group_add_child): call
set_is_static() on new child.
* src/goocanvasgroup.c (goo_canvas_group_set_is_static): implement new
interface method, calling set_is_static() for all children if changed.
* src/goocanvasitemsimple.c:
* src/goocanvasgroup.c:
* src/goocanvastable.c: use new goo_canvas_request_item_redraw()
function so static items are redrawn correctly.
* demo/mv-demo.c (create_static_model):
* demo/demo.c (setup_static_items): added some static items to test.
Note that dragging around when scale != 1.0 is weird as the coord
spaces are different, but is expected.
Modified:
trunk/ChangeLog
trunk/demo/demo.c
trunk/demo/mv-demo.c
trunk/docs/goocanvas-sections.txt
trunk/src/goocanvas.c
trunk/src/goocanvas.h
trunk/src/goocanvasgroup.c
trunk/src/goocanvasitem.c
trunk/src/goocanvasitem.h
trunk/src/goocanvasitemsimple.c
trunk/src/goocanvasitemsimple.h
trunk/src/goocanvastable.c
Modified: trunk/demo/demo.c
==============================================================================
--- trunk/demo/demo.c (original)
+++ trunk/demo/demo.c Fri Oct 31 16:50:17 2008
@@ -1326,6 +1326,40 @@
}
+static void
+setup_static_items (GooCanvas *canvas)
+{
+ GooCanvasItem *static_root, *item;
+
+ static_root = goo_canvas_get_static_root_item (canvas);
+
+ item = goo_canvas_polyline_new_line (static_root,
+ 40.0, 410.0,
+ 40.0, 330.0,
+ "stroke-color", "midnightblue",
+ "line-width", 3.0,
+ "end-arrow", TRUE,
+ "arrow-tip-length", 3.0,
+ "arrow-length", 4.0,
+ "arrow-width", 3.5,
+ NULL);
+ setup_item_signals (item);
+
+ item = goo_canvas_polyline_new_line (static_root,
+ 32.0, 370.0,
+ 48.0, 370.0,
+ "stroke-color", "midnightblue",
+ "line-width", 3.0,
+ NULL);
+ setup_item_signals (item);
+
+ item = goo_canvas_text_new (static_root, "N", 40, 320, -1, GTK_ANCHOR_S,
+ "font", "Sans 12",
+ NULL);
+ setup_item_signals (item);
+}
+
+
/* This checks that the rgba color properties work properly, i.e. the value
written to them is the same when read back out. */
static void
@@ -1423,6 +1457,7 @@
setup_texts (root);
setup_images (root);
setup_invisible_texts (root);
+ setup_static_items (canvas);
#endif
test_color_properties (root);
Modified: trunk/demo/mv-demo.c
==============================================================================
--- trunk/demo/mv-demo.c (original)
+++ trunk/demo/mv-demo.c Fri Oct 31 16:50:17 2008
@@ -385,7 +385,8 @@
GtkWidget *
-create_canvas_primitives (GooCanvasItemModel *model)
+create_canvas_primitives (GooCanvasItemModel *model,
+ GooCanvasItemModel *static_model)
{
GtkWidget *vbox;
GtkWidget *hbox;
@@ -631,6 +632,8 @@
item views to render each of the items. */
goo_canvas_set_root_item_model (GOO_CANVAS (canvas), model);
+ goo_canvas_set_static_root_item_model (GOO_CANVAS (canvas), static_model);
+
#if 0
g_signal_connect_after (canvas, "key_press_event",
G_CALLBACK (key_press),
@@ -1211,6 +1214,39 @@
}
+static GooCanvasItemModel*
+create_static_model ()
+{
+ GooCanvasItemModel *static_root, *item;
+
+ static_root = goo_canvas_group_model_new (NULL, NULL);
+
+ item = goo_canvas_polyline_model_new_line (static_root,
+ 40.0, 410.0,
+ 40.0, 330.0,
+ "stroke-color", "midnightblue",
+ "line-width", 3.0,
+ "end-arrow", TRUE,
+ "arrow-tip-length", 3.0,
+ "arrow-length", 4.0,
+ "arrow-width", 3.5,
+ NULL);
+
+ item = goo_canvas_polyline_model_new_line (static_root,
+ 32.0, 370.0,
+ 48.0, 370.0,
+ "stroke-color", "midnightblue",
+ "line-width", 3.0,
+ NULL);
+
+ item = goo_canvas_text_model_new (static_root, "N", 40, 320, -1, GTK_ANCHOR_S,
+ "font", "Sans 12",
+ NULL);
+
+ return static_root;
+}
+
+
static void
test_simple_transforms (GooCanvasItemModel *root)
{
@@ -1295,7 +1331,8 @@
static GtkWidget*
-create_window (GooCanvasItemModel *model)
+create_window (GooCanvasItemModel *model,
+ GooCanvasItemModel *static_model)
{
GtkWidget *window, *notebook;
@@ -1310,7 +1347,7 @@
gtk_container_add (GTK_CONTAINER (window), notebook);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
- create_canvas_primitives (model),
+ create_canvas_primitives (model, static_model),
gtk_label_new ("Primitives"));
#if 1
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
@@ -1375,21 +1412,23 @@
int
main (int argc, char *argv[])
{
- GooCanvasItemModel *model;
+ GooCanvasItemModel *model, *static_model;
GtkWidget *window;
gtk_set_locale ();
gtk_init (&argc, &argv);
model = create_model ();
+ static_model = create_static_model ();
/* Create 2 windows to show off multiple views. */
- window = create_window (model);
+ window = create_window (model, static_model);
#if 1
- window = create_window (model);
+ window = create_window (model, static_model);
#endif
g_object_unref (model);
+ g_object_unref (static_model);
gtk_main ();
return 0;
Modified: trunk/docs/goocanvas-sections.txt
==============================================================================
--- trunk/docs/goocanvas-sections.txt (original)
+++ trunk/docs/goocanvas-sections.txt Fri Oct 31 16:50:17 2008
@@ -95,6 +95,8 @@
goo_canvas_item_set_simple_transform
goo_canvas_item_get_bounds
goo_canvas_item_is_visible
+goo_canvas_item_get_is_static
+goo_canvas_item_set_is_static
<SUBSECTION>
goo_canvas_item_animate
@@ -351,10 +353,20 @@
<SUBSECTION>
goo_canvas_new
+
+<SUBSECTION>
goo_canvas_get_root_item
goo_canvas_set_root_item
goo_canvas_get_root_item_model
goo_canvas_set_root_item_model
+
+<SUBSECTION>
+goo_canvas_get_static_root_item
+goo_canvas_set_static_root_item
+goo_canvas_get_static_root_item_model
+goo_canvas_set_static_root_item_model
+
+<SUBSECTION>
goo_canvas_get_bounds
goo_canvas_set_bounds
goo_canvas_get_scale
@@ -394,6 +406,7 @@
goo_canvas_update
goo_canvas_request_update
goo_canvas_request_redraw
+goo_canvas_request_item_redraw
goo_canvas_get_default_line_width
<SUBSECTION Standard>
Modified: trunk/src/goocanvas.c
==============================================================================
--- trunk/src/goocanvas.c (original)
+++ trunk/src/goocanvas.c Fri Oct 31 16:50:17 2008
@@ -105,6 +105,17 @@
#include "goocanvasmarshal.h"
+#define GOO_CANVAS_GET_PRIVATE(canvas) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((canvas), GOO_TYPE_CANVAS, GooCanvasPrivate))
+
+typedef struct _GooCanvasPrivate GooCanvasPrivate;
+struct _GooCanvasPrivate {
+ GooCanvasItem *static_root_item;
+ GooCanvasItemModel *static_root_item_model;
+ gint window_x, window_y;
+};
+
+
enum {
PROP_0,
@@ -134,6 +145,7 @@
LAST_SIGNAL
};
+
static guint canvas_signals[LAST_SIGNAL] = { 0 };
static void goo_canvas_dispose (GObject *object);
@@ -201,6 +213,9 @@
gboolean redraw_if_needed);
static void goo_canvas_update_automatic_bounds (GooCanvas *canvas);
+static void goo_canvas_convert_to_static_item_space (GooCanvas *canvas,
+ gdouble *x,
+ gdouble *y);
G_DEFINE_TYPE (GooCanvas, goo_canvas, GTK_TYPE_CONTAINER)
@@ -217,6 +232,8 @@
GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
GtkContainerClass *container_class = (GtkContainerClass*) klass;
+ g_type_class_add_private (gobject_class, sizeof (GooCanvasPrivate));
+
gobject_class->dispose = goo_canvas_dispose;
gobject_class->finalize = goo_canvas_finalize;
gobject_class->get_property = goo_canvas_get_property;
@@ -443,6 +460,8 @@
static void
goo_canvas_init (GooCanvas *canvas)
{
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
+
/* We set GTK_CAN_FOCUS by default, so it works as people expect.
Though developers can turn this off if not needed for efficiency. */
GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
@@ -485,6 +504,14 @@
time. Apps can set their own root item if required. */
canvas->root_item = goo_canvas_group_new (NULL, NULL);
goo_canvas_item_set_canvas (canvas->root_item, canvas);
+
+ priv->static_root_item = goo_canvas_group_new (NULL, NULL);
+ goo_canvas_item_set_canvas (priv->static_root_item, canvas);
+ goo_canvas_item_set_is_static (priv->static_root_item, TRUE);
+ priv->static_root_item_model = NULL;
+
+ priv->window_x = 0;
+ priv->window_y = 0;
}
@@ -509,6 +536,7 @@
goo_canvas_dispose (GObject *object)
{
GooCanvas *canvas = (GooCanvas*) object;
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
if (canvas->model_to_item)
{
@@ -528,6 +556,18 @@
canvas->root_item_model = NULL;
}
+ if (priv->static_root_item)
+ {
+ g_object_unref (priv->static_root_item);
+ priv->static_root_item = NULL;
+ }
+
+ if (priv->static_root_item_model)
+ {
+ g_object_unref (priv->static_root_item_model);
+ priv->static_root_item_model = NULL;
+ }
+
if (canvas->idle_id)
{
g_source_remove (canvas->idle_id);
@@ -954,6 +994,142 @@
/**
+ * goo_canvas_get_static_root_item:
+ * @canvas: a #GooCanvas.
+ *
+ * Gets the static root item of the canvas.
+ *
+ * Returns: the static root item, or %NULL.
+ **/
+GooCanvasItem*
+goo_canvas_get_static_root_item (GooCanvas *canvas)
+{
+ g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL);
+
+ return GOO_CANVAS_GET_PRIVATE (canvas)->static_root_item;
+}
+
+
+/**
+ * goo_canvas_set_static_root_item:
+ * @canvas: a #GooCanvas.
+ * @item: the static root item.
+ *
+ * Sets the static root item. Any existing static items are removed.
+ **/
+void
+goo_canvas_set_static_root_item (GooCanvas *canvas,
+ GooCanvasItem *item)
+{
+ GooCanvasPrivate *priv;
+
+ g_return_if_fail (GOO_IS_CANVAS (canvas));
+ g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
+
+ priv = GOO_CANVAS_GET_PRIVATE (canvas);
+
+ if (priv->static_root_item == item)
+ return;
+
+ /* Remove any current model. */
+ if (priv->static_root_item_model)
+ {
+ g_object_unref (priv->static_root_item_model);
+ priv->static_root_item_model = NULL;
+ }
+
+ if (priv->static_root_item)
+ g_object_unref (priv->static_root_item);
+
+ priv->static_root_item = g_object_ref (item);
+ goo_canvas_item_set_canvas (priv->static_root_item, canvas);
+ goo_canvas_item_set_is_static (priv->static_root_item, TRUE);
+
+ canvas->need_update = TRUE;
+
+ if (GTK_WIDGET_REALIZED (canvas))
+ goo_canvas_update (canvas);
+
+ gtk_widget_queue_draw (GTK_WIDGET (canvas));
+}
+
+
+/**
+ * goo_canvas_get_static_root_item_model:
+ * @canvas: a #GooCanvas.
+ *
+ * Gets the static root item model of the canvas.
+ *
+ * Returns: the static root item model, or %NULL.
+ **/
+GooCanvasItemModel*
+goo_canvas_get_static_root_item_model (GooCanvas *canvas)
+{
+ g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL);
+
+ return GOO_CANVAS_GET_PRIVATE (canvas)->static_root_item_model;
+}
+
+
+/**
+ * goo_canvas_set_static_root_item_model:
+ * @canvas: a #GooCanvas.
+ * @model: the static root item model.
+ *
+ * Sets the static root item model. Any existing static item models are
+ * removed.
+ **/
+void
+goo_canvas_set_static_root_item_model (GooCanvas *canvas,
+ GooCanvasItemModel *model)
+{
+ GooCanvasPrivate *priv;
+
+ g_return_if_fail (GOO_IS_CANVAS (canvas));
+ g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
+
+ priv = GOO_CANVAS_GET_PRIVATE (canvas);
+
+ if (priv->static_root_item_model == model)
+ return;
+
+ if (priv->static_root_item_model)
+ {
+ g_object_unref (priv->static_root_item_model);
+ priv->static_root_item_model = NULL;
+ }
+
+ if (priv->static_root_item)
+ {
+ g_object_unref (priv->static_root_item);
+ priv->static_root_item = NULL;
+ }
+
+ if (model)
+ {
+ priv->static_root_item_model = g_object_ref (model);
+
+ /* Create a hierarchy of canvas items for all the items in the model. */
+ priv->static_root_item = goo_canvas_create_item (canvas, model);
+ }
+ else
+ {
+ /* The model has been reset so we go back to a default root group. */
+ priv->static_root_item = goo_canvas_group_new (NULL, NULL);
+ }
+
+ goo_canvas_item_set_canvas (priv->static_root_item, canvas);
+ goo_canvas_item_set_is_static (priv->static_root_item, TRUE);
+ canvas->need_update = TRUE;
+
+ if (GTK_WIDGET_REALIZED (canvas))
+ goo_canvas_update (canvas);
+
+ gtk_widget_queue_draw (GTK_WIDGET (canvas));
+}
+
+
+/**
* goo_canvas_get_item:
* @canvas: a #GooCanvas.
* @model: a #GooCanvasItemModel.
@@ -1014,19 +1190,30 @@
gdouble y,
gboolean is_pointer_event)
{
+ GooCanvasPrivate *priv;
cairo_t *cr;
GooCanvasItem *result = NULL;
- GList *list;
+ GList *list = NULL;
g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL);
- /* If no root item is set, just return NULL. */
- if (!canvas->root_item)
- return NULL;
-
+ priv = GOO_CANVAS_GET_PRIVATE (canvas);
cr = goo_canvas_create_cairo_context (canvas);
- list = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr,
- is_pointer_event, TRUE, NULL);
+
+ if (canvas->root_item)
+ list = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr,
+ is_pointer_event, TRUE, NULL);
+
+ if (!list && priv->static_root_item)
+ {
+ gdouble static_x = x, static_y = y;
+
+ goo_canvas_convert_to_static_item_space (canvas, &static_x, &static_y);
+ list = goo_canvas_item_get_items_at (priv->static_root_item,
+ static_x, static_y, cr,
+ is_pointer_event, TRUE, NULL);
+ }
+
cairo_destroy (cr);
/* We just return the top item in the list. */
@@ -1059,18 +1246,29 @@
gdouble y,
gboolean is_pointer_event)
{
+ GooCanvasPrivate *priv;
cairo_t *cr;
- GList *result;
+ GList *result = NULL;
g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL);
- /* If no root item is set, just return NULL. */
- if (!canvas->root_item)
- return NULL;
-
+ priv = GOO_CANVAS_GET_PRIVATE (canvas);
cr = goo_canvas_create_cairo_context (canvas);
- result = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr,
- is_pointer_event, TRUE, NULL);
+
+ if (canvas->root_item)
+ result = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr,
+ is_pointer_event, TRUE, NULL);
+
+ if (priv->static_root_item)
+ {
+ gdouble static_x = x, static_y = y;
+
+ goo_canvas_convert_to_static_item_space (canvas, &static_x, &static_y);
+ result = goo_canvas_item_get_items_at (priv->static_root_item,
+ static_x, static_y, cr,
+ is_pointer_event, TRUE, result);
+ }
+
cairo_destroy (cr);
return result;
@@ -1181,6 +1379,7 @@
goo_canvas_realize (GtkWidget *widget)
{
GooCanvas *canvas;
+ GooCanvasPrivate *priv;
GdkWindowAttr attributes;
gint attributes_mask;
gint width_pixels, height_pixels;
@@ -1189,6 +1388,7 @@
g_return_if_fail (GOO_IS_CANVAS (widget));
canvas = GOO_CANVAS (widget);
+ priv = GOO_CANVAS_GET_PRIVATE (canvas);
GTK_WIDGET_SET_FLAGS (canvas, GTK_REALIZED);
attributes.window_type = GDK_WINDOW_CHILD;
@@ -1228,6 +1428,9 @@
| GDK_FOCUS_CHANGE_MASK
| gtk_widget_get_events (widget);
+ priv->window_x = attributes.x;
+ priv->window_y = attributes.y;
+
canvas->canvas_window = gdk_window_new (widget->window,
&attributes, attributes_mask);
gdk_window_set_user_data (canvas->canvas_window, widget);
@@ -1440,6 +1643,47 @@
}
+static void
+request_static_redraw (GooCanvas *canvas,
+ const GooCanvasBounds *bounds)
+{
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
+ GdkRectangle rect;
+
+ if (!GTK_WIDGET_DRAWABLE (canvas) || (bounds->x1 == bounds->x2))
+ return;
+
+ /* We subtract one from the left & top edges, in case anti-aliasing makes
+ the drawing use an extra pixel. */
+ rect.x = (double) bounds->x1 - priv->window_x - 1;
+ rect.y = (double) bounds->y1 - priv->window_y - 1;
+
+ /* We add an extra one here for the same reason. (The other extra one is to
+ round up to the next pixel.) And one for luck! */
+ rect.width = (double) bounds->x2 - priv->window_x - rect.x + 2 + 1;
+ rect.height = (double) bounds->y2 - priv->window_y - rect.y + 2 + 1;
+
+ gdk_window_invalidate_rect (canvas->canvas_window, &rect, FALSE);
+}
+
+
+static void
+request_all_static_redraws (GooCanvas *canvas)
+{
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
+ GooCanvasBounds bounds;
+
+ if (!priv->static_root_item)
+ return;
+
+ /* Get the bounds of all the static items, relative to the window. */
+ goo_canvas_item_get_bounds (priv->static_root_item, &bounds);
+
+ /* Request a redraw of the old position. */
+ request_static_redraw (canvas, &bounds);
+}
+
+
/* This makes sure the canvas is all set up correctly, i.e. the scrollbar
adjustments are set, the canvas x & y offsets are calculated, and the
canvas window is sized. */
@@ -1648,19 +1892,52 @@
goo_canvas_adjustment_value_changed (GtkAdjustment *adjustment,
GooCanvas *canvas)
{
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
AtkObject *accessible;
if (!canvas->freeze_count && GTK_WIDGET_REALIZED (canvas))
{
+ /* Request a redraw of the bounds of the static items. */
+ request_all_static_redraws (canvas);
+
+ /* Move the static items to the new position. */
+ priv->window_x = -canvas->hadjustment->value;
+ priv->window_y = -canvas->vadjustment->value;
+
+ /* Now do the redraw. This makes sure the static items don't get dragged when the rest
+ of the window is scrolled. */
+ if (adjustment)
+ gdk_window_process_updates (canvas->canvas_window, TRUE);
+
+ /* To avoid flicker of static items completely we could redraw the entire canvas whenever
+ it is scrolled, by mapping the temporary window as we do when zooming. Though of course
+ it is a lot slower. We could make this an option. (If this code is used we don't need
+ to redraw the static items and process updates afterwards.) */
+#if 0
+ if (GTK_WIDGET_MAPPED (canvas))
+ gdk_window_show (canvas->tmp_window);
+#endif
+
gdk_window_move (canvas->canvas_window,
- canvas->hadjustment->value,
- canvas->vadjustment->value);
-
+
/* If this is callback from a signal for one of the scrollbars, process
updates here for smoother scrolling. */
if (adjustment)
gdk_window_process_updates (canvas->canvas_window, TRUE);
+ /* Now make sure the static items are redrawn in their new position. */
+ request_all_static_redraws (canvas);
+
+ if (adjustment)
+ gdk_window_process_updates (canvas->canvas_window, TRUE);
+
+#if 0
+ if (GTK_WIDGET_MAPPED (canvas))
+ gdk_window_hide (canvas->tmp_window);
+#endif
+
/* Notify any accessibility modules that the view has changed. */
accessible = gtk_widget_get_accessible (GTK_WIDGET (canvas));
g_signal_emit_by_name (accessible, "visible_data_changed");
@@ -2095,7 +2372,8 @@
goo_canvas_update_internal (GooCanvas *canvas,
cairo_t *cr)
{
- GooCanvasBounds bounds;
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
+ GooCanvasBounds bounds, static_bounds;
/* It is possible that processing the first set of updates causes other
updates to be scheduled, so we loop round until all are done. Items
@@ -2108,6 +2386,10 @@
canvas->need_entire_subtree_update = FALSE;
if (canvas->root_item)
goo_canvas_item_update (canvas->root_item, entire_tree, cr, &bounds);
+
+ if (priv->static_root_item)
+ goo_canvas_item_update (priv->static_root_item, entire_tree, cr,
+ &static_bounds);
}
/* If the bounds are automatically-calculated, update them now. */
@@ -2189,7 +2471,7 @@
/**
* goo_canvas_request_redraw:
* @canvas: a #GooCanvas.
- * @bounds: the bounds to redraw.
+ * @bounds: the bounds to redraw, in device space.
*
* This function is only intended to be used by subclasses of #GooCanvas or
* #GooCanvasItem implementations.
@@ -2224,6 +2506,54 @@
}
+/**
+ * goo_canvas_request_item_redraw:
+ * @canvas: a #GooCanvas.
+ * @bounds: the bounds of the item to redraw.
+ * @is_static: if the item is static.
+ *
+ * This function is only intended to be used by subclasses of #GooCanvas or
+ * #GooCanvasItem implementations.
+ *
+ * Requests that the given bounds be redrawn. If the item is static the bounds are assumed to
+ * be in the static item coordinate space, otherwise they are assumed to be in device space.
+ **/
+void
+goo_canvas_request_item_redraw (GooCanvas *canvas,
+ const GooCanvasBounds *bounds,
+ gboolean is_static)
+{
+ if (is_static)
+ request_static_redraw (canvas, bounds);
+ else
+ goo_canvas_request_redraw (canvas, bounds);
+}
+
+
+static void
+paint_static_items (GooCanvas *canvas,
+ GdkEventExpose *event,
+ cairo_t *cr)
+{
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
+ GooCanvasBounds static_bounds;
+ double static_x_offset, static_y_offset;
+
+ cairo_save (cr);
+ cairo_identity_matrix (cr);
+ static_x_offset = floor (canvas->hadjustment->value);
+ static_y_offset = floor (canvas->vadjustment->value);
+ cairo_translate (cr, static_x_offset, static_y_offset);
+ /* FIXME: Uses pixels at present - use canvas units instead? */
+ static_bounds.x1 = event->area.x - static_x_offset;
+ static_bounds.y1 = event->area.y - static_y_offset;
+ static_bounds.x2 = event->area.width + static_bounds.x1;
+ static_bounds.y2 = event->area.height + static_bounds.y1;
+ goo_canvas_item_paint (priv->static_root_item, cr, &static_bounds, 1.0);
+ cairo_restore (cr);
+}
+
+
static gboolean
goo_canvas_expose_event (GtkWidget *widget,
GdkEventExpose *event)
@@ -2301,6 +2631,8 @@
goo_canvas_item_paint (canvas->root_item, cr, &bounds, canvas->scale);
+ paint_static_items (canvas, event, cr);
+
cairo_destroy (cr);
GTK_WIDGET_CLASS (goo_canvas_parent_class)->expose_event (widget, event);
@@ -3140,6 +3472,20 @@
}
+/* Converts from device space to the coordinate space the static items are in, i.e. in pixels
+ from the top-left of the viewport window. */
+static void
+goo_canvas_convert_to_static_item_space (GooCanvas *canvas,
+ gdouble *x,
+ gdouble *y)
+{
+ *x = ((*x - canvas->bounds.x1) * canvas->device_to_pixels_x)
+ + canvas->canvas_x_offset - canvas->hadjustment->value;
+ *y = ((*y - canvas->bounds.y1) * canvas->device_to_pixels_y)
+ + canvas->canvas_y_offset - canvas->vadjustment->value;
+}
+
+
/**
* goo_canvas_convert_to_item_space:
* @canvas: a #GooCanvas.
Modified: trunk/src/goocanvas.h
==============================================================================
--- trunk/src/goocanvas.h (original)
+++ trunk/src/goocanvas.h Fri Oct 31 16:50:17 2008
@@ -203,6 +203,14 @@
void goo_canvas_set_root_item_model (GooCanvas *canvas,
GooCanvasItemModel *model);
+GooCanvasItem* goo_canvas_get_static_root_item (GooCanvas *canvas);
+void goo_canvas_set_static_root_item (GooCanvas *canvas,
+ GooCanvasItem *item);
+
+GooCanvasItemModel* goo_canvas_get_static_root_item_model (GooCanvas *canvas);
+void goo_canvas_set_static_root_item_model (GooCanvas *canvas,
+ GooCanvasItemModel *model);
+
GooCanvasItem* goo_canvas_get_item (GooCanvas *canvas,
GooCanvasItemModel *model);
GooCanvasItem* goo_canvas_get_item_at (GooCanvas *canvas,
@@ -298,6 +306,9 @@
void goo_canvas_request_update (GooCanvas *canvas);
void goo_canvas_request_redraw (GooCanvas *canvas,
const GooCanvasBounds *bounds);
+void goo_canvas_request_item_redraw (GooCanvas *canvas,
+ const GooCanvasBounds *bounds,
+ gboolean is_static);
gdouble goo_canvas_get_default_line_width (GooCanvas *canvas);
Modified: trunk/src/goocanvasgroup.c
==============================================================================
--- trunk/src/goocanvasgroup.c (original)
+++ trunk/src/goocanvasgroup.c Fri Oct 31 16:50:17 2008
@@ -151,6 +151,7 @@
GooCanvasItem *child,
gint position)
{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
GooCanvasGroup *group = (GooCanvasGroup*) item;
AtkObject *atk_obj, *child_atk_obj;
@@ -167,6 +168,7 @@
}
goo_canvas_item_set_parent (child, item);
+ goo_canvas_item_set_is_static (child, simple->simple_data->is_static);
/* Emit the "children_changed" ATK signal, if ATK is enabled. */
atk_obj = atk_gobject_accessible_for_object (G_OBJECT (item));
@@ -196,7 +198,8 @@
if (simple->canvas)
{
goo_canvas_item_get_bounds (child, &bounds);
- goo_canvas_request_redraw (simple->canvas, &bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &bounds,
+ simple->simple_data->is_static);
}
goo_canvas_util_ptr_array_move (group->items, old_position, new_position);
@@ -222,7 +225,8 @@
if (simple->canvas)
{
goo_canvas_item_get_bounds (child, &bounds);
- goo_canvas_request_redraw (simple->canvas, &bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &bounds,
+ simple->simple_data->is_static);
}
/* Emit the "children_changed" ATK signal, if ATK is enabled. */
@@ -274,6 +278,9 @@
GooCanvasGroup *group = (GooCanvasGroup*) item;
gint i;
+ if (simple->canvas == canvas)
+ return;
+
simple->canvas = canvas;
/* Recursively set the canvas of all child items. */
@@ -286,6 +293,29 @@
static void
+goo_canvas_group_set_is_static (GooCanvasItem *item,
+ gboolean is_static)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasGroup *group = (GooCanvasGroup*) item;
+ gint i;
+
+ if (simple_data->is_static == is_static)
+ return;
+
+ simple_data->is_static = is_static;
+
+ /* Recursively set the canvas of all child items. */
+ for (i = 0; i < group->items->len; i++)
+ {
+ GooCanvasItem *item = group->items->pdata[i];
+ goo_canvas_item_set_is_static (item, is_static);
+ }
+}
+
+
+static void
on_model_child_added (GooCanvasGroupModel *model,
gint position,
GooCanvasGroup *group)
@@ -561,6 +591,7 @@
iface->paint = goo_canvas_group_paint;
iface->set_model = goo_canvas_group_set_model;
+ iface->set_is_static = goo_canvas_group_set_is_static;
}
Modified: trunk/src/goocanvasitem.c
==============================================================================
--- trunk/src/goocanvasitem.c (original)
+++ trunk/src/goocanvasitem.c Fri Oct 31 16:50:17 2008
@@ -676,6 +676,49 @@
/**
+ * goo_canvas_item_get_is_static:
+ * @item: an item.
+ *
+ * Returns %TRUE if the item is static. Static items do not move or change
+ * size when the canvas is scrolled or the scale changes.
+ *
+ * Returns: %TRUE if the item is static.
+ **/
+gboolean
+goo_canvas_item_get_is_static (GooCanvasItem *item)
+{
+ GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+
+ if (iface->get_is_static)
+ return iface->get_is_static (item);
+ return FALSE;
+}
+
+
+/**
+ * goo_canvas_item_set_is_static:
+ * @item: an item.
+ * @is_static: if the item is static.
+ *
+ * Notifies the item that it is static. Static items do not move or change
+ * size when the canvas is scrolled or the scale changes.
+ *
+ * Container items such as #GooCanvasGroup should call this function when
+ * children are added, to notify children whether they are static or not.
+ * Containers should also pass on any changes in their own status to children.
+ **/
+void
+goo_canvas_item_set_is_static (GooCanvasItem *item,
+ gboolean is_static)
+{
+ GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+
+ if (iface->set_is_static)
+ iface->set_is_static (item, is_static);
+}
+
+
+/**
* goo_canvas_item_remove:
* @item: an item.
*
@@ -1554,7 +1597,7 @@
* goo_canvas_item_paint:
* @item: a #GooCanvasItem.
* @cr: a cairo context.
- * @bounds: the bounds that need to be repainted.
+ * @bounds: the bounds that need to be repainted, in device space.
* @scale: the scale to use to determine whether an item should be painted.
* See #GooCanvasItem:visibility-threshold.
*
Modified: trunk/src/goocanvasitem.h
==============================================================================
--- trunk/src/goocanvasitem.h (original)
+++ trunk/src/goocanvasitem.h Fri Oct 31 16:50:17 2008
@@ -109,6 +109,8 @@
* @get_style: gets the item's style.
* @set_style: sets the item's style.
* @is_visible: returns %TRUE if the item is currently visible.
+ * @get_is_static: returns %TRUE if the item is static.
+ * @set_is_static: notifies the item whether it is static or not.
* @get_requested_height: returns the requested height of the item,
* given a particular allocated width, using the parent's coordinate space.
* @get_model: gets the model that the canvas item is viewing.
@@ -280,6 +282,14 @@
gpointer /*GtkTooltip*/ *tooltip);
+ /*< public >*/
+
+ gboolean (* get_is_static) (GooCanvasItem *item);
+ void (* set_is_static) (GooCanvasItem *item,
+ gboolean is_static);
+
+ /*< private >*/
+
/* Padding for future expansion */
void (*_goo_canvas_reserved1) (void);
void (*_goo_canvas_reserved2) (void);
@@ -287,8 +297,6 @@
void (*_goo_canvas_reserved4) (void);
void (*_goo_canvas_reserved5) (void);
void (*_goo_canvas_reserved6) (void);
- void (*_goo_canvas_reserved7) (void);
- void (*_goo_canvas_reserved8) (void);
};
@@ -445,6 +453,9 @@
gdouble x_offset,
gdouble y_offset);
+gboolean goo_canvas_item_get_is_static (GooCanvasItem *item);
+void goo_canvas_item_set_is_static (GooCanvasItem *item,
+ gboolean is_static);
/*
Modified: trunk/src/goocanvasitemsimple.c
==============================================================================
--- trunk/src/goocanvasitemsimple.c (original)
+++ trunk/src/goocanvasitemsimple.c Fri Oct 31 16:50:17 2008
@@ -930,6 +930,9 @@
goo_canvas_item_simple_changed (GooCanvasItemSimple *item,
gboolean recompute_bounds)
{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+
if (recompute_bounds)
{
item->need_entire_subtree_update = TRUE;
@@ -945,7 +948,7 @@
else
{
if (item->canvas)
- goo_canvas_request_redraw (item->canvas, &item->bounds);
+ goo_canvas_request_item_redraw (item->canvas, &item->bounds, simple_data->is_static);
}
}
@@ -1151,6 +1154,27 @@
}
+static gboolean
+goo_canvas_item_simple_get_is_static (GooCanvasItem *item)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+
+ return simple_data->is_static;
+}
+
+
+static void
+goo_canvas_item_simple_set_is_static (GooCanvasItem *item,
+ gboolean is_static)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+
+ simple_data->is_static = is_static;
+}
+
+
/**
* goo_canvas_item_simple_check_style:
* @item: a #GooCanvasItemSimple.
@@ -1258,7 +1282,7 @@
if (entire_tree || simple->need_update)
{
/* Request a redraw of the existing bounds. */
- goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
cairo_save (cr);
if (simple_data->transform)
@@ -1285,7 +1309,7 @@
cairo_restore (cr);
/* Request a redraw of the new bounds. */
- goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
}
*bounds = simple->bounds;
@@ -1303,7 +1327,7 @@
double x_offset, y_offset;
/* Request a redraw of the existing bounds. */
- goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
cairo_save (cr);
if (simple_data->transform)
@@ -1373,6 +1397,7 @@
gdouble y_offset)
{
GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
/* Simple items can't resize at all, so we just adjust the bounds x & y
positions here, and let the item be clipped if necessary. */
@@ -1382,7 +1407,7 @@
simple->bounds.y2 += y_offset;
/* Request a redraw of the new bounds. */
- goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
}
@@ -1568,6 +1593,8 @@
iface->get_style = goo_canvas_item_simple_get_style;
iface->set_style = goo_canvas_item_simple_set_style;
iface->is_visible = goo_canvas_item_simple_is_visible;
+ iface->get_is_static = goo_canvas_item_simple_get_is_static;
+ iface->set_is_static = goo_canvas_item_simple_set_is_static;
iface->get_model = goo_canvas_item_simple_get_model;
iface->set_model = goo_canvas_item_simple_set_model_internal;
Modified: trunk/src/goocanvasitemsimple.h
==============================================================================
--- trunk/src/goocanvasitemsimple.h (original)
+++ trunk/src/goocanvasitemsimple.h Fri Oct 31 16:50:17 2008
@@ -32,6 +32,7 @@
* @own_style: if the item has its own style, rather than using its parent's.
* @clip_fill_rule: the #cairo_fill_rule_t setting specifying the fill rule
* used for the clip path.
+ * @is_static: if the item is static.
*
* This is the data common to both the model and view classes.
*/
@@ -53,10 +54,11 @@
guint can_focus : 1;
guint own_style : 1;
guint clip_fill_rule : 4;
+ guint is_static : 1;
/*< private >*/
/* We might use this in future for a cache setting - never/always/visible. */
- guint cache_setting : 3;
+ guint cache_setting : 2;
/* We might need this for tooltips in future. */
guint has_tooltip : 1;
};
Modified: trunk/src/goocanvastable.c
==============================================================================
--- trunk/src/goocanvastable.c (original)
+++ trunk/src/goocanvastable.c Fri Oct 31 16:50:17 2008
@@ -1935,7 +1935,7 @@
gint row, column, end;
/* Request a redraw of the existing bounds */
- goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
/* We reset the bounds to 0, just in case we are hidden or aren't allocated
any area. */
@@ -2158,7 +2158,7 @@
cairo_restore (cr);
- goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+ goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]