dia r4245 - in trunk: . objects/Misc objects/Misc/pixmaps sheets
- From: hans svn gnome org
- To: svn-commits-list gnome org
- Subject: dia r4245 - in trunk: . objects/Misc objects/Misc/pixmaps sheets
- Date: Sat, 31 Jan 2009 21:18:59 +0000 (UTC)
Author: hans
Date: Sat Jan 31 21:18:59 2009
New Revision: 4245
URL: http://svn.gnome.org/viewvc/dia?rev=4245&view=rev
Log:
2009-01-31 Hans Breuer <hans breuer org>
* objects/Misc/pixmaps/grid_object.xpm objects/Misc/grid_object.c
objects/Misc/libmisc.c objects/Misc/Makefile.am sheets/Misc.sheet.in:
patch from Don Blaheta adding a Grid object, bug #534118
Added:
trunk/objects/Misc/grid_object.c
trunk/objects/Misc/pixmaps/grid_object.xpm
Modified:
trunk/ChangeLog
trunk/objects/Misc/Makefile.am
trunk/objects/Misc/libmisc.c
trunk/sheets/Misc.sheet.in
Modified: trunk/objects/Misc/Makefile.am
==============================================================================
--- trunk/objects/Misc/Makefile.am (original)
+++ trunk/objects/Misc/Makefile.am Sat Jan 31 21:18:59 2009
@@ -4,6 +4,7 @@
libmisc_objects_la_SOURCES = \
libmisc.c \
analog_clock.c \
+ grid_object.c \
measure.c \
tree.c
@@ -15,6 +16,7 @@
EXTRA_DIST = \
pixmaps/analog_clock.xpm \
+ pixmaps/grid_object.xpm \
pixmaps/measure.xpm \
pixmaps/newgroup.xpm \
pixmaps/tree.xpm
Added: trunk/objects/Misc/grid_object.c
==============================================================================
--- (empty file)
+++ trunk/objects/Misc/grid_object.c Sat Jan 31 21:18:59 2009
@@ -0,0 +1,522 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * Grid object
+ * Copyright (C) 2008 Don Blaheta
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+#include <glib.h>
+#include <time.h>
+#include <stdio.h>
+
+#include "intl.h"
+#include "object.h"
+#include "element.h"
+#include "connectionpoint.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "widgets.h"
+#include "message.h"
+#include "color.h"
+#include "properties.h"
+
+#include "pixmaps/grid_object.xpm"
+
+#define GRID_OBJECT_BASE_CONNECTION_POINTS 9
+
+typedef struct _Grid_Object {
+ Element element;
+
+ ConnectionPoint base_cps[9];
+ gint cells_rows;
+ gint cells_cols;
+ ConnectionPoint *cells;
+
+ Color border_color;
+ real border_line_width;
+ Color inner_color;
+ gboolean show_background;
+ gint grid_rows;
+ gint grid_cols;
+ Color gridline_color;
+ real gridline_width;
+} Grid_Object;
+
+static real grid_object_distance_from(Grid_Object *grid_object,
+ Point *point);
+
+static void grid_object_select(Grid_Object *grid_object,
+ Point *clicked_point,
+ DiaRenderer *interactive_renderer);
+static ObjectChange* grid_object_move_handle(Grid_Object *grid_object,
+ Handle *handle, Point *to,
+ ConnectionPoint *cp, HandleMoveReason reason,
+ ModifierKeys modifiers);
+static ObjectChange* grid_object_move(Grid_Object *grid_object, Point *to);
+static void grid_object_draw(Grid_Object *grid_object, DiaRenderer *renderer);
+static void grid_object_update_data(Grid_Object *grid_object);
+static DiaObject *grid_object_create(Point *startpoint,
+ void *user_data,
+ Handle **handle1,
+ Handle **handle2);
+static void grid_object_reallocate_cells (Grid_Object* grid_object);
+static void grid_object_destroy(Grid_Object *grid_object);
+static DiaObject *grid_object_load(ObjectNode obj_node, int version,
+ const char *filename);
+static PropDescription *grid_object_describe_props(
+ Grid_Object *grid_object);
+static void grid_object_get_props(Grid_Object *grid_object,
+ GPtrArray *props);
+static void grid_object_set_props(Grid_Object *grid_object,
+ GPtrArray *props);
+
+static ObjectTypeOps grid_object_type_ops =
+{
+ (CreateFunc) grid_object_create,
+ (LoadFunc) grid_object_load/*using properties*/,
+ (SaveFunc) object_save_using_properties,
+ (GetDefaultsFunc) NULL,
+ (ApplyDefaultsFunc) NULL
+};
+
+DiaObjectType grid_object_type =
+{
+ "Misc - Grid", /* name */
+ 0, /* version */
+ (char **) grid_object_xpm, /* pixmap */
+
+ &grid_object_type_ops /* ops */
+};
+
+static ObjectOps grid_object_ops = {
+ (DestroyFunc) grid_object_destroy,
+ (DrawFunc) grid_object_draw,
+ (DistanceFunc) grid_object_distance_from,
+ (SelectFunc) grid_object_select,
+ (CopyFunc) object_copy_using_properties,
+ (MoveFunc) grid_object_move,
+ (MoveHandleFunc) grid_object_move_handle,
+ (GetPropertiesFunc) object_create_props_dialog,
+ (ApplyPropertiesDialogFunc) object_apply_props_from_dialog,
+ (ObjectMenuFunc) NULL,
+ (DescribePropsFunc) grid_object_describe_props,
+ (GetPropsFunc) grid_object_get_props,
+ (SetPropsFunc) grid_object_set_props,
+ (TextEditFunc) 0,
+ (ApplyPropertiesListFunc) object_apply_props,
+};
+
+static PropDescription grid_object_props[] = {
+ ELEMENT_COMMON_PROPERTIES,
+ PROP_STD_LINE_WIDTH,
+ PROP_STD_LINE_COLOUR,
+ PROP_STD_FILL_COLOUR,
+ PROP_STD_SHOW_BACKGROUND,
+
+ { "grid_rows", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+ N_("Rows"), NULL, NULL },
+ { "grid_cols", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+ N_("Columns"), NULL, NULL },
+ { "gridline_colour", PROP_TYPE_COLOUR, PROP_FLAG_VISIBLE,
+ N_("Gridline color"), NULL, NULL },
+ { "gridline_width", PROP_TYPE_REAL, PROP_FLAG_VISIBLE,
+ N_("Gridline width"), NULL,NULL },
+
+ {NULL}
+};
+
+static PropDescription *
+grid_object_describe_props(Grid_Object *grid_object)
+{
+ if (grid_object_props[0].quark == 0) {
+ prop_desc_list_calculate_quarks(grid_object_props);
+ }
+ return grid_object_props;
+}
+
+static PropOffset grid_object_offsets[] = {
+ ELEMENT_COMMON_PROPERTIES_OFFSETS,
+ { PROP_STDNAME_LINE_WIDTH, PROP_STDTYPE_LINE_WIDTH, offsetof(Grid_Object, border_line_width) },
+ { "line_colour", PROP_TYPE_COLOUR, offsetof(Grid_Object, border_color) },
+ { "fill_colour", PROP_TYPE_COLOUR, offsetof(Grid_Object,inner_color) },
+ { "show_background", PROP_TYPE_BOOL,offsetof(Grid_Object,show_background) },
+ { "grid_rows", PROP_TYPE_INT, offsetof(Grid_Object, grid_rows) },
+ { "grid_cols", PROP_TYPE_INT, offsetof(Grid_Object, grid_cols) },
+ { "gridline_colour", PROP_TYPE_COLOUR, offsetof(Grid_Object, gridline_color) },
+ { "gridline_width", PROP_TYPE_REAL, offsetof(Grid_Object,
+ gridline_width) },
+
+ {NULL}
+};
+
+static void
+grid_object_get_props(Grid_Object *grid_object, GPtrArray *props)
+{
+ object_get_props_from_offsets(&grid_object->element.object,
+ grid_object_offsets,props);
+}
+
+static void
+grid_object_set_props(Grid_Object *grid_object, GPtrArray *props)
+{
+ DiaObject *obj = &grid_object->element.object;
+
+ object_set_props_from_offsets(obj, grid_object_offsets,props);
+
+ grid_object_reallocate_cells(grid_object);
+
+ grid_object_update_data(grid_object);
+}
+
+static real
+grid_object_distance_from(Grid_Object *grid_object, Point *point)
+{
+ DiaObject *obj = &grid_object->element.object;
+ return distance_rectangle_point(&obj->bounding_box, point);
+}
+
+static void
+grid_object_select(Grid_Object *grid_object, Point *clicked_point,
+ DiaRenderer *interactive_renderer)
+{
+ element_update_handles(&grid_object->element);
+}
+
+static ObjectChange*
+grid_object_move_handle(Grid_Object *grid_object, Handle *handle,
+ Point *to, ConnectionPoint *cp,
+ HandleMoveReason reason, ModifierKeys modifiers)
+{
+ g_assert(grid_object!=NULL);
+ g_assert(handle!=NULL);
+ g_assert(to!=NULL);
+
+ element_move_handle(&grid_object->element, handle->id, to, cp,
+ reason, modifiers);
+ grid_object_update_data(grid_object);
+
+ return NULL;
+}
+
+static ObjectChange*
+grid_object_move(Grid_Object *grid_object, Point *to)
+{
+ grid_object->element.corner = *to;
+ grid_object_update_data(grid_object);
+
+ return NULL;
+}
+
+/** Converts 2D indices into 1D. Currently row-major. */
+inline static int grid_cell (int i, int j, int rows, int cols)
+{
+ return j * cols + i;
+}
+
+static void
+grid_object_update_data(Grid_Object *grid_object)
+{
+ Element *elem = &grid_object->element;
+ DiaObject *obj = &elem->object;
+ ElementBBExtras *extra = &elem->extra_spacing;
+
+ real inset = (grid_object->border_line_width - grid_object->gridline_width)/2.0;
+ real cell_width = (elem->width - 2.0 * inset) / grid_object->grid_cols;
+ real cell_height = (elem->height - 2.0 * inset) / grid_object->grid_rows;
+ int i, j;
+ coord left, top;
+
+ extra->border_trans = grid_object->border_line_width / 2.0;
+ element_update_boundingbox(elem);
+ element_update_handles(elem);
+ element_update_connections_rectangle(elem, grid_object->base_cps);
+
+ obj->position = elem->corner;
+ left = obj->position.x;
+ top = obj->position.y;
+ for (i = 0; i < grid_object->grid_cols; ++i)
+ for (j = 0; j < grid_object->grid_rows; ++j)
+ {
+ int cell = grid_cell(i, j, grid_object->grid_rows, grid_object->grid_cols);
+ grid_object->cells[cell].pos.x =
+ left + inset + i*cell_width + cell_width/2.0;
+ grid_object->cells[cell].pos.y =
+ top + inset + j*cell_height + cell_height/2.0;
+ }
+}
+
+static void
+grid_object_draw_gridlines (Grid_Object *grid_object, DiaRenderer *renderer,
+ Point* lr_corner)
+{
+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+ Element *elem;
+ Point st, fn;
+ real cell_size;
+ unsigned i;
+ real inset;
+
+ elem = &grid_object->element;
+
+ /* The goal is to have all cells equal size; if the border line is
+ * much wider than the gridline, the outer course of cells will be
+ * visibly smaller. So we "inset" them by a little bit: */
+ inset = (grid_object->border_line_width - grid_object->gridline_width)/2;
+
+ /* horizontal gridlines */
+ st.x = elem->corner.x;
+ st.y = elem->corner.y + inset;
+ fn.x = elem->corner.x + elem->width;
+ fn.y = elem->corner.y + inset;
+
+ cell_size = (elem->height - 2 * inset)
+ / grid_object->grid_rows;
+ if (cell_size < 0)
+ cell_size = 0;
+ for (i = 1; i < grid_object->grid_rows; ++i) {
+ st.y += cell_size;
+ fn.y += cell_size;
+ renderer_ops->draw_line(renderer,&st,&fn,&grid_object->gridline_color);
+ }
+
+ /* vertical gridlines */
+ st.x = elem->corner.x + inset;
+ st.y = elem->corner.y;
+ fn.x = elem->corner.x + inset;
+ fn.y = elem->corner.y + elem->height;
+
+ cell_size = (elem->width - 2 * inset)
+ / grid_object->grid_cols;
+ if (cell_size < 0)
+ cell_size = 0;
+ for (i = 1; i < grid_object->grid_cols; ++i) {
+ st.x += cell_size;
+ fn.x += cell_size;
+ renderer_ops->draw_line(renderer,&st,&fn,&grid_object->gridline_color);
+ }
+}
+
+static void
+grid_object_draw(Grid_Object *grid_object, DiaRenderer *renderer)
+{
+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+ Element *elem;
+ Point lr_corner;
+
+ g_assert(grid_object != NULL);
+ g_assert(renderer != NULL);
+
+ elem = &grid_object->element;
+
+ lr_corner.x = elem->corner.x + elem->width;
+ lr_corner.y = elem->corner.y + elem->height;
+
+ renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
+ renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
+
+ /* draw background */
+ if (grid_object->show_background)
+ renderer_ops->fill_rect(renderer,&elem->corner,
+ &lr_corner,
+ &grid_object->inner_color);
+
+ /* draw gridlines */
+ renderer_ops->set_linewidth(renderer, grid_object->gridline_width);
+ grid_object_draw_gridlines(grid_object, renderer, &lr_corner);
+
+ /* draw outline */
+ renderer_ops->set_linewidth(renderer, grid_object->border_line_width);
+ renderer_ops->draw_rect(renderer,&elem->corner,
+ &lr_corner,
+ &grid_object->border_color);
+}
+
+
+static DiaObject *
+grid_object_create(Point *startpoint,
+ void *user_data,
+ Handle **handle1,
+ Handle **handle2)
+{
+ Grid_Object *grid_object;
+ Element *elem;
+ DiaObject *obj;
+ unsigned i;
+
+ grid_object = g_new0(Grid_Object,1);
+ elem = &(grid_object->element);
+
+ obj = &(grid_object->element.object);
+ obj->type = &grid_object_type;
+ obj->ops = &grid_object_ops;
+
+ elem->corner = *startpoint;
+ elem->width = 4.0;
+ elem->height = 4.0;
+
+ element_init(elem, 8, 9);
+
+ grid_object->border_color = attributes_get_foreground();
+ grid_object->border_line_width = attributes_get_default_linewidth();
+ grid_object->inner_color = attributes_get_background();
+ grid_object->show_background = TRUE;
+ grid_object->grid_rows = 3;
+ grid_object->grid_cols = 4;
+ grid_object->gridline_color.red = 0.5;
+ grid_object->gridline_color.green = 0.5;
+ grid_object->gridline_color.blue = 0.5;
+ grid_object->gridline_width = attributes_get_default_linewidth();
+
+ for (i = 0; i < 9; ++i)
+ {
+ obj->connections[i] = &grid_object->base_cps[i];
+ grid_object->base_cps[i].object = obj;
+ grid_object->base_cps[i].connected = NULL;
+ }
+ grid_object->base_cps[8].flags = CP_FLAGS_MAIN;
+
+ grid_object->cells_rows = 0;
+ grid_object->cells_cols = 0;
+ grid_object->cells = NULL;
+ grid_object_reallocate_cells(grid_object);
+
+ grid_object_update_data(grid_object);
+
+ *handle1 = NULL;
+ *handle2 = obj->handles[7];
+
+ return &grid_object->element.object;
+}
+
+static void
+connectionpoint_init (ConnectionPoint* cp, DiaObject* obj)
+{
+ cp->object = obj;
+ cp->connected = NULL;
+ cp->directions = DIR_ALL;
+ cp->name = NULL;
+ cp->flags = 0;
+}
+
+static void
+connectionpoint_update(ConnectionPoint* newcp, ConnectionPoint* oldcp)
+{
+ GList* cur;
+ newcp->connected = oldcp->connected;
+
+ cur = newcp->connected; /* GList of DO* */
+ while (cur != NULL)
+ {
+ DiaObject* connecting_obj = g_list_nth_data(cur, 0);
+ int i;
+ for (i = 0; i < connecting_obj->num_handles; ++i)
+ {
+ if (connecting_obj->handles[i]->connected_to == oldcp)
+ { /* this is the inbound connection */
+ connecting_obj->handles[i]->connected_to = newcp;
+ }
+ }
+
+ cur = g_list_next(cur);
+ }
+}
+
+/** Adjusts allocations for connection points; does not actually compute
+ * them. This call should always be followed with a call to update_data. */
+static void
+grid_object_reallocate_cells (Grid_Object* grid_object)
+{
+ DiaObject* obj = &(grid_object->element.object);
+ int old_rows = grid_object->cells_rows;
+ int old_cols = grid_object->cells_cols;
+ int new_rows = grid_object->grid_rows;
+ int new_cols = grid_object->grid_cols;
+ int i, j;
+ ConnectionPoint* new_cells;
+
+ if (old_rows == new_rows && old_cols == new_cols)
+ return; /* no reallocation necessary */
+
+ /* obj->connections doesn't own the pointers, so just realloc; values
+ * will be updated later */
+ obj->num_connections = GRID_OBJECT_BASE_CONNECTION_POINTS + new_rows*new_cols;
+ obj->connections = (ConnectionPoint **) g_realloc(obj->connections,
+ obj->num_connections * sizeof(ConnectionPoint *));
+
+ /* If either new dimension is smaller, some connpoints will have to
+ * be disconnected before reallocating */
+
+ /* implicit: if (new_rows < old_rows) */
+ for (j = new_rows; j < old_rows; ++j)
+ for (i = 0; i < old_cols; ++i)
+ {
+ int cell = grid_cell(i, j, old_rows, old_cols);
+ object_remove_connections_to(&grid_object->cells[cell]);
+ }
+
+ /* implicit: if (new_cols < old_cols) */
+ for (i = new_cols; i < old_cols; ++i)
+ for (j = 0; j < old_cols && j < new_cols; ++j) /* don't double-delete */
+ {
+ int cell = grid_cell(i, j, old_rows, old_cols);
+ object_remove_connections_to(&grid_object->cells[cell]);
+ }
+
+ /* Can't use realloc; if grid has different dims, memory lays out
+ * differently. Must copy by hand. */
+
+ new_cells = g_malloc(new_rows * new_cols * sizeof(ConnectionPoint));
+ for (i = 0; i < new_cols; ++i)
+ for (j = 0; j < new_rows; ++j)
+ {
+ int oldloc = grid_cell(i,j,old_rows,old_cols);
+ int newloc = grid_cell(i,j,new_rows,new_cols);
+ connectionpoint_init(&new_cells[newloc], obj);
+ obj->connections[GRID_OBJECT_BASE_CONNECTION_POINTS + newloc] =
+ &new_cells[newloc];
+ if (i < old_cols && j < old_rows)
+ {
+ connectionpoint_update(&new_cells[newloc], &grid_object->cells[oldloc]);
+ }
+ }
+
+ g_free(grid_object->cells);
+ grid_object->cells = new_cells;
+ grid_object->cells_rows = new_rows;
+ grid_object->cells_cols = new_cols;
+}
+
+static void
+grid_object_destroy(Grid_Object *grid_object)
+{
+ element_destroy(&grid_object->element);
+ g_free(grid_object->cells);
+}
+
+static DiaObject *
+grid_object_load(ObjectNode obj_node, int version, const char *filename)
+{
+ return object_load_using_properties(&grid_object_type,
+ obj_node,version,filename);
+}
Modified: trunk/objects/Misc/libmisc.c
==============================================================================
--- trunk/objects/Misc/libmisc.c (original)
+++ trunk/objects/Misc/libmisc.c Sat Jan 31 21:18:59 2009
@@ -29,6 +29,7 @@
#include "plug-ins.h"
extern DiaObjectType analog_clock_type;
+extern DiaObjectType grid_object_type;
extern DiaObjectType tree_type;
extern DiaObjectType measure_type;
@@ -42,6 +43,7 @@
return DIA_PLUGIN_INIT_ERROR;
object_register_type(&analog_clock_type);
+ object_register_type(&grid_object_type);
object_register_type(&tree_type);
object_register_type(&measure_type);
Added: trunk/objects/Misc/pixmaps/grid_object.xpm
==============================================================================
--- (empty file)
+++ trunk/objects/Misc/pixmaps/grid_object.xpm Sat Jan 31 21:18:59 2009
@@ -0,0 +1,28 @@
+/* XPM */
+static char * grid_object_xpm[] = {
+"22 22 3 1",
+" c None",
+". c #000000",
+"% c #C0C0C0",
+" ",
+" ................... ",
+" .%%%%%.%%%%%.%%%%%. ",
+" .% .% .% . ",
+" .% .% .% . ",
+" .% .% .% . ",
+" .% .% .% . ",
+" ................... ",
+" .%%%%%.%%%%%.%%%%%. ",
+" .% .% .% . ",
+" .% .% .% . ",
+" .% .% .% . ",
+" .% .% .% . ",
+" ................... ",
+" .%%%%%.%%%%%.%%%%%. ",
+" .% .% .% . ",
+" .% .% .% . ",
+" .% .% .% . ",
+" .% .% .% . ",
+" ................... ",
+" ",
+" "};
Modified: trunk/sheets/Misc.sheet.in
==============================================================================
--- trunk/sheets/Misc.sheet.in (original)
+++ trunk/sheets/Misc.sheet.in Sat Jan 31 21:18:59 2009
@@ -24,6 +24,9 @@
<object name="Misc - Measure" intdata="0">
<_description>Measure distance</_description>
</object>
+ <object name="Misc - Grid">
+ <_description>Resizable grid</_description>
+ </object>
<object name="Misc - NewGroup">
<_description>New-style group object, for testing</_description>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]