[dia] Bug 576548 - Refactoring of highlighting in interactive rendering
- From: Hans Breuer <hans src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dia] Bug 576548 - Refactoring of highlighting in interactive rendering
- Date: Sun, 4 Oct 2009 17:13:52 +0000 (UTC)
commit ec0943877ba6b4adbe975f625380b983ec861ff9
Author: Hans Breuer <hans breuer org>
Date: Sun Oct 4 19:12:23 2009 +0200
Bug 576548 - Refactoring of highlighting in interactive rendering
The previous implementation was keeping the state in every object
(DiaObject::highlight_color) and in the renderer to support it: e.g.
DiaGdkRenderer::highlight_color. But the real highlighting state is managed by
the diagram (where it needs to be).
We got rid of the object knowing about highlight state; provide methods in
the InteractiveRenderer interface to perform highlighted rendering and have
something like a "highlighting selection" (similar to standard selection)
to manage which object should be rendered highlighted.
From: Heikki Paajanen <hepaajan iki fi>
Date: Thu, 28 May 2009 18:37:49 +0300
Subject: Refactoring of highlighting in interactive rendering
https://bugzilla.gnome.org/attachment.cgi?id=135703
From: Hans Breuer <hans breuer org>
Date: Sat, 30 May 2009 14:07:08 +0200
Subject: Bug 576548 - Highlighting cleanup second iteration
https://bugzilla.gnome.org/attachment.cgi?id=135704
* app/display.c : don't crash if the renderer does not support highligthing
* lib/diagramdata.[ch] : renamed some functions and more consistent format
* app/highlight.c app/object_ops.c : reflect renaming
* lib/libdia.def : export highlight accessors
* lib/plug-ins.h : increment API_VERSION, object size changed
app/create_object.c | 2 +-
app/display.c | 10 ++++++-
app/highlight.c | 16 ++--------
app/highlight.h | 2 +-
app/modify_tool.c | 13 ++------
app/object_ops.c | 2 +-
app/render_gdk.c | 43 +++++++++++++++++++++++++++
app/textedit.c | 4 +--
lib/diagdkrenderer.c | 9 +----
lib/diagramdata.c | 54 +++++++++++++++++++++++++++++++++++
lib/diagramdata.h | 14 +++++++++
lib/diainteractiverenderer.c | 1 +
lib/diarenderer.h | 6 ++++
lib/libdia.def | 3 ++
lib/object.h | 3 --
lib/plug-ins.h | 2 +-
plug-ins/libart/dialibartrenderer.c | 7 ----
plug-ins/libart/render_libart.c | 42 +++++++++++++++++++++++++++
18 files changed, 187 insertions(+), 46 deletions(-)
---
diff --git a/app/create_object.c b/app/create_object.c
index 4ba1117..f2bf369 100644
--- a/app/create_object.c
+++ b/app/create_object.c
@@ -233,7 +233,7 @@ create_object_motion(CreateObjectTool *tool, GdkEventMotion *event,
if (connectionpoint != NULL) {
to = connectionpoint->pos;
- highlight_object(connectionpoint->object, NULL, ddisp->diagram);
+ highlight_object(connectionpoint->object, DIA_HIGHLIGHT_CONNECTIONPOINT, ddisp->diagram);
ddisplay_set_all_cursor(get_cursor(CURSOR_CONNECT));
}
}
diff --git a/app/display.c b/app/display.c
index 343eafd..661d364 100644
--- a/app/display.c
+++ b/app/display.c
@@ -618,7 +618,15 @@ ddisplay_obj_render(DiaObject *obj, DiaRenderer *renderer,
DDisplay *ddisp = (DDisplay *)data;
int i;
- DIA_RENDERER_GET_CLASS(renderer)->draw_object(renderer, obj);
+ DiaInteractiveRendererInterface *irenderer =
+ DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer);
+ DiaHighlightType hltype = data_object_get_highlight(DIA_DIAGRAM_DATA(ddisp->diagram), obj);
+
+ if (hltype != DIA_HIGHLIGHT_NONE && irenderer->draw_object_highlighted != NULL)
+ irenderer->draw_object_highlighted(renderer, obj, hltype);
+ else /* maybe the renderer does not support highlighting */
+ DIA_RENDERER_GET_CLASS(renderer)->draw_object(renderer, obj);
+
if (ddisp->show_cx_pts &&
obj->parent_layer != NULL && obj->parent_layer->connectable) {
for (i=0;i<obj->num_connections;i++) {
diff --git a/app/highlight.c b/app/highlight.c
index 8100369..61d56b1 100644
--- a/app/highlight.c
+++ b/app/highlight.c
@@ -40,15 +40,10 @@
* as it knows about the conversion.
*/
-static Color red = { 1.0, 0.0, 0.0 };
-
void
-highlight_object(DiaObject *obj, Color *col, Diagram *dia)
+highlight_object(DiaObject *obj, DiaHighlightType type, Diagram *dia)
{
- if (col)
- obj->highlight_color = col;
- else
- obj->highlight_color = &red;
+ data_highlight_add(dia->data, obj, type);
object_add_updates(obj, dia);
}
@@ -56,11 +51,8 @@ highlight_object(DiaObject *obj, Color *col, Diagram *dia)
void
highlight_object_off(DiaObject *obj, Diagram *dia)
{
- if (obj->highlight_color != NULL) {
- /* Must add updates first, so we get the border erased. */
- object_add_updates(obj, dia);
- obj->highlight_color = NULL;
- }
+ object_add_updates(obj, dia);
+ data_highlight_remove(dia->data, obj);
}
/** Resets all highlighting in this layer. Helper function for
diff --git a/app/highlight.h b/app/highlight.h
index 005bf06..8913de6 100644
--- a/app/highlight.h
+++ b/app/highlight.h
@@ -31,7 +31,7 @@
* If color is NULL, a standard #FF0000 color (red) is used.
* The exact method used for highlighting depends on the renderer.
*/
-void highlight_object(DiaObject *obj, Color *col, Diagram *dia);
+void highlight_object(DiaObject *obj, DiaHighlightType type, Diagram *dia);
/** Remove highlighting from an object.
*/
void highlight_object_off(DiaObject *obj, Diagram *dia);
diff --git a/app/modify_tool.c b/app/modify_tool.c
index 75525da..6c9af24 100644
--- a/app/modify_tool.c
+++ b/app/modify_tool.c
@@ -414,11 +414,6 @@ modify_move_already(ModifyTool *tool, DDisplay *ddisp, Point *to)
}
}
-/** Used for highlighting mainpoint connections. */
-static Color mainpoint_color = { 1.0, 0.8, 0.0 };
-/** Used for highlighting normal connections. */
-static Color cp_color = { 1.0, 0.0, 0.0 };
-
static void
modify_motion(ModifyTool *tool, GdkEventMotion *event,
DDisplay *ddisp)
@@ -535,14 +530,14 @@ modify_motion(ModifyTool *tool, GdkEventMotion *event,
connectionpoint =
object_find_connectpoint_display(ddisp, &to, tool->object, TRUE);
if (connectionpoint != NULL) {
- Color *hi_color;
+ DiaHighlightType type;
to = connectionpoint->pos;
if (connectionpoint->flags & CP_FLAGS_MAIN) {
- hi_color = &mainpoint_color;
+ type = DIA_HIGHLIGHT_CONNECTIONPOINT_MAIN;
} else {
- hi_color = &cp_color;
+ type = DIA_HIGHLIGHT_CONNECTIONPOINT;
}
- highlight_object(connectionpoint->object, hi_color, ddisp->diagram);
+ highlight_object(connectionpoint->object, type, ddisp->diagram);
ddisplay_set_all_cursor(get_cursor(CURSOR_CONNECT));
}
}
diff --git a/app/object_ops.c b/app/object_ops.c
index 7daddc1..0096408 100644
--- a/app/object_ops.c
+++ b/app/object_ops.c
@@ -35,7 +35,7 @@ object_add_updates(DiaObject *obj, Diagram *dia)
int i;
/* Bounding box */
- if (obj->highlight_color != NULL) {
+ if (data_object_get_highlight(dia->data,obj) != DIA_HIGHLIGHT_NONE) {
diagram_add_update_with_border(dia, &obj->bounding_box, 5);
} else {
diagram_add_update(dia, dia_object_get_enclosing_box (obj));
diff --git a/app/render_gdk.c b/app/render_gdk.c
index 26d1d84..50c7393 100644
--- a/app/render_gdk.c
+++ b/app/render_gdk.c
@@ -23,10 +23,20 @@
#include <string.h>
#include <gdk/gdk.h>
+#include "object.h"
#include "message.h"
#include "render_gdk.h"
#include "diagdkrenderer.h"
+
+/** Used for highlighting mainpoint connections. */
+static Color cp_main_color = { 1.0, 0.8, 0.0 };
+/** Used for highlighting normal connections. */
+static Color cp_color = { 1.0, 0.0, 0.0 };
+
+static Color text_edit_color = {1.0, 1.0, 0.0 };
+
+
static void clip_region_clear(DiaRenderer *renderer);
static void clip_region_add_rect(DiaRenderer *renderer,
Rectangle *rect);
@@ -49,6 +59,9 @@ static void set_size (DiaRenderer *renderer,
static void copy_to_window (DiaRenderer *renderer,
gpointer window,
int x, int y, int width, int height);
+static void draw_object_highlighted (DiaRenderer *renderer,
+ DiaObject *object,
+ DiaHighlightType type);
static void dia_gdk_renderer_iface_init (DiaInteractiveRendererInterface* iface)
{
@@ -59,6 +72,7 @@ static void dia_gdk_renderer_iface_init (DiaInteractiveRendererInterface* iface)
iface->fill_pixel_rect = fill_pixel_rect;
iface->copy_to_window = copy_to_window;
iface->set_size = set_size;
+ iface->draw_object_highlighted = draw_object_highlighted;
}
DiaRenderer *
@@ -246,3 +260,32 @@ fill_pixel_rect(DiaRenderer *object,
gdk_draw_rectangle (renderer->pixmap, gc, TRUE,
x, y, width, height);
}
+
+static void
+draw_object_highlighted (DiaRenderer *renderer, DiaObject *object, DiaHighlightType type)
+{
+ DiaGdkRenderer *gdk_rend = DIA_GDK_RENDERER(renderer);
+ Color *color = NULL;
+ switch (type) {
+ case DIA_HIGHLIGHT_CONNECTIONPOINT:
+ color = &cp_color;
+ break;
+ case DIA_HIGHLIGHT_CONNECTIONPOINT_MAIN:
+ color = &cp_main_color;
+ break;
+ case DIA_HIGHLIGHT_TEXT_EDIT:
+ color = &text_edit_color;
+ break;
+ case DIA_HIGHLIGHT_NONE:
+ color = NULL;
+ break;
+ }
+ if( color ) {
+ gdk_rend->highlight_color = color;
+ object->ops->draw(object, renderer);
+ gdk_rend->highlight_color = NULL;
+ }
+
+ object->ops->draw(object, renderer);
+}
+
diff --git a/app/textedit.c b/app/textedit.c
index 64ac322..2df962f 100644
--- a/app/textedit.c
+++ b/app/textedit.c
@@ -124,14 +124,12 @@ textedit_exit(DDisplay *ddisp)
static void
textedit_begin_edit(DDisplay *ddisp, Focus *focus)
{
- Color *focus_col = color_new_rgb(1.0, 1.0, 0.0);
-
g_assert(dia_object_is_selected(focus_get_object(focus)));
if (!textedit_mode(ddisp)) {
textedit_enter(ddisp);
}
ddisplay_set_active_focus(ddisp, focus);
- highlight_object(focus->obj, focus_col, ddisp->diagram);
+ highlight_object(focus->obj, DIA_HIGHLIGHT_TEXT_EDIT, ddisp->diagram);
object_add_updates(focus->obj, ddisp->diagram);
/* Undo not quite ready yet.
undo_push_change(ddisp->diagram->undo, text_edit_create_change(focus->text));
diff --git a/lib/diagdkrenderer.c b/lib/diagdkrenderer.c
index 6ccf42f..1e15dde 100644
--- a/lib/diagdkrenderer.c
+++ b/lib/diagdkrenderer.c
@@ -46,6 +46,7 @@
#include <pango/pangoft2.h>
#endif
+
static int get_width_pixels (DiaRenderer *);
static int get_height_pixels (DiaRenderer *);
@@ -1056,16 +1057,10 @@ fill_rounded_rect (DiaRenderer *self,
fill_rect (self, ul_corner, lr_corner, color);
}
+
static void
draw_object (DiaRenderer *renderer, DiaObject *object)
{
- if (renderer->is_interactive &&
- object->highlight_color != NULL) {
- DiaGdkRenderer *gdk_rend = DIA_GDK_RENDERER(renderer);
- gdk_rend->highlight_color = object->highlight_color;
- object->ops->draw(object, renderer);
- gdk_rend->highlight_color = NULL;
- }
object->ops->draw(object, renderer);
}
diff --git a/lib/diagramdata.c b/lib/diagramdata.c
index 43f10aa..062bc70 100644
--- a/lib/diagramdata.c
+++ b/lib/diagramdata.c
@@ -45,6 +45,11 @@ enum {
LAST_SIGNAL
};
+typedef struct {
+ DiaObject *obj;
+ DiaHighlightType type;
+} ObjectHighlight;
+
static guint diagram_data_signals[LAST_SIGNAL] = { 0, };
static gpointer parent_class = NULL;
@@ -117,6 +122,8 @@ diagram_data_init(DiagramData *data)
data->selected_count_private = 0;
data->selected = NULL;
+
+ data->highlighted = NULL;
data->is_compressed = compress; /* Overridden by doc */
@@ -327,6 +334,53 @@ data_delete_layer(DiagramData *data, Layer *layer)
}
}
+static ObjectHighlight *
+find_object_highlight(GList *list, DiaObject *obj)
+{
+ ObjectHighlight *oh=NULL;
+ while(list) {
+ oh = (ObjectHighlight*)list->data;
+ if (oh && oh->obj == obj) {
+ return oh;
+ }
+ list = g_list_next(list);
+ }
+ return NULL;
+}
+
+void
+data_highlight_add(DiagramData *data, DiaObject *obj, DiaHighlightType type)
+{
+ ObjectHighlight *oh;
+ if (find_object_highlight (data->highlighted, obj))
+ return; /* should this be an error?`*/
+ oh = g_malloc(sizeof(ObjectHighlight));
+ oh->obj = obj;
+ oh->type = type;
+ data->highlighted = g_list_prepend(data->highlighted, oh);
+}
+
+void
+data_highlight_remove(DiagramData *data, DiaObject *obj)
+{
+ ObjectHighlight *oh;
+ if (!(oh = find_object_highlight (data->highlighted, obj)))
+ return; /* should this be an error?`*/
+ data->highlighted = g_list_remove(data->highlighted, oh);
+ g_free(oh);
+}
+
+DiaHighlightType
+data_object_get_highlight(DiagramData *data, DiaObject *obj)
+{
+ ObjectHighlight *oh;
+ DiaHighlightType type = DIA_HIGHLIGHT_NONE;
+ if (oh = find_object_highlight (data->highlighted, obj)) {
+ type = oh->type;
+ }
+ return type;
+}
+
/** Select an object in a diagram. Note that this does not unselect other
* objects currently selected in the diagram.
* @param data The diagram to select in.
diff --git a/lib/diagramdata.h b/lib/diagramdata.h
index eb37f8b..3e3c296 100644
--- a/lib/diagramdata.h
+++ b/lib/diagramdata.h
@@ -82,6 +82,9 @@ struct _DiagramData {
/** The focus (from text_edits) that's currently being edited, if any.
* Updated by focus.c */
Focus *active_text_edit;
+
+ GList *highlighted; /*!< List of objects that are highlighted */
+
};
/**
@@ -120,6 +123,13 @@ struct _Layer {
layer_get_parent_diagram() */
};
+typedef enum {
+ DIA_HIGHLIGHT_NONE,
+ DIA_HIGHLIGHT_CONNECTIONPOINT,
+ DIA_HIGHLIGHT_CONNECTIONPOINT_MAIN,
+ DIA_HIGHLIGHT_TEXT_EDIT
+} DiaHighlightType;
+
Layer *new_layer (char *name, DiagramData *parent);
void layer_destroy(Layer *layer);
@@ -134,6 +144,10 @@ int data_layer_get_index (const DiagramData *data, const Layer *layer);
int data_layer_count(const DiagramData *data);
Layer *data_layer_get_nth (const DiagramData *data, guint index);
+void data_highlight_add(DiagramData *data, DiaObject *obj, DiaHighlightType type);
+void data_highlight_remove(DiagramData *data, DiaObject *obj);
+DiaHighlightType data_object_get_highlight(DiagramData *data, DiaObject *obj);
+
void data_select(DiagramData *data, DiaObject *obj);
void data_unselect(DiagramData *data, DiaObject *obj);
void data_remove_all_selected(DiagramData *data);
diff --git a/lib/diainteractiverenderer.c b/lib/diainteractiverenderer.c
index 7d13209..0419797 100644
--- a/lib/diainteractiverenderer.c
+++ b/lib/diainteractiverenderer.c
@@ -33,6 +33,7 @@ dia_interactive_renderer_iface_init (DiaInteractiveRendererInterface *iface)
iface->fill_pixel_rect = NULL;
iface->copy_to_window = NULL;
iface->set_size = NULL;
+ iface->draw_object_highlighted = NULL;
}
GType
diff --git a/lib/diarenderer.h b/lib/diarenderer.h
index a903bfd..22fda68 100644
--- a/lib/diarenderer.h
+++ b/lib/diarenderer.h
@@ -27,6 +27,8 @@
#include "geometry.h"
#include "font.h" /* not strictly needed by this header, but needed in almost any plug-in/ */
+#include "diagramdata.h"
+
G_BEGIN_DECLS
/*! GObject boiler plate, create runtime information */
@@ -289,6 +291,10 @@ struct _DiaInteractiveRendererInterface
void (*copy_to_window) (DiaRenderer *renderer,
gpointer window,
int x, int y, int width, int height);
+
+ void (*draw_object_highlighted) (DiaRenderer *renderer,
+ DiaObject *object,
+ DiaHighlightType type);
};
GType dia_interactive_renderer_interface_get_type (void) G_GNUC_CONST;
diff --git a/lib/libdia.def b/lib/libdia.def
index b6b9db8..e417c8b 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -150,6 +150,9 @@ EXPORTS
data_foreach_object
data_get_sorted_selected
data_get_sorted_selected_remove
+ data_highlight_add
+ data_highlight_remove
+ data_object_get_highlight
data_int
data_layer_count
data_layer_get_index
diff --git a/lib/object.h b/lib/object.h
index 0ad570b..1fbdb4c 100644
--- a/lib/object.h
+++ b/lib/object.h
@@ -489,9 +489,6 @@ struct _DiaObject {
GList *children; /*!< In case this object is a parent of other object the children are listed here */
gint flags; /*!< Various flags that can be set for this object, see defines above */
- Color *highlight_color; /*!< The color that this object is currently
- highlighted with, or NULL if it is not
- highlighted. */
/** The area that contains all parts rendered interactively, so includes
* handles, bezier controllers etc. Despite historical difference, this
* should not be accessed directly, but through dia_object_get_bounding_box().
diff --git a/lib/plug-ins.h b/lib/plug-ins.h
index a2ec0ce..902901f 100644
--- a/lib/plug-ins.h
+++ b/lib/plug-ins.h
@@ -48,7 +48,7 @@ G_BEGIN_DECLS
* The list is by no means complete. If in doubt about your change
* please ask on dia-list or alternative increment ;-) --hb
*/
-#define DIA_PLUGIN_API_VERSION 13
+#define DIA_PLUGIN_API_VERSION 14
typedef enum {
DIA_PLUGIN_INIT_OK,
diff --git a/plug-ins/libart/dialibartrenderer.c b/plug-ins/libart/dialibartrenderer.c
index 5f30962..5f12d46 100644
--- a/plug-ins/libart/dialibartrenderer.c
+++ b/plug-ins/libart/dialibartrenderer.c
@@ -1329,13 +1329,6 @@ draw_image(DiaRenderer *self,
static void
draw_object (DiaRenderer *renderer, DiaObject *object)
{
- if (renderer->is_interactive &&
- object->highlight_color != NULL) {
- DiaLibartRenderer *libart_rend = DIA_LIBART_RENDERER(renderer);
- libart_rend->highlight_color = object->highlight_color;
- object->ops->draw(object, renderer);
- libart_rend->highlight_color = NULL;
- }
object->ops->draw(object, renderer);
}
diff --git a/plug-ins/libart/render_libart.c b/plug-ins/libart/render_libart.c
index e34a2f5..bcf7c3c 100644
--- a/plug-ins/libart/render_libart.c
+++ b/plug-ins/libart/render_libart.c
@@ -26,11 +26,20 @@
#ifdef HAVE_LIBART
+#include "object.h"
#include "dialibartrenderer.h"
#include <libart_lgpl/art_rgb.h>
#include "font.h"
#include "color.h"
+/** Used for highlighting mainpoint connections. */
+static Color cp_main_color = { 1.0, 0.8, 0.0 };
+/** Used for highlighting normal connections. */
+static Color cp_color = { 1.0, 0.0, 0.0 };
+
+static Color text_edit_color = {1.0, 1.0, 0.0 };
+
+
static void clip_region_clear(DiaRenderer *self);
static void clip_region_add_rect(DiaRenderer *self,
Rectangle *rect);
@@ -51,6 +60,9 @@ static void set_size(DiaRenderer *self, gpointer window,
int width, int height);
static void copy_to_window (DiaRenderer *self, gpointer window,
int x, int y, int width, int height);
+static void draw_object_highlighted (DiaRenderer *renderer,
+ DiaObject *object,
+ DiaHighlightType type);
void
@@ -63,6 +75,7 @@ dia_libart_renderer_iface_init (DiaInteractiveRendererInterface* iface)
iface->fill_pixel_rect = fill_pixel_rect;
iface->copy_to_window = copy_to_window;
iface->set_size = set_size;
+ iface->draw_object_highlighted = draw_object_highlighted;
}
@@ -460,6 +473,35 @@ fill_pixel_rect(DiaRenderer *self,
}
}
+
+static void
+draw_object_highlighted (DiaRenderer *renderer, DiaObject *object, DiaHighlightType type)
+{
+ DiaLibartRenderer *libart_rend = DIA_LIBART_RENDERER(renderer);
+ Color *color = NULL;
+ switch (type) {
+ case DIA_HIGHLIGHT_CONNECTIONPOINT:
+ color = &cp_color;
+ break;
+ case DIA_HIGHLIGHT_CONNECTIONPOINT_MAIN:
+ color = &cp_main_color;
+ break;
+ case DIA_HIGHLIGHT_TEXT_EDIT:
+ color = &text_edit_color;
+ break;
+ case DIA_HIGHLIGHT_NONE:
+ color = NULL;
+ break;
+ }
+ if( color ) {
+ libart_rend->highlight_color = color;
+ object->ops->draw(object, renderer);
+ libart_rend->highlight_color = NULL;
+ }
+
+ object->ops->draw(object, renderer);
+}
+
#else
DiaRenderer *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]