[dia] Initial implementation of diagram-as-element (embedding diagrams)
- From: Hans Breuer <hans src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dia] Initial implementation of diagram-as-element (embedding diagrams)
- Date: Sat, 3 Oct 2009 13:59:53 +0000 (UTC)
commit fbe3937bb67c0cb450f54f44ed176e8a90bfcd27
Author: Hans Breuer <hans breuer org>
Date: Sat Oct 3 15:58:13 2009 +0200
Initial implementation of diagram-as-element (embedding diagrams)
TODO:
- extend the renderer interface to get rid of the extra DiaImage,
at least for some renderers (DiaRenderer::set_matrix?)
- the image gets updated too often, something wrong with mtime check?
- make diagrams directly selecteable in the properties dialog file entry
- allow to open the diagram stand-alone by context menu
- make new object available in the Misc sheet
objects/Misc/Makefile.am | 2 +
objects/Misc/diagram_as_object.c | 319 +++++++++++++++++++++++++++
objects/Misc/libmisc.c | 2 +
objects/Misc/pixmaps/diagram_as_element.xpm | 231 +++++++++++++++++++
objects/makefile.msc | 1 +
5 files changed, 555 insertions(+), 0 deletions(-)
---
diff --git a/objects/Misc/Makefile.am b/objects/Misc/Makefile.am
index f09b34f..0dd48ff 100644
--- a/objects/Misc/Makefile.am
+++ b/objects/Misc/Makefile.am
@@ -4,6 +4,7 @@ pkglib_LTLIBRARIES = libmisc_objects.la
libmisc_objects_la_SOURCES = \
libmisc.c \
analog_clock.c \
+ diagram_as_object.c \
grid_object.c \
measure.c \
tree.c
@@ -16,6 +17,7 @@ INCLUDES = -I$(top_srcdir)/intl -I$(srcdir)/../../lib \
EXTRA_DIST = \
pixmaps/analog_clock.xpm \
+ pixmaps/diagram_as_element.xpm \
pixmaps/grid_object.xpm \
pixmaps/measure.xpm \
pixmaps/newgroup.xpm \
diff --git a/objects/Misc/diagram_as_object.c b/objects/Misc/diagram_as_object.c
new file mode 100644
index 0000000..0dd5ada
--- /dev/null
+++ b/objects/Misc/diagram_as_object.c
@@ -0,0 +1,319 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * diagram_as_object.c -- embedding diagrams
+ * Copyright (C) 2009 Hans Breuer, <Hans Breuer Org>
+ *
+ * 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
+ * MERCHANTABILITY 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include <time.h>
+#ifdef HAVE_UTIME_H
+# include <utime.h>
+#else
+# include <sys/utime.h>
+#endif
+#include <glib.h>
+#ifdef G_OS_WIN32
+#include <io.h> /* close */
+#endif
+#include <glib/gstdio.h>
+
+#include "object.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "properties.h"
+#include "boundingbox.h"
+#include "element.h"
+#include "diagramdata.h"
+#include "filter.h"
+#include "intl.h"
+
+#include "filter.h"
+#include "dia_image.h"
+
+#include "pixmaps/diagram_as_element.xpm"
+
+#define DEFAULT_WIDTH 2.0
+#define DEFAULT_HEIGHT 2.0
+#define NUM_CONNECTIONS 9
+/* Object definition */
+typedef struct _DiagramAsElement {
+ Element element;
+
+ ConnectionPoint connections[NUM_CONNECTIONS];
+
+ Color border_color;
+ real border_line_width;
+ Color inner_color;
+ gboolean show_background;
+
+ gchar *filename;
+ time_t mtime;
+ DiagramData *data;
+
+ /* for indirect rendering*/
+ DiaImage *image;
+
+ real scale;
+} DiagramAsElement;
+
+static DiaObject *
+_dae_create (Point *startpoint,
+ void *user_data,
+ Handle **handle1,
+ Handle **handle2);
+
+static ObjectTypeOps _dae_type_ops =
+{
+ (CreateFunc) _dae_create,
+ (LoadFunc) object_load_using_properties,
+ (SaveFunc) object_save_using_properties,
+ (GetDefaultsFunc) NULL,
+ (ApplyDefaultsFunc) NULL
+};
+
+DiaObjectType diagram_as_element_type =
+{
+ "Misc - Diagram", /* name */
+ 0, /* version */
+ (char **) diagram_as_element_xpm, /* pixmap */
+
+ &_dae_type_ops /* ops */
+};
+
+static void _dae_update_data (DiagramAsElement *dae);
+
+static PropDescription _dae_props[] = {
+ ELEMENT_COMMON_PROPERTIES,
+ PROP_STD_LINE_WIDTH,
+ PROP_STD_LINE_COLOUR,
+ PROP_STD_FILL_COLOUR,
+ PROP_STD_SHOW_BACKGROUND,
+ { "diagram_file", PROP_TYPE_FILE, PROP_FLAG_VISIBLE,
+ N_("Diagram file"), NULL, NULL},
+ PROP_DESC_END
+};
+static PropDescription *
+_dae_describe_props(DiagramAsElement *dae)
+{
+ if (_dae_props[0].quark == 0)
+ prop_desc_list_calculate_quarks(_dae_props);
+ return _dae_props;
+}
+static PropOffset _dae_offsets[] = {
+ ELEMENT_COMMON_PROPERTIES_OFFSETS,
+ { PROP_STDNAME_LINE_WIDTH, PROP_STDTYPE_LINE_WIDTH, offsetof(DiagramAsElement, border_line_width) },
+ { "line_colour", PROP_TYPE_COLOUR, offsetof(DiagramAsElement, border_color) },
+ { "fill_colour", PROP_TYPE_COLOUR, offsetof(DiagramAsElement, inner_color) },
+ { "show_background", PROP_TYPE_BOOL,offsetof(DiagramAsElement, show_background) },
+ { "diagram_file", PROP_TYPE_FILE, offsetof(DiagramAsElement, filename) },
+ { NULL }
+};
+static void
+_dae_get_props(DiagramAsElement *dae, GPtrArray *props)
+{
+ object_get_props_from_offsets(&dae->element.object, _dae_offsets, props);
+}
+static void
+_dae_set_props(DiagramAsElement *dae, GPtrArray *props)
+{
+ object_set_props_from_offsets(&dae->element.object, _dae_offsets, props);
+ _dae_update_data(dae);
+}
+static real
+_dae_distance_from(DiagramAsElement *dae, Point *point)
+{
+ DiaObject *obj = &dae->element.object;
+ return distance_rectangle_point(&obj->bounding_box, point);
+}
+static void
+_dae_select(DiagramAsElement *dae, Point *clicked_point, DiaRenderer *interactive_renderer)
+{
+ element_update_handles(&dae->element);
+}
+static ObjectChange*
+_dae_move_handle(DiagramAsElement *dae, Handle *handle,
+ Point *to, ConnectionPoint *cp,
+ HandleMoveReason reason, ModifierKeys modifiers)
+{
+ Element *elem = &dae->element;
+ real aspect = elem->width / elem->height;
+
+ g_assert(handle!=NULL);
+ g_assert(to!=NULL);
+
+ element_move_handle_aspect(&dae->element, handle->id, to, /*cp, reason, modifiers,*/ aspect);
+ _dae_update_data(dae);
+
+ return NULL;
+}
+static ObjectChange*
+_dae_move(DiagramAsElement *dae, Point *to)
+{
+ dae->element.corner = *to;
+ _dae_update_data(dae);
+
+ return NULL;
+}
+_dae_draw(DiagramAsElement *dae, DiaRenderer *renderer)
+{
+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+ Element *elem = &dae->element;
+
+ if (!dae->data) {
+ /* just draw the box */
+ Point lower_right = {
+ elem->corner.x + elem->width,
+ elem->corner.y + elem->height
+ };
+
+ renderer_ops->draw_rect(renderer,&elem->corner, &lower_right,
+ &dae->border_color);
+
+ } else {
+ if (FALSE) {
+ /* if the renderer supports transformations ... */
+ /* temporary messing with it (not enough) */
+ dae->data->paper.scaling *= dae->scale;
+ data_render (dae->data, DIA_RENDERER (renderer), NULL, NULL, NULL);
+ dae->data->paper.scaling /= dae->scale;
+ } else {
+ /* we have to render to an image and draw that */
+ if (!dae->image) { /* lazy creation */
+ gchar *imgfname = NULL;
+ gint fd = g_file_open_tmp ("diagram-as-elementXXXXXX.png", &imgfname, NULL);
+ if (fd != -1) {
+ DiaExportFilter *ef = filter_guess_export_filter (imgfname);
+
+ close(fd);
+ if (ef) {
+ ef->export_func (dae->data, imgfname, dae->filename, ef->user_data);
+ /* TODO: change export_func to return success or GError* */
+ dae->image = dia_image_load (imgfname);
+ }
+ g_free (imgfname);
+ }
+ }
+ if (dae->image)
+ renderer_ops->draw_image (renderer, &elem->corner, elem->width, elem->height, dae->image);
+ }
+ }
+}
+static void
+_dae_update_data(DiagramAsElement *dae)
+{
+ struct utimbuf utbuf;
+ Element *elem = &dae->element;
+
+ if ( strlen(dae->filename)
+ && g_utime(dae->filename, &utbuf) == 0
+ && dae->mtime != utbuf.modtime) {
+ DiaImportFilter *inf;
+
+ if (dae->data)
+ g_object_unref(dae->data);
+ dae->data = g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL);
+
+ inf = filter_guess_import_filter(dae->filename);
+ if (inf && inf->import_func(dae->filename, dae->data, inf->user_data)) {
+ dae->scale = dae->element.width / (dae->data->extents.right - dae->data->extents.left);
+ dae->element.height = (dae->data->extents.bottom - dae->data->extents.top) * dae->scale;
+ dae->mtime = utbuf.modtime;
+ }
+ /* invalidate possibly cached image */
+ if (dae->image) {
+ g_object_unref (dae->image);
+ dae->image = NULL;
+ }
+ }
+ /* fixme - fit the scale to draw the diagram in elements size ?*/
+ if (dae->scale)
+ dae->scale = dae->element.width / (dae->data->extents.right - dae->data->extents.left);
+
+ elem->extra_spacing.border_trans = dae->border_line_width/2.0;
+ element_update_boundingbox(elem);
+ element_update_handles(elem);
+}
+static void
+_dae_destroy(DiagramAsElement *dae)
+{
+ if (dae->data)
+ g_object_unref(dae->data);
+
+ g_free(dae->filename);
+
+ element_destroy(&dae->element);
+}
+
+static ObjectOps _dae_ops = {
+ (DestroyFunc) _dae_destroy,
+ (DrawFunc) _dae_draw,
+ (DistanceFunc) _dae_distance_from,
+ (SelectFunc) _dae_select,
+ (CopyFunc) object_copy_using_properties,
+ (MoveFunc) _dae_move,
+ (MoveHandleFunc) _dae_move_handle,
+ (GetPropertiesFunc) object_create_props_dialog,
+ (ApplyPropertiesDialogFunc) object_apply_props_from_dialog,
+ (ObjectMenuFunc) NULL,
+ (DescribePropsFunc) _dae_describe_props,
+ (GetPropsFunc) _dae_get_props,
+ (SetPropsFunc) _dae_set_props,
+ (TextEditFunc) 0,
+ (ApplyPropertiesListFunc) object_apply_props,
+};
+
+/*! factory function */
+static DiaObject *
+_dae_create (Point *startpoint,
+ void *user_data,
+ Handle **handle1,
+ Handle **handle2)
+{
+ DiagramAsElement *dae;
+ Element *elem;
+ DiaObject *obj;
+ int i;
+
+ dae = g_new0(DiagramAsElement, 1);
+
+ obj = &dae->element.object;
+ obj->type = &diagram_as_element_type;
+ obj->ops = &_dae_ops;
+
+ elem = &dae->element;
+ elem->corner = *startpoint;
+ elem->width = DEFAULT_WIDTH;
+ elem->height = DEFAULT_HEIGHT;
+
+ element_init(elem, 8, NUM_CONNECTIONS);
+
+ for (i=0; i<NUM_CONNECTIONS; i++) {
+ obj->connections[i] = &dae->connections[i];
+ dae->connections[i].object = obj;
+ dae->connections[i].connected = NULL;
+ }
+ dae->connections[8].flags = CP_FLAGS_MAIN;
+
+ dae->filename = g_strdup("");
+
+ _dae_update_data(dae);
+
+ *handle1 = NULL;
+ *handle2 = obj->handles[7];
+ return &dae->element.object;
+}
diff --git a/objects/Misc/libmisc.c b/objects/Misc/libmisc.c
index 981f52c..e72ea9a 100644
--- a/objects/Misc/libmisc.c
+++ b/objects/Misc/libmisc.c
@@ -32,6 +32,7 @@ extern DiaObjectType analog_clock_type;
extern DiaObjectType grid_object_type;
extern DiaObjectType tree_type;
extern DiaObjectType measure_type;
+extern DiaObjectType diagram_as_element_type;
DIA_PLUGIN_CHECK_INIT
@@ -46,6 +47,7 @@ dia_plugin_init(PluginInfo *info)
object_register_type(&grid_object_type);
object_register_type(&tree_type);
object_register_type(&measure_type);
+ object_register_type(&diagram_as_element_type);
return DIA_PLUGIN_INIT_OK;
}
diff --git a/objects/Misc/pixmaps/diagram_as_element.xpm b/objects/Misc/pixmaps/diagram_as_element.xpm
new file mode 100644
index 0000000..11a8545
--- /dev/null
+++ b/objects/Misc/pixmaps/diagram_as_element.xpm
@@ -0,0 +1,231 @@
+/* XPM */
+static char * diagram_as_element_xpm[] = {
+"22 22 206 2",
+" c None",
+". c #4E4E4E",
+"+ c #5B5B5B",
+"@ c #2D2D2D",
+"# c #3D3D3D",
+"$ c #5D5D5D",
+"% c #7E7E7E",
+"& c #9C9C9B",
+"* c #8D8D8D",
+"= c #3C3C3B",
+"- c #474747",
+"; c #555555",
+"> c #6B6B6B",
+", c #898988",
+"' c #969696",
+") c #A5A5A5",
+"! c #B0B0AF",
+"~ c #A5A5A4",
+"{ c #5D5D5C",
+"] c #717171",
+"^ c #878787",
+"/ c #8E8E8E",
+"( c #A2A2A1",
+"_ c #AEAEAD",
+": c #B3B3B3",
+"< c #B1B1B1",
+"[ c #ADADAC",
+"} c #838383",
+"| c #606060",
+"1 c #B5B5B5",
+"2 c #A2A2A2",
+"3 c #737373",
+"4 c #5C6C5C",
+"5 c #60755F",
+"6 c #969796",
+"7 c #AFAFAF",
+"8 c #AEAEAE",
+"9 c #ADADAD",
+"0 c #9D9D9D",
+"a c #565656",
+"b c #888888",
+"c c #BBBBBB",
+"d c #5E615E",
+"e c #1D751D",
+"f c #1A8E1A",
+"g c #7B847B",
+"h c #ABABAB",
+"i c #ACACAC",
+"j c #ABABAA",
+"k c #272727",
+"l c #727272",
+"m c #7A7A79",
+"n c #6A6A6A",
+"o c #636563",
+"p c #296629",
+"q c #267726",
+"r c #7B827A",
+"s c #A8A8A8",
+"t c #9E9E9E",
+"u c #515151",
+"v c #5C5C5C",
+"w c #7F7F7E",
+"x c #7C7C7C",
+"y c #646463",
+"z c #393F38",
+"A c #3B433B",
+"B c #5F605E",
+"C c #706F6E",
+"D c #727171",
+"E c #747474",
+"F c #8A8A8A",
+"G c #A8A8A7",
+"H c #AFAFAE",
+"I c #808080",
+"J c #686868",
+"K c #858585",
+"L c #595959",
+"M c #606160",
+"N c #7C7979",
+"O c #8A5F5F",
+"P c #875E5E",
+"Q c #7A7878",
+"R c #5F5F5F",
+"S c #6E6E6E",
+"T c #A7A7A7",
+"U c #B9B9B8",
+"V c #B8B8B8",
+"W c #8D8E8D",
+"X c #B9A8A7",
+"Y c #D15A57",
+"Z c #C95656",
+"` c #AB9D9D",
+" . c #3F3F3F",
+".. c #7B7B7B",
+"+. c #B7B7B7",
+"@. c #898989",
+"#. c #5E5E5E",
+"$. c #BEBEBE",
+"%. c #CACACA",
+"&. c #C5C5C4",
+"*. c #8C8C8C",
+"=. c #6D6B6B",
+"-. c #896665",
+";. c #884746",
+">. c #864645",
+",. c #7F5C5C",
+"'. c #747171",
+"). c #3E3E3E",
+"!. c #5A5A5A",
+"~. c #BCBCBC",
+"{. c #B3B3B2",
+"]. c #666666",
+"^. c #444444",
+"/. c #BABABA",
+"(. c #DADADA",
+"_. c #D6D6D6",
+":. c #999999",
+"<. c #7F6363",
+"[. c #A03736",
+"}. c #934C4B",
+"|. c #984E4B",
+"1. c #992F2E",
+"2. c #775D5C",
+"3. c #383837",
+"4. c #656565",
+"5. c #C2C2C2",
+"6. c #C5C5C5",
+"7. c #9A9A9A",
+"8. c #434341",
+"9. c #373737",
+"0. c #E7E7E7",
+"a. c #E1E1E1",
+"b. c #AA8B8B",
+"c. c #D47878",
+"d. c #D07778",
+"e. c #D07777",
+"f. c #C86B6A",
+"g. c #8D6D6D",
+"h. c #474646",
+"i. c #CBCBCB",
+"j. c #CBCBCA",
+"k. c #797978",
+"l. c #959595",
+"m. c #E9E9E9",
+"n. c #BFBFBF",
+"o. c #777777",
+"p. c #777676",
+"q. c #94908F",
+"r. c #969292",
+"s. c #8F8B8B",
+"t. c #6F6D6D",
+"u. c #868685",
+"v. c #D1D1D0",
+"w. c #CFCFCE",
+"x. c #C6C6C6",
+"y. c #9B9B9A",
+"z. c #3C3C3C",
+"A. c #E5E5E5",
+"B. c #929292",
+"C. c #989898",
+"D. c #D5D5D5",
+"E. c #D4D4D4",
+"F. c #C3C3C3",
+"G. c #919191",
+"H. c #535353",
+"I. c #D7D7D7",
+"J. c #E4E4E4",
+"K. c #949494",
+"L. c #DCDCDC",
+"M. c #E3E3E2",
+"N. c #E0E0E0",
+"O. c #E1E1E0",
+"P. c #DEDEDD",
+"Q. c #CCCCCC",
+"R. c #222222",
+"S. c #070707",
+"T. c #FAFAFA",
+"U. c #E6E6E6",
+"V. c #F4F4F4",
+"W. c #F3F3F3",
+"X. c #EFEFEF",
+"Y. c #D2D2D2",
+"Z. c #636363",
+"`. c #262626",
+" + c #080808",
+".+ c #000000",
+"++ c #FFFFFF",
+"@+ c #FEFEFE",
+"#+ c #F9F9F9",
+"$+ c #EDEDED",
+"%+ c #CFCFCF",
+"&+ c #575756",
+"*+ c #616161",
+"=+ c #DFDFDF",
+"-+ c #E8E8E8",
+";+ c #C0C0C0",
+">+ c #868686",
+",+ c #484848",
+"'+ c #181818",
+")+ c #050505",
+"!+ c #313131",
+"~+ c #0F0F0F",
+"{+ c #040404",
+"]+ c #141414",
+"^+ c #121212",
+"/+ c #0B0B0B",
+" ",
+" . + ",
+" @ # $ % & * = ",
+" - ; > , ' ) ! ! ~ { ",
+" ] ^ / ( _ : : < ! [ } ",
+" | 1 2 3 4 5 6 ! 7 8 9 0 a ",
+" b c ' d e f g h 8 [ i j % ",
+" k l m n o p q r s i h i 8 t u ",
+" v w x y z A B C D E F G H I ",
+" J 2 0 K L M N O P Q R S T ) a ",
+" S U V : K W X Y Z ` } + ",
+" #.$.%.&.*.=.-.;.>.,.'.).!.~.{.]. ",
+" ^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8. ",
+" 9.< 0.a.) b.c.d.e.f.g.h./ i.j.c k. ",
+" l.m.n.o.p.q.q.r.s.t.u.c v.w.x.y.z. ",
+" E A./.].J B.' C.0 7 %.D.E.F.G.H. ",
+" R I.J.K.0 L.A.M.N.O.P.Q.( R R.S. ",
+" +.T.U.0.V.W.X.A.Y.T Z.`. +.+.+ ",
+" * V ++ +#+$+%+' &+`. +.+.+.+.+ ",
+" *+=+#+-+;+>+,+'+)+.+.+.+.+ ",
+" * t > !+~+{+.+.+ ",
+" ]+^+/+ "};
diff --git a/objects/makefile.msc b/objects/makefile.msc
index 719368b..cf64853 100644
--- a/objects/makefile.msc
+++ b/objects/makefile.msc
@@ -202,6 +202,7 @@ OBJECTS = \
grid_object.obj \
measure.obj \
tree.obj \
+ diagram_as_object.obj \
libmisc.obj
!ENDIF
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]