dia r4104 - in trunk: . app lib objects/SISSI objects/standard plug-ins/python



Author: hans
Date: Sat Aug  9 12:28:03 2008
New Revision: 4104
URL: http://svn.gnome.org/viewvc/dia?rev=4104&view=rev

Log:
2008-08-09  Hans Breuer  <hans breuer org>

	* app/display.[hc] app/dia.def : factor out ddisplay_show_all() from
	* app/commands.c : ... view_show_all_callback ...
	to make the functions signature more appropriate to be called by 
	a plug-in

	* plug-ins/python/autolayoutforce.py : my playground for Fred Morcos'
	'force based autolayout' algorithm, see:
	http://mail.gnome.org/archives/dia-list/2008-August/msg00030.html
	* plug-ins/python/Makefile.am : to EXTRA_DIST (not to be installed)

	* lib/bezier_conn.c lib/bezier_shape.c : use g_new0 for Handle 
	allocation to ensure they pointers are not referencing random objects
	
	* lib/connectionpoint.c(connpoint_is_autogap): an unconnected 
	ConnectionPoint can not matter for autogap
	* lib/bezier.c : allows to remove the hack to disable the bounding box
	calculation in bezier_load()

	* lib/connectionpoint.h : turned ConnectionPoint(Flags|Dir) to enums,
	helps documentation and graphical debuggers
	
	* lib/geometry.h(Rectangle): swap top/left and bottom/right to a more 
	usual order (after debugging quite some bounding box code) finally 
	because of it's use in bezierline_update_data()
	* lib/plug-ins.h : increment DIA_PLUGIN_API_VERSION

	* lib/libdia.def : rectangle_in_rectangle export

	* object/SISSI/sissi.c : don't try to load an image file from NULL 
	filename; some formatting near that.



Added:
   trunk/plug-ins/python/autolayoutforce.py   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/app/commands.c
   trunk/app/dia.def
   trunk/app/display.c
   trunk/app/display.h
   trunk/lib/bezier_conn.c
   trunk/lib/beziershape.c
   trunk/lib/boundingbox.c
   trunk/lib/connectionpoint.c
   trunk/lib/connectionpoint.h
   trunk/lib/geometry.h
   trunk/lib/libdia.def
   trunk/lib/plug-ins.h
   trunk/objects/SISSI/sissi.c
   trunk/objects/standard/bezier.c

Modified: trunk/app/commands.c
==============================================================================
--- trunk/app/commands.c	(original)
+++ trunk/app/commands.c	Sat Aug  9 12:28:03 2008
@@ -955,50 +955,11 @@
 view_show_all_callback (GtkAction *action)
 {
   DDisplay *ddisp;
-  Diagram *dia;
-  real magnify_x, magnify_y;
-  int width, height;
-  Point middle;
 
   ddisp = ddisplay_active();
   if (!ddisp) return;
-  dia = ddisp->diagram;
-
-  width = dia_renderer_get_width_pixels (ddisp->renderer);
-  height = dia_renderer_get_height_pixels (ddisp->renderer);
-
-  /* if there is something selected show that instead of all exisiting objects */
-  if (dia->data->selected) {
-    GList *list = dia->data->selected;
-    Rectangle extents = *dia_object_get_enclosing_box ((DiaObject*)list->data);
-    list = g_list_next(list);
-    while (list) {
-      DiaObject *obj = (DiaObject *)list->data;
-      rectangle_union(&extents, dia_object_get_enclosing_box (obj));
-      list = g_list_next(list);
-    }
-    magnify_x = (real)width / (extents.right - extents.left) / ddisp->zoom_factor;
-    magnify_y = (real)height / (extents.bottom - extents.top) / ddisp->zoom_factor;
-    middle.x = extents.left + (extents.right - extents.left) / 2.0;
-    middle.y = extents.top + (extents.bottom - extents.top) / 2.0;
-  } else {
-    magnify_x = (real)width /
-      (dia->data->extents.right - dia->data->extents.left) / ddisp->zoom_factor;
-    magnify_y = (real)height /
-      (dia->data->extents.bottom - dia->data->extents.top) / ddisp->zoom_factor;
-
-    middle.x = dia->data->extents.left +
-      (dia->data->extents.right - dia->data->extents.left) / 2.0;
-    middle.y = dia->data->extents.top +
-      (dia->data->extents.bottom - dia->data->extents.top) / 2.0;
-  }
-
-  ddisplay_zoom (ddisp, &middle, 
-		 ((magnify_x<magnify_y)?magnify_x:magnify_y)/1.05);
-
-  ddisplay_update_scrollbars(ddisp);
-  ddisplay_add_update_all(ddisp);
-  ddisplay_flush(ddisp);
+  
+  ddisplay_show_all (ddisp);
 }
 
 void

Modified: trunk/app/dia.def
==============================================================================
--- trunk/app/dia.def	(original)
+++ trunk/app/dia.def	Sat Aug  9 12:28:03 2008
@@ -12,6 +12,7 @@
  ddisplay_scroll_up
  ddisplay_set_origo
  ddisplay_set_title
+ ddisplay_show_all
  ddisplay_zoom
  new_display
  diagram_add_update
@@ -35,6 +36,7 @@
  diagram_unselect_object
  diagram_update_extents
  diagram_update_connections_object
+ diagram_update_connections_selection
  dia_open_diagrams
 
  ; just for the applications

Modified: trunk/app/display.c
==============================================================================
--- trunk/app/display.c	(original)
+++ trunk/app/display.c	Sat Aug  9 12:28:03 2008
@@ -1528,3 +1528,52 @@
 {
   ddisp->active_focus = focus;
 }
+
+void
+ddisplay_show_all (DDisplay *ddisp)
+{
+  Diagram *dia;
+  real magnify_x, magnify_y;
+  int width, height;
+  Point middle;
+
+  g_return_if_fail (ddisp != NULL);
+  
+  dia = ddisp->diagram;
+
+  width = dia_renderer_get_width_pixels (ddisp->renderer);
+  height = dia_renderer_get_height_pixels (ddisp->renderer);
+
+  /* if there is something selected show that instead of all exisiting objects */
+  if (dia->data->selected) {
+    GList *list = dia->data->selected;
+    Rectangle extents = *dia_object_get_enclosing_box ((DiaObject*)list->data);
+    list = g_list_next(list);
+    while (list) {
+      DiaObject *obj = (DiaObject *)list->data;
+      rectangle_union(&extents, dia_object_get_enclosing_box (obj));
+      list = g_list_next(list);
+    }
+    magnify_x = (real)width / (extents.right - extents.left) / ddisp->zoom_factor;
+    magnify_y = (real)height / (extents.bottom - extents.top) / ddisp->zoom_factor;
+    middle.x = extents.left + (extents.right - extents.left) / 2.0;
+    middle.y = extents.top + (extents.bottom - extents.top) / 2.0;
+  } else {
+    magnify_x = (real)width /
+      (dia->data->extents.right - dia->data->extents.left) / ddisp->zoom_factor;
+    magnify_y = (real)height /
+      (dia->data->extents.bottom - dia->data->extents.top) / ddisp->zoom_factor;
+
+    middle.x = dia->data->extents.left +
+      (dia->data->extents.right - dia->data->extents.left) / 2.0;
+    middle.y = dia->data->extents.top +
+      (dia->data->extents.bottom - dia->data->extents.top) / 2.0;
+  }
+
+  ddisplay_zoom (ddisp, &middle, 
+		 ((magnify_x<magnify_y)?magnify_x:magnify_y)/1.05);
+
+  ddisplay_update_scrollbars(ddisp);
+  ddisplay_add_update_all(ddisp);
+  ddisplay_flush(ddisp);
+}

Modified: trunk/app/display.h
==============================================================================
--- trunk/app/display.h	(original)
+++ trunk/app/display.h	Sat Aug  9 12:28:03 2008
@@ -173,6 +173,8 @@
 gboolean ddisplay_scroll_center_point(DDisplay *ddisp, Point *p);
 gboolean ddisplay_scroll_to_object(DDisplay *ddisp, DiaObject *obj);
 
+void ddisplay_show_all (DDisplay *ddisp);
+
 void display_update_menu_state(DDisplay *ddisp);
 void ddisplay_update_statusbar(DDisplay *ddisp);
 void ddisplay_do_update_menu_sensitivity (DDisplay *ddisp);

Modified: trunk/lib/bezier_conn.c
==============================================================================
--- trunk/lib/bezier_conn.c	(original)
+++ trunk/lib/bezier_conn.c	Sat Aug  9 12:28:03 2008
@@ -482,9 +482,9 @@
   }
   realpoint.type = BEZ_CURVE_TO;
 
-  new_handle1 = g_malloc(sizeof(Handle));
-  new_handle2 = g_malloc(sizeof(Handle));
-  new_handle3 = g_malloc(sizeof(Handle));
+  new_handle1 = g_new0(Handle,1);
+  new_handle2 = g_new0(Handle,1);
+  new_handle3 = g_new0(Handle,1);
   setup_handle(new_handle1, HANDLE_RIGHTCTRL);
   setup_handle(new_handle2, HANDLE_LEFTCTRL);
   setup_handle(new_handle3, HANDLE_BEZMAJOR);
@@ -764,16 +764,16 @@
 
   obj = &bez->object;
 
-  obj->handles[0] = g_new(Handle,1);
+  obj->handles[0] = g_new0(Handle,1);
   obj->handles[0]->connect_type = HANDLE_CONNECTABLE;
   obj->handles[0]->connected_to = NULL;
   obj->handles[0]->type = HANDLE_MAJOR_CONTROL;
   obj->handles[0]->id = HANDLE_MOVE_STARTPOINT;
 
   for (i = 1; i < num_points; i++) {
-    obj->handles[3*i-2] = g_new(Handle, 1);
-    obj->handles[3*i-1] = g_new(Handle, 1);
-    obj->handles[3*i] = g_new(Handle, 1);
+    obj->handles[3*i-2] = g_new0(Handle,1);
+    obj->handles[3*i-1] = g_new0(Handle,1);
+    obj->handles[3*i] = g_new0(Handle,1);
   
     setup_handle(obj->handles[3*i-2], HANDLE_RIGHTCTRL);
     setup_handle(obj->handles[3*i-1], HANDLE_LEFTCTRL);
@@ -867,13 +867,13 @@
     to->corner_types[i] = from->corner_types[i];
   }
 
-  to->object.handles[0] = g_new(Handle,1);
+  to->object.handles[0] = g_new0(Handle,1);
   *to->object.handles[0] = *from->object.handles[0];
   for (i = 1; i < to->object.num_handles - 1; i++) {
-    to->object.handles[i] = g_new(Handle, 1);
+    to->object.handles[i] = g_new0(Handle,1);
     setup_handle(to->object.handles[i], from->object.handles[i]->id);
   }
-  to->object.handles[to->object.num_handles-1] = g_new(Handle,1);
+  to->object.handles[to->object.num_handles-1] = g_new0(Handle,1);
   *to->object.handles[to->object.num_handles-1] =
     *from->object.handles[to->object.num_handles-1];
 
@@ -997,18 +997,18 @@
     }
   }
 
-  obj->handles[0] = g_new(Handle, 1);
+  obj->handles[0] = g_new0(Handle,1);
   obj->handles[0]->connect_type = HANDLE_CONNECTABLE;
   obj->handles[0]->connected_to = NULL;
   obj->handles[0]->type = HANDLE_MAJOR_CONTROL;
   obj->handles[0]->id = HANDLE_MOVE_STARTPOINT;
   
   for (i = 1; i < bez->numpoints; i++) {
-    obj->handles[3*i-2] = g_new(Handle, 1);
+    obj->handles[3*i-2] = g_new0(Handle,1);
     setup_handle(obj->handles[3*i-2], HANDLE_RIGHTCTRL);
-    obj->handles[3*i-1] = g_new(Handle, 1);
+    obj->handles[3*i-1] = g_new0(Handle,1);
     setup_handle(obj->handles[3*i-1], HANDLE_LEFTCTRL);
-    obj->handles[3*i]   = g_new(Handle, 1);
+    obj->handles[3*i]   = g_new0(Handle,1);
     setup_handle(obj->handles[3*i],   HANDLE_BEZMAJOR);
   }
 

Modified: trunk/lib/beziershape.c
==============================================================================
--- trunk/lib/beziershape.c	(original)
+++ trunk/lib/beziershape.c	Sat Aug  9 12:28:03 2008
@@ -438,9 +438,9 @@
   }
   realpoint.type = BEZ_CURVE_TO;
 
-  new_handle1 = g_new(Handle, 1);
-  new_handle2 = g_new(Handle, 1);
-  new_handle3 = g_new(Handle, 1);
+  new_handle1 = g_new0(Handle,1);
+  new_handle2 = g_new0(Handle,1);
+  new_handle3 = g_new0(Handle,1);
   setup_handle(new_handle1, HANDLE_RIGHTCTRL);
   setup_handle(new_handle2, HANDLE_LEFTCTRL);
   setup_handle(new_handle3, HANDLE_BEZMAJOR);
@@ -771,9 +771,9 @@
   obj = &bezier->object;
 
   for (i = 0; i < num_points-1; i++) {
-    obj->handles[3*i] = g_new(Handle, 1);
-    obj->handles[3*i+1] = g_new(Handle, 1);
-    obj->handles[3*i+2] = g_new(Handle, 1);
+    obj->handles[3*i] = g_new0(Handle,1);
+    obj->handles[3*i+1] = g_new0(Handle,1);
+    obj->handles[3*i+2] = g_new0(Handle,1);
   
     obj->handles[3*i]->connect_type = HANDLE_NONCONNECTABLE;
     obj->handles[3*i]->connected_to = NULL;
@@ -872,7 +872,7 @@
   }
 
   for (i = 0; i < toobj->num_handles; i++) {
-    toobj->handles[i] = g_new(Handle, 1);
+    toobj->handles[i] = g_new0(Handle,1);
     setup_handle(toobj->handles[i], fromobj->handles[i]->id);
   }
   for (i = 0; i < toobj->num_connections; i++) {
@@ -997,9 +997,9 @@
   }
 
   for (i = 0; i < bezier->numpoints - 1; i++) {
-    obj->handles[3*i] = g_new(Handle, 1);
-    obj->handles[3*i+1] = g_new(Handle, 1);
-    obj->handles[3*i+2]   = g_new(Handle, 1);
+    obj->handles[3*i] = g_new0(Handle,1);
+    obj->handles[3*i+1] = g_new0(Handle,1);
+    obj->handles[3*i+2]   = g_new0(Handle,1);
 
     setup_handle(obj->handles[3*i], HANDLE_RIGHTCTRL);
     setup_handle(obj->handles[3*i+1], HANDLE_LEFTCTRL);

Modified: trunk/lib/boundingbox.c
==============================================================================
--- trunk/lib/boundingbox.c	(original)
+++ trunk/lib/boundingbox.c	Sat Aug  9 12:28:03 2008
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <glib.h>
 #include <math.h>
+#include <string.h> /* memcmp() */
 #include "geometry.h"
 #include "boundingbox.h"
 
@@ -322,7 +323,7 @@
   vp.y=0;
 
   g_assert(pts[0].type == BEZ_MOVE_TO);
-  
+
   rect->left = rect->right = pts[0].p1.x;
   rect->top = rect->bottom = pts[0].p1.y;
 

Modified: trunk/lib/connectionpoint.c
==============================================================================
--- trunk/lib/connectionpoint.c	(original)
+++ trunk/lib/connectionpoint.c	Sat Aug  9 12:28:03 2008
@@ -85,5 +85,5 @@
 gboolean
 connpoint_is_autogap(ConnectionPoint *cp)
 {
-  return cp != NULL && (cp->flags & CP_FLAG_AUTOGAP);
+  return cp != NULL && (cp->flags & CP_FLAG_AUTOGAP) && (cp->connected != NULL);
 }

Modified: trunk/lib/connectionpoint.h
==============================================================================
--- trunk/lib/connectionpoint.h	(original)
+++ trunk/lib/connectionpoint.h	Sat Aug  9 12:28:03 2008
@@ -26,32 +26,36 @@
 #define CONNECTIONPOINT_SIZE 5
 #define CHANGED_TRESHOLD 0.001
 
-/* Connections directions, used as hints to zigzaglines */
-/* Ordered this way to let *2 be rotate clockwise, /2 rotate counterclockwise.
+/*! \brief Connections directions, used as hints to e.g. zigzaglines 
+ * Ordered this way to let *2 be rotate clockwise, /2 rotate counterclockwise.
  * Used as bits */
-#define DIR_NORTH 1
-#define DIR_EAST  2
-#define DIR_SOUTH 4
-#define DIR_WEST  8
-
-/* Convenience directions */
-#define DIR_NORTHEAST (DIR_NORTH|DIR_EAST)
-#define DIR_SOUTHEAST (DIR_SOUTH|DIR_EAST)
-#define DIR_NORTHWEST (DIR_NORTH|DIR_WEST)
-#define DIR_SOUTHWEST (DIR_SOUTH|DIR_WEST)
-#define DIR_NONE      0
-#define DIR_ALL       (DIR_NORTH|DIR_SOUTH|DIR_EAST|DIR_WEST)
-
-#define CP_FLAG_ANYPLACE	1 /*!< Set if this connpoint is the one that
-				     is connected to when a connection is
-				     dropped on an object. */
-#define CP_FLAG_AUTOGAP		2 /*!< Set if this connpoint is internal
-				     and so should force a gap on the lines. */
+typedef enum {
+  DIR_NONE  = 0,
+  DIR_NORTH = (1<<0),
+  DIR_EAST  = (1<<1),
+  DIR_SOUTH = (1<<2),
+  DIR_WEST  = (1<<3),
+  /* Convenience directions */
+  DIR_NORTHEAST = (DIR_NORTH|DIR_EAST),
+  DIR_SOUTHEAST = (DIR_SOUTH|DIR_EAST),
+  DIR_NORTHWEST = (DIR_NORTH|DIR_WEST),
+  DIR_SOUTHWEST = (DIR_SOUTH|DIR_WEST),
+  DIR_ALL       = (DIR_NORTH|DIR_SOUTH|DIR_EAST|DIR_WEST)
+} ConnectionPointDirection;
+
+/*! \brief Additional behaviour flags for connection points */
+typedef enum {
+  CP_FLAG_ANYPLACE = (1<<0), /*!< Set if this connpoint is the one that
+			                 is connected to when a connection is
+			                 dropped on an object. */
+  CP_FLAG_AUTOGAP =  (1<<1), /*!< Set if this connpoint is internal
+			                and so should force a gap on the lines. */
 
 /*! Most non-connection objects want exactly one CP with this, in the middle. */
-#define CP_FLAGS_MAIN		3 /*!< Use this for the central CP that
-				     takes connections from all over the
-				     object and has autogap. */
+  CP_FLAGS_MAIN	=   (CP_FLAG_ANYPLACE|CP_FLAG_AUTOGAP) /*!< Use this for the central CP that
+			              takes connections from all over the
+			              object and has autogap. */
+} ConnectionPointFlags;
 
 /*!
  * \brief To connect object with other objects handles

Modified: trunk/lib/geometry.h
==============================================================================
--- trunk/lib/geometry.h	(original)
+++ trunk/lib/geometry.h	Sat Aug  9 12:28:03 2008
@@ -86,18 +86,18 @@
 
 /*! \brief A rectangle given by upper left and lower right corner */
 struct _Rectangle {
-  coord top; /*!< y1 */
   coord left; /*!< x1 */
-  coord bottom; /*!< y2 */
+  coord top; /*!< y1 */
   coord right; /*!< x2 */
+  coord bottom; /*!< y2 */
 };
 
 /*! \brief A rectangle for fixed point e.g. pixel coordinates */
 struct _IntRectangle {
-  int top; /*!< y1 */
   int left; /*!< x1 */
-  int bottom; /*!< y2 */
+  int top; /*!< y1 */
   int right; /*!< x2 */
+  int bottom; /*!< y2 */
 };
 
 /*! 

Modified: trunk/lib/libdia.def
==============================================================================
--- trunk/lib/libdia.def	(original)
+++ trunk/lib/libdia.def	Sat Aug  9 12:28:03 2008
@@ -625,6 +625,7 @@
 
  rectangle_add_point
  rectangle_bbox
+ rectangle_in_rectangle
  rectangle_intersection
  rectangle_intersects
  rectangle_union

Modified: trunk/lib/plug-ins.h
==============================================================================
--- trunk/lib/plug-ins.h	(original)
+++ trunk/lib/plug-ins.h	Sat Aug  9 12:28:03 2008
@@ -48,7 +48,7 @@
  * 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 9
+#define DIA_PLUGIN_API_VERSION 10
 
 typedef enum {
   DIA_PLUGIN_INIT_OK,

Modified: trunk/objects/SISSI/sissi.c
==============================================================================
--- trunk/objects/SISSI/sissi.c	(original)
+++ trunk/objects/SISSI/sissi.c	Sat Aug  9 12:28:03 2008
@@ -403,29 +403,32 @@
   
   object_sissi->nb_others_fixes=object_sissi_origin->nb_others_fixes;
 
-   object_sissi->border_color=object_sissi_origin->border_color;
-   object_sissi->fill_colour=object_sissi_origin->fill_colour; 
-   object_sissi->radius=object_sissi_origin->radius;
-   object_sissi->subscribers=object_sissi_origin->subscribers; 
-   object_sissi->show_background=object_sissi_origin->show_background;
-   object_sissi->line_colour=object_sissi_origin->line_colour; 
-   object_sissi->dashlength=object_sissi_origin->dashlength;
-   object_sissi->line_width=object_sissi_origin->line_width; 
-   object_sissi->border_width=object_sissi_origin->border_width;
-   object_sissi->draw_border=object_sissi_origin->draw_border; 
-   object_sissi->keep_aspect=object_sissi_origin->keep_aspect;
-
-   object_sissi->confidentiality = g_strdup(object_sissi_origin->confidentiality);
-   object_sissi->entity = g_strdup(object_sissi_origin->entity);
-   object_sissi->entity_type = g_strdup(object_sissi_origin->entity_type);
-   object_sissi->site = g_strdup(object_sissi_origin->site);
-   object_sissi->room = g_strdup(object_sissi_origin->room);
-   object_sissi->name = g_strdup(object_sissi_origin->name);
+  object_sissi->border_color=object_sissi_origin->border_color;
+  object_sissi->fill_colour=object_sissi_origin->fill_colour; 
+  object_sissi->radius=object_sissi_origin->radius;
+  object_sissi->subscribers=object_sissi_origin->subscribers; 
+  object_sissi->show_background=object_sissi_origin->show_background;
+  object_sissi->line_colour=object_sissi_origin->line_colour; 
+  object_sissi->dashlength=object_sissi_origin->dashlength;
+  object_sissi->line_width=object_sissi_origin->line_width; 
+  object_sissi->border_width=object_sissi_origin->border_width;
+  object_sissi->draw_border=object_sissi_origin->draw_border; 
+  object_sissi->keep_aspect=object_sissi_origin->keep_aspect;
+
+  object_sissi->confidentiality = g_strdup(object_sissi_origin->confidentiality);
+  object_sissi->entity = g_strdup(object_sissi_origin->entity);
+  object_sissi->entity_type = g_strdup(object_sissi_origin->entity_type);
+  object_sissi->site = g_strdup(object_sissi_origin->site);
+  object_sissi->room = g_strdup(object_sissi_origin->room);
+  object_sissi->name = g_strdup(object_sissi_origin->name);
       
-   object_sissi->type_element = g_strdup(object_sissi_origin->type_element);
-   object_sissi->file =g_strdup(object_sissi_origin->file);
-   object_sissi->image = dia_image_load(dia_get_data_directory(object_sissi->file));
-  
+  object_sissi->type_element = g_strdup(object_sissi_origin->type_element);
+  object_sissi->file =g_strdup(object_sissi_origin->file);
+  if (object_sissi->file) {
+    char *filename = dia_get_data_directory(object_sissi->file);
+    object_sissi->image = dia_image_load(filename);
+    g_free (filename);
+  }
   for (i=0;i<NUM_CONNECTIONS;i++) {
     obj->connections[i] = &object_sissi->connections[i];
     object_sissi->connections[i].object = obj;

Modified: trunk/objects/standard/bezier.c
==============================================================================
--- trunk/objects/standard/bezier.c	(original)
+++ trunk/objects/standard/bezier.c	Sat Aug  9 12:28:03 2008
@@ -381,11 +381,11 @@
 					 &bezierline->end_arrow);
     exchange_bez_gap_points(bez,gap_points);
   } else {
-  renderer_ops->draw_bezier_with_arrows(renderer, bez->points, bez->numpoints,
-					 bezierline->line_width,
-					 &bezierline->line_color,
-					 &bezierline->start_arrow,
-					 &bezierline->end_arrow);
+    renderer_ops->draw_bezier_with_arrows(renderer, bez->points, bez->numpoints,
+					  bezierline->line_width,
+					  &bezierline->line_color,
+					  &bezierline->start_arrow,
+					  &bezierline->end_arrow);
   }
 
 #if 0
@@ -629,10 +629,6 @@
   BezierConn *bez;
   DiaObject *obj;
   AttributeNode attr;
-  /* When the bezier is loaded it is not yet connected to the other objects
-   * hence we cannot compute it's real bounding box if auto gaps are used 
-   * bb is a backup bounding box */
-  Rectangle bb; 
 
   bezierline = g_new0(Bezierline, 1);
 
@@ -679,9 +675,11 @@
   if (attr != NULL)
     bezierline->absolute_end_gap =  data_real( attribute_first_data(attr) );
   
-  bb = obj->bounding_box;
-  bezierline_update_data(bezierline); /* screws up the bounding box if auto_gap */
-  obj->bounding_box =  bb;
+  /* if "screws up the bounding box if auto_gap" it must be fixed there
+   * not by copying some meaningless bounding_box before this function call!
+   * But the real fix is in connectionpoint.c(connpoint_is_autogap)
+   */
+  bezierline_update_data(bezierline); 
 
   return &bezierline->bez.object;
 }

Added: trunk/plug-ins/python/autolayoutforce.py
==============================================================================
--- (empty file)
+++ trunk/plug-ins/python/autolayoutforce.py	Sat Aug  9 12:28:03 2008
@@ -0,0 +1,123 @@
+#  autolayoutforce.py - graph layout plug-in for Dia
+#
+#  Copyright (C) 2008 Frederic-Gerald Morcos <fred mrocos gmail com>
+#  Copyright (c) 2008 Hans Breuer <hans breuer org>
+#
+#  Playground for the "force based autolayout" algorithm initially implemented
+# for Dia in C by Fred Morcos
+
+#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+import math, dia
+
+def bbox_area (o) :
+	r = o.bounding_box
+	return (r.bottom - r.top) * (r.right - r.left)
+
+def attraction (aconst, node, other) :
+	"Calculates the attraction between two connected elements"
+	p1 = node.properties["obj_pos"].value
+	p2 = other.properties["obj_pos"].value
+	x = (p2.x - p1.x) * aconst
+	y = (p2.y - p1.y) * aconst
+	return (x,y)
+
+def repulsion (rconst, node, other) :
+	"Calculates the repulsion between any two elements"
+	p1 = node.properties["obj_pos"].value
+	p2 = other.properties["obj_pos"].value
+
+	m2 = bbox_area (other)
+	m1 = bbox_area (node)
+	
+	dx = p1.x - p2.x
+	dy = p1.y - p2.y
+
+	denom = math.pow (dx * dx + dy * dy, 1.5) # magic number?
+	numer = m1 * m2 * rconst
+
+	try :
+		fx = (numer * dx) / denom
+		fy = (numer * dy) / denom
+	except ZeroDivisionError :
+		print "ZeroDivisionError"
+		return (0,0)
+
+	return (fx,fy)
+	
+def layout_force (nodes, rconst, aconst, timestep, damping) :
+	energy = [0.0, 0.0]
+	for o in nodes :
+		netforce = [0.0, 0.0]
+		velocity = [0.0, 0.0]
+		for oo in nodes :
+			if oo != o :
+				r = repulsion (rconst, o, oo)
+				netforce[0] += r[0]
+				netforce[1] += r[1]
+		for cpt in o.connections : # connection points
+			for co in cpt.connected : # connected objects in this point
+				edge = co
+				oo = None
+				for h in edge.handles :
+					cto = h.connected_to # the other objects connection point
+					if  cto and cto.object != o :
+						oo = cto.object
+						# we usually only find _one_ other handle
+						a = attraction (aconst, o, oo)
+						netforce[0] += a[0]
+						netforce[1] += a[1]
+		#print "Netforce", netforce, timestep, damping
+		velocity[0] = timestep * netforce[0] * damping
+		velocity[1] = timestep * netforce[1] * damping
+
+		# new position
+		p = o.properties["obj_pos"].value
+		px = p.x + timestep * velocity[0]
+		py = p.y + timestep * velocity[1]
+		#print "move", timestep * velocity[0], timestep * velocity[1]
+		o.move (px, py)
+
+		mass = bbox_area (o)
+		energy[0] += mass * math.pow (velocity[0], 2) / 2
+		energy[1] += mass * math.pow (velocity[1], 2) / 2
+	return energy
+
+def layout_force_cb (data, flags) :
+	diagram = dia.active_display().diagram
+	# the things (nodes) we are moving around are all connected 'elements', 
+	# connection objects are only moving as a side effect
+	nodes = []
+	for o in data.selected :
+		for cpt in o.connections : # ConnectionPoint
+			if len (cpt.connected) > 0 :
+				nodes.append (o)
+				break
+	# this ususally is an iterative process, finished if no energy is left
+	#FIXME: layout_force (nodes, 2.0, 2.0, 0.2, 0.5) PASSES 0.0, 0.0
+	e = layout_force (nodes, 2.0, 3.0, 2e-1, 5e-1)
+	n = 0 # arbitrary limit to avoid endless loop
+	while (e[0] > 1 or e[1] > 1) and n < 100 :
+		e = layout_force (nodes, 2.0, 3.0, 2e-1, 5e-1)
+		n += 1
+	for o in nodes :
+		diagram.update_connections (o)
+	data.active_layer.update_extents() # data/diagram _update_extents don't recalculate?
+	diagram.update_extents ()
+	diagram.flush()
+	print n, "iterations"
+
+dia.register_action ("LayoutForcePy", "Layout (force)", 
+                     "/DisplayMenu/Test/TestExtensionStart", 
+                     layout_force_cb)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]