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

PATCH: radio cell and mobile base station



Hi,

I already sent a similar patch a few weeks ago, but
fortunately it hasn't been applied :-) In the original
patch, the base station was implemented as shape, which was
not very nice.  Now I did both base station and radio cell
as an object.  An example for the use of both elements is
attached separately.

Please apply this patch and forget the older version!

Cheers,
-- 
W. Borgert <debacle@debian.org>
diff -ruN dia/objects/network/basestation.c dia.new/objects/network/basestation.c
--- dia/objects/network/basestation.c	1970-01-01 00:00:00.000000000 +0000
+++ dia.new/objects/network/basestation.c	2003-12-07 17:25:13.000000000 +0000
@@ -0,0 +1,430 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * 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.
+ */
+
+/* Copyright 2003, W. Borgert <debacle@debian.org>
+   copied a lot from UML/actor.c */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+
+#include "intl.h"
+#include "object.h"
+#include "element.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "text.h"
+#include "properties.h"
+
+#include "pixmaps/basestation.xpm"
+
+typedef struct _Basestation Basestation;
+struct _Basestation {
+  Element element;
+
+  ConnectionPoint connections[8];
+
+  Color line_colour;
+  Color fill_colour;
+
+  Text *text;
+  TextAttributes attrs;
+
+  int sectors;			/* oftenly 3 or 4, always >= 1, but
+				   check is missing */
+};
+
+#define BASESTATION_WIDTH 0.8
+#define BASESTATION_HEIGHT 4.0
+#define BASESTATION_LINEWIDTH 0.1
+
+static real basestation_distance_from(Basestation *basestation,
+                                      Point *point);
+static void basestation_select(Basestation *basestation,
+                               Point *clicked_point,
+                               DiaRenderer *interactive_renderer);
+static ObjectChange
+    *basestation_move_handle(Basestation *basestation, Handle *handle,
+                             Point *to, ConnectionPoint *cp,
+                             HandleMoveReason reason,
+                             ModifierKeys modifiers);
+static ObjectChange *basestation_move(Basestation *basestation, Point *to);
+static void basestation_draw(Basestation *basestation,
+                             DiaRenderer *renderer);
+static Object *basestation_create(Point *startpoint,
+                                  void *user_data,
+                                  Handle **handle1,
+                                  Handle **handle2);
+static void basestation_destroy(Basestation *basestation);
+static Object *basestation_load(ObjectNode obj_node,
+                                int version,
+                                const char *filename);
+static PropDescription
+    *basestation_describe_props(Basestation *basestation);
+static void basestation_get_props(Basestation *basestation,
+                                  GPtrArray *props);
+static void basestation_set_props(Basestation *basestation,
+                                  GPtrArray *props);
+static void basestation_update_data(Basestation *basestation);
+
+static ObjectTypeOps basestation_type_ops =
+  {
+    (CreateFunc) basestation_create,
+    (LoadFunc)   basestation_load,
+    (SaveFunc)   object_save_using_properties,
+    (GetDefaultsFunc)   NULL,
+    (ApplyDefaultsFunc) NULL
+  };
+
+ObjectType basestation_type =
+  {
+    "Network - Base Station",   /* name */
+    0,                          /* version */
+    (char **) basestation_xpm,  /* pixmap */
+
+    &basestation_type_ops       /* ops */
+  };
+
+static ObjectOps basestation_ops = {
+  (DestroyFunc)         basestation_destroy,
+  (DrawFunc)            basestation_draw,
+  (DistanceFunc)        basestation_distance_from,
+  (SelectFunc)          basestation_select,
+  (CopyFunc)            object_copy_using_properties,
+  (MoveFunc)            basestation_move,
+  (MoveHandleFunc)      basestation_move_handle,
+  (GetPropertiesFunc)   object_create_props_dialog,
+  (ApplyPropertiesFunc) object_apply_props_from_dialog,
+  (ObjectMenuFunc)      NULL,
+  (DescribePropsFunc)   basestation_describe_props,
+  (GetPropsFunc)        basestation_get_props,
+  (SetPropsFunc)        basestation_set_props,
+};
+
+static PropDescription basestation_props[] = {
+  ELEMENT_COMMON_PROPERTIES,
+  PROP_STD_LINE_COLOUR,
+  PROP_STD_FILL_COLOUR,
+  PROP_STD_TEXT_FONT,
+  PROP_STD_TEXT_HEIGHT,
+  PROP_STD_TEXT_COLOUR,
+  PROP_STD_TEXT_ALIGNMENT,
+  { "text", PROP_TYPE_TEXT, 0, N_("Text"), NULL, NULL },
+  { "sectors", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+    N_("Sectors"), NULL, NULL },
+  PROP_DESC_END
+};
+
+static PropDescription *
+basestation_describe_props(Basestation *basestation)
+{
+  if (basestation_props[0].quark == 0) {
+    prop_desc_list_calculate_quarks(basestation_props);
+  }
+  return basestation_props;
+}
+
+static PropOffset basestation_offsets[] = {
+  ELEMENT_COMMON_PROPERTIES_OFFSETS,
+  {"line_colour", PROP_TYPE_COLOUR, offsetof(Basestation, line_colour)},
+  {"fill_colour", PROP_TYPE_COLOUR, offsetof(Basestation, fill_colour)},
+  {"text", PROP_TYPE_TEXT, offsetof(Basestation, text)},
+  {"text_font", PROP_TYPE_FONT, offsetof(Basestation, attrs.font)},
+  {"text_height", PROP_TYPE_REAL, offsetof(Basestation, attrs.height)},
+  {"text_colour", PROP_TYPE_COLOUR, offsetof(Basestation, attrs.color)},
+  {"text_alignment", PROP_TYPE_ENUM,
+   offsetof(Basestation, attrs.alignment)},
+  {"sectors", PROP_TYPE_INT, offsetof(Basestation, sectors)},
+  { NULL, 0, 0 },
+};
+
+static void
+basestation_get_props(Basestation * basestation, GPtrArray *props)
+{
+  text_get_attributes(basestation->text,&basestation->attrs);
+  object_get_props_from_offsets(&basestation->element.object,
+                                basestation_offsets,props);
+}
+
+static void
+basestation_set_props(Basestation *basestation, GPtrArray *props)
+{
+  object_set_props_from_offsets(&basestation->element.object,
+                                basestation_offsets, props);
+  apply_textattr_properties(props,basestation->text,
+                            "text", &basestation->attrs);
+  basestation_update_data(basestation);
+}
+
+static real
+basestation_distance_from(Basestation *basestation, Point *point)
+{
+  Object *obj = &basestation->element.object;
+  return distance_rectangle_point(&obj->bounding_box, point);
+}
+
+static void
+basestation_select(Basestation *basestation, Point *clicked_point,
+                   DiaRenderer *interactive_renderer)
+{
+  text_set_cursor(basestation->text, clicked_point, interactive_renderer);
+  text_grab_focus(basestation->text, &basestation->element.object);
+  element_update_handles(&basestation->element);
+}
+
+static ObjectChange*
+basestation_move_handle(Basestation *basestation, Handle *handle,
+                        Point *to, ConnectionPoint *cp,
+                        HandleMoveReason reason, ModifierKeys modifiers)
+{
+  assert(basestation!=NULL);
+  assert(handle!=NULL);
+  assert(to!=NULL);
+
+  assert(handle->id < 8);
+
+  return NULL;
+}
+
+static ObjectChange*
+basestation_move(Basestation *basestation, Point *to)
+{
+  Element *elem = &basestation->element;
+
+  elem->corner = *to;
+  elem->corner.x -= elem->width/2.0;
+  elem->corner.y -= elem->height / 2.0;
+
+  basestation_update_data(basestation);
+
+  return NULL;
+}
+
+static void
+basestation_draw(Basestation *basestation, DiaRenderer *renderer)
+{
+  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+  Element *elem;
+  real x, y, w, h;
+  real r = BASESTATION_WIDTH/2.0;
+  Point ct, cb, p1, p2;
+  Point points[6];
+
+  assert(basestation != NULL);
+  assert(renderer != NULL);
+
+  elem = &basestation->element;
+
+  x = elem->corner.x;
+  y = elem->corner.y + r;
+  w = elem->width;
+  h = elem->height - r;
+
+  renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
+  renderer_ops->set_linejoin(renderer, LINEJOIN_ROUND);
+  renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
+  renderer_ops->set_linewidth(renderer, BASESTATION_LINEWIDTH);
+
+  ct.x = x + w/2.0;
+  ct.y = y + r/2.0;
+  cb.x = ct.x;
+  cb.y = ct.y + h - r;
+
+  /* antenna 1 */
+  points[0] = ct; points[0].x -= r/4.0; points[0].y -= 3.0*r/4.0;
+  points[1] = ct; points[1].x += r/4.0; points[1].y -= 3.0*r/4.0;
+  points[2] = ct; points[2].x += r/4.0; points[2].y += 1.0;
+  points[3] = ct; points[3].x -= r/4.0; points[3].y += 1.0;
+  renderer_ops->fill_polygon(renderer, points, 4,
+                             &basestation->fill_colour);
+  renderer_ops->draw_polygon(renderer, points, 4,
+                             &basestation->line_colour);
+  /* bottom */
+  renderer_ops->fill_ellipse(renderer, &cb, r, r/2.0,
+                             &basestation->fill_colour);
+  renderer_ops->draw_arc(renderer, &cb, r, r/2.0, 180, 0,
+                         &basestation->line_colour);
+  /* bar */
+  p1 = ct;
+  p1.x -= r/2.0;
+  p2 = cb;
+  p2.x += r/2.0;
+  renderer_ops->fill_rect(renderer, &p1, &p2,
+                          &basestation->fill_colour);
+  p2.x -= r;
+  renderer_ops->draw_line(renderer, &p1, &p2,
+                          &basestation->line_colour);
+  p1.x += r;
+  p2.x += r;
+  renderer_ops->draw_line(renderer, &p1, &p2,
+                          &basestation->line_colour);
+  /* top */
+  renderer_ops->fill_ellipse(renderer, &ct, r, r/2.0,
+                             &basestation->fill_colour);
+  renderer_ops->draw_ellipse(renderer, &ct, r, r/2.0,
+                             &basestation->line_colour);
+  /* antenna 2 */
+  points[0] = ct; points[0].x += r/4.0;   points[0].y -= 0;
+  points[1] = ct; points[1].x += 3.0*r/4.0; points[1].y -= r/2.0;
+  points[2] = ct; points[2].x += 3.0*r/4.0; points[2].y += 1.0 - r/2.0;
+  points[3] = ct; points[3].x += r/4.0;   points[3].y += 1.0;
+  renderer_ops->fill_polygon(renderer, points, 4,
+                             &basestation->fill_colour);
+  renderer_ops->draw_polygon(renderer, points, 4,
+                             &basestation->line_colour);
+  /* antenna 3 */
+  points[0] = ct; points[0].x -= r/4.0;   points[0].y -= 0;
+  points[1] = ct; points[1].x -= 3.0*r/4.0; points[1].y -= r/2.0;
+  points[2] = ct; points[2].x -= 3.0*r/4.0; points[2].y += 1.0 - r/2.0;
+  points[3] = ct; points[3].x -= r/4.0;   points[3].y += 1.0;
+  renderer_ops->fill_polygon(renderer, points, 4,
+                             &basestation->fill_colour);
+  renderer_ops->draw_polygon(renderer, points, 4,
+                             &basestation->line_colour);
+  text_draw(basestation->text, renderer);
+}
+
+static void
+basestation_update_data(Basestation *basestation)
+{
+  Element *elem = &basestation->element;
+  Object *obj = &elem->object;
+  Rectangle text_box;
+  Point p;
+
+  text_calc_boundingbox(basestation->text, &text_box);
+
+  elem->width = BASESTATION_WIDTH;
+  elem->height = BASESTATION_HEIGHT+basestation->text->height;
+
+  /* Update connections: */
+  basestation->connections[0].pos.x = elem->corner.x;
+  basestation->connections[0].pos.y = elem->corner.y;
+  basestation->connections[0].directions = DIR_NORTH|DIR_WEST;
+  basestation->connections[1].pos.x = elem->corner.x + elem->width / 2.0;
+  basestation->connections[1].pos.y = elem->corner.y;
+  basestation->connections[1].directions = DIR_NORTH;
+  basestation->connections[2].pos.x = elem->corner.x + elem->width;
+  basestation->connections[2].pos.y = elem->corner.y;
+  basestation->connections[2].directions = DIR_NORTH|DIR_EAST;
+  basestation->connections[3].pos.x = elem->corner.x;
+  basestation->connections[3].pos.y = elem->corner.y + elem->height / 2.0;
+  basestation->connections[3].directions = DIR_WEST;
+  basestation->connections[4].pos.x = elem->corner.x + elem->width;
+  basestation->connections[4].pos.y = elem->corner.y + elem->height / 2.0;
+  basestation->connections[4].directions = DIR_EAST;
+  basestation->connections[5].pos.x = elem->corner.x;
+  basestation->connections[5].pos.y = elem->corner.y + elem->height;
+  basestation->connections[5].directions = DIR_SOUTH|DIR_WEST;
+  basestation->connections[6].pos.x = elem->corner.x + elem->width / 2.0;
+  basestation->connections[6].pos.y = elem->corner.y + elem->height;
+  basestation->connections[6].directions = DIR_SOUTH;
+  basestation->connections[7].pos.x = elem->corner.x + elem->width;
+  basestation->connections[7].pos.y = elem->corner.y + elem->height;
+  basestation->connections[7].directions = DIR_SOUTH|DIR_EAST;
+
+  element_update_boundingbox(elem);
+
+  p = elem->corner;
+  p.x += elem->width/2;
+  p.y += elem->height + basestation->text->ascent;
+  text_set_position(basestation->text, &p);
+
+  /* Add bounding box for text: */
+  rectangle_union(&obj->bounding_box, &text_box);
+
+  obj->position = elem->corner;
+  obj->position.x += elem->width/2.0;
+  obj->position.y += elem->height/2.0;
+
+  element_update_handles(elem);
+}
+
+static Object *
+basestation_create(Point *startpoint,
+                   void *user_data,
+                   Handle **handle1,
+                   Handle **handle2)
+{
+  Basestation *basestation;
+  Element *elem;
+  Object *obj;
+  Point p;
+  DiaFont *font;
+  int i;
+
+  basestation = g_new0(Basestation, 1);
+  elem = &basestation->element;
+  obj = &elem->object;
+
+  obj->type = &basestation_type;
+  obj->ops = &basestation_ops;
+  elem->corner = *startpoint;
+  elem->width = BASESTATION_WIDTH;
+  elem->height = BASESTATION_HEIGHT;
+
+  font = dia_font_new_from_style (DIA_FONT_MONOSPACE, 0.8);
+  p = *startpoint;
+  p.y += BASESTATION_HEIGHT -
+    dia_font_descent(_("Base Station"), font, 0.8);
+
+  basestation->text = new_text(_("Base Station"),
+                               font, 0.8, &p, &color_black, ALIGN_CENTER);
+  dia_font_unref(font);
+  text_get_attributes(basestation->text,&basestation->attrs);
+  basestation->line_colour = color_black;
+  basestation->fill_colour = color_white;
+  basestation->sectors = 3;
+
+  element_init(elem, 8, 8);
+
+  for (i=0; i<8; i++) {
+    obj->connections[i] = &basestation->connections[i];
+    basestation->connections[i].object = obj;
+    basestation->connections[i].connected = NULL;
+  }
+  elem->extra_spacing.border_trans = BASESTATION_LINEWIDTH/2.0;
+  basestation_update_data(basestation);
+
+  for (i=0; i<8; i++) {
+    obj->handles[i]->type = HANDLE_NON_MOVABLE;
+  }
+
+  *handle1 = NULL;
+  *handle2 = NULL;
+  return &basestation->element.object;
+}
+
+static void
+basestation_destroy(Basestation *basestation)
+{
+  text_destroy(basestation->text);
+
+  element_destroy(&basestation->element);
+}
+
+static Object *
+basestation_load(ObjectNode obj_node, int version, const char *filename)
+{
+  return object_load_using_properties(&basestation_type,
+                                      obj_node, version, filename);
+}
diff -ruN dia/objects/network/Makefile.am dia.new/objects/network/Makefile.am
--- dia/objects/network/Makefile.am	2003-12-07 17:15:01.000000000 +0000
+++ dia.new/objects/network/Makefile.am	2003-12-07 17:15:40.000000000 +0000
@@ -5,6 +5,8 @@
 			      network.h \
 			      network.c \
 			      bus.c \
+			      radiocell.c \
+			      basestation.c \
 			      wanlink.c 
 
 libnetwork_objects_la_LDFLAGS = -export-dynamic -module -avoid-version
@@ -17,6 +19,8 @@
 	pixmaps/computer.xpm \
 	pixmaps/disc.xpm \
 	pixmaps/flash.xpm \
+	pixmaps/radiocell.xpm \
+	pixmaps/basestation.xpm \
 	pixmaps/wanlink.xpm \
 	pixmaps/hub.xpm \
 	pixmaps/modem.xpm \
diff -ruN dia/objects/network/network.c dia.new/objects/network/network.c
--- dia/objects/network/network.c	2003-12-07 17:15:12.000000000 +0000
+++ dia.new/objects/network/network.c	2003-12-07 17:15:46.000000000 +0000
@@ -31,6 +31,8 @@
 
 extern ObjectType bus_type;
 extern ObjectType bus_type_std;
+extern ObjectType radiocell_type;
+extern ObjectType basestation_type;
 extern ObjectType wanlink_type;
 
 DIA_PLUGIN_CHECK_INIT
@@ -44,6 +46,8 @@
 
   object_register_type(&bus_type_std);
   object_register_type(&bus_type);
+  object_register_type(&radiocell_type);
+  object_register_type(&basestation_type);
   object_register_type(&wanlink_type);
 
   return DIA_PLUGIN_INIT_OK;
diff -ruN dia/objects/network/pixmaps/basestation.xpm dia.new/objects/network/pixmaps/basestation.xpm
--- dia/objects/network/pixmaps/basestation.xpm	1970-01-01 00:00:00.000000000 +0000
+++ dia.new/objects/network/pixmaps/basestation.xpm	2003-12-07 17:16:16.000000000 +0000
@@ -0,0 +1,28 @@
+/* XPM */
+static char * basestation_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"       .     .        ",
+"       .. . ..        ",
+"       .+.+.+.        ",
+"       .+.+.+.        ",
+"       .+.+.+.        ",
+"       .+.+.+.        ",
+"        ..+..         ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"         .+.          ",
+"          .           "};
diff -ruN dia/objects/network/pixmaps/radiocell.xpm dia.new/objects/network/pixmaps/radiocell.xpm
--- dia/objects/network/pixmaps/radiocell.xpm	1970-01-01 00:00:00.000000000 +0000
+++ dia.new/objects/network/pixmaps/radiocell.xpm	2003-12-07 17:16:10.000000000 +0000
@@ -0,0 +1,28 @@
+/* XPM */
+static char * radiocell_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"                      ",
+"      ..........      ",
+"     .++++++++++.     ",
+"     .++++++++++.     ",
+"    .++++++++++++.    ",
+"   .++++++++++++++.   ",
+"   .++++++++++++++.   ",
+"  .++++++++++++++++.  ",
+" .++++++++++++++++++. ",
+" .++++++++++++++++++. ",
+".++++++++++++++++++++.",
+".++++++++++++++++++++.",
+" .++++++++++++++++++. ",
+" .++++++++++++++++++. ",
+"  .++++++++++++++++.  ",
+"   .++++++++++++++.   ",
+"   .++++++++++++++.   ",
+"    .++++++++++++.    ",
+"     .++++++++++.     ",
+"     .++++++++++.     ",
+"      ..........      ",
+"                      "};
diff -ruN dia/objects/network/radiocell.c dia.new/objects/network/radiocell.c
--- dia/objects/network/radiocell.c	1970-01-01 00:00:00.000000000 +0000
+++ dia.new/objects/network/radiocell.c	2003-12-07 17:25:06.000000000 +0000
@@ -0,0 +1,380 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * 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.
+ */
+
+/* Copyright 2003, W. Borgert <debacle@debian.org>
+   copied a lot from UML/large_package.c and standard/polygon.c */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+
+#include "intl.h"
+#include "object.h"
+#include "polyshape.h"
+#include "diarenderer.h"
+#include "attributes.h"
+#include "text.h"
+#include "properties.h"
+
+#include "network.h"
+
+#include "pixmaps/radiocell.xpm"
+
+/* TODO? no visual effect ATM, but useful anyway */
+typedef enum {
+  MACRO_CELL,
+  MICRO_CELL,
+  PICO_CELL,
+} CellType;
+
+/* TODO: add different cell technologies, like GSM, UMTS, ... */
+
+typedef struct _RadioCell RadioCell;
+
+struct _RadioCell {
+  PolyShape poly;		/* always 1st! */
+  CellType celltype;
+  real radius;			/* pseudo-radius */
+  ConnectionPoint cp;		/* connection point in the center */
+  Color line_colour;
+  LineStyle line_style;
+  real dashlength;
+  real line_width;
+  gboolean show_background;
+  Color fill_colour;
+  Text *text;
+  TextAttributes attrs;
+  int subscribers;		/* number of subscribers in this cell,
+				   always >= 0, but check is missing */
+};
+
+#define RADIOCELL_LINEWIDTH  0.1
+#define RADIOCELL_FONTHEIGHT 0.8
+
+static real radiocell_distance_from(RadioCell *radiocell, Point *point);
+static void radiocell_select(RadioCell *radiocell, Point *clicked_point,
+			     DiaRenderer *interactive_renderer);
+static ObjectChange* radiocell_move_handle(RadioCell *radiocell,
+					   Handle *handle,
+					   Point *to, ConnectionPoint *cp,
+					   HandleMoveReason reason,
+					   ModifierKeys modifiers);
+static ObjectChange* radiocell_move(RadioCell *radiocell, Point *to);
+static void radiocell_draw(RadioCell *radiocell, DiaRenderer *renderer);
+static Object *radiocell_create(Point *startpoint,
+				void *user_data,
+				Handle **handle1,
+				Handle **handle2);
+static void radiocell_destroy(RadioCell *radiocell);
+static void radiocell_update_data(RadioCell *radiocell);
+static PropDescription *radiocell_describe_props(RadioCell *radiocell);
+static void radiocell_get_props(RadioCell *radiocell, GPtrArray *props);
+static void radiocell_set_props(RadioCell *radiocell, GPtrArray *props);
+static Object *radiocell_load(ObjectNode obj_node, int version,
+			      const char *filename);
+
+static ObjectTypeOps radiocell_type_ops =
+{
+  (CreateFunc)        radiocell_create,
+  (LoadFunc)          radiocell_load,
+  (SaveFunc)          object_save_using_properties,
+  (GetDefaultsFunc)   NULL,
+  (ApplyDefaultsFunc) NULL
+};
+
+ObjectType radiocell_type =
+{
+  "Network - Radio Cell",	/* name */
+  0,				/* version */
+  (char **) radiocell_xpm,	/* pixmap */
+
+  &radiocell_type_ops		/* ops */
+};
+
+static ObjectOps radiocell_ops = {
+  (DestroyFunc)         radiocell_destroy,
+  (DrawFunc)            radiocell_draw,
+  (DistanceFunc)        radiocell_distance_from,
+  (SelectFunc)          radiocell_select,
+  (CopyFunc)            object_copy_using_properties,
+  (MoveFunc)            radiocell_move,
+  (MoveHandleFunc)      radiocell_move_handle,
+  (GetPropertiesFunc)   object_create_props_dialog,
+  (ApplyPropertiesFunc) object_apply_props_from_dialog,
+  (ObjectMenuFunc)      NULL,
+  (DescribePropsFunc)   radiocell_describe_props,
+  (GetPropsFunc)        radiocell_get_props,
+  (SetPropsFunc)        radiocell_set_props
+};
+
+static PropEnumData prop_cell_type_data[] = {
+  { N_("Macro Cell"), MACRO_CELL },
+  { N_("Micro Cell"), MICRO_CELL },
+  { N_("Pico Cell"),  PICO_CELL },
+  { NULL, 0}
+};
+
+static PropDescription radiocell_props[] = {
+  POLYSHAPE_COMMON_PROPERTIES,
+  { "radius", PROP_TYPE_REAL, 0, N_("Radius"), NULL, NULL },
+  { "celltype", PROP_TYPE_ENUM, PROP_FLAG_VISIBLE,
+    N_("Cell Type:"), NULL, prop_cell_type_data },
+  PROP_STD_LINE_WIDTH,
+  PROP_STD_LINE_COLOUR,
+  PROP_STD_LINE_STYLE,
+  PROP_STD_FILL_COLOUR,
+  PROP_STD_SHOW_BACKGROUND,
+  { "text", PROP_TYPE_TEXT, 0, N_("Text"), NULL, NULL },
+  PROP_STD_TEXT_FONT,
+  PROP_STD_TEXT_HEIGHT,
+  PROP_STD_TEXT_COLOUR,
+  PROP_STD_TEXT_ALIGNMENT,
+  { "subscribers", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+    N_("Subscribers"), NULL, NULL },
+  PROP_DESC_END
+};
+
+static PropDescription *
+radiocell_describe_props(RadioCell *radiocell)
+{
+  if (radiocell_props[0].quark == 0) {
+    prop_desc_list_calculate_quarks(radiocell_props);
+  }
+  return radiocell_props;
+}
+
+static PropOffset radiocell_offsets[] = {
+  POLYSHAPE_COMMON_PROPERTIES_OFFSETS,
+  { "radius", PROP_TYPE_REAL, offsetof(RadioCell, radius) },
+  { "celltype", PROP_TYPE_ENUM, offsetof(RadioCell, celltype) },
+  { "line_width", PROP_TYPE_REAL, offsetof(RadioCell, line_width) },
+  { "line_colour", PROP_TYPE_COLOUR, offsetof(RadioCell, line_colour) },
+  { "line_style", PROP_TYPE_LINESTYLE,
+    offsetof(RadioCell, line_style), offsetof(RadioCell, dashlength) },
+  { "fill_colour", PROP_TYPE_COLOUR, offsetof(RadioCell, fill_colour) },
+  { "show_background", PROP_TYPE_BOOL,
+    offsetof(RadioCell, show_background) },
+  { "text", PROP_TYPE_TEXT, offsetof(RadioCell, text) },
+  { "text_font", PROP_TYPE_FONT, offsetof(RadioCell, attrs.font) },
+  { "text_height", PROP_TYPE_REAL, offsetof(RadioCell, attrs.height) },
+  { "text_colour", PROP_TYPE_COLOUR, offsetof(RadioCell, attrs.color) },
+  { "text_alignment", PROP_TYPE_ENUM,
+    offsetof(RadioCell, attrs.alignment) },
+  { "subscribers", PROP_TYPE_INT, offsetof(RadioCell, subscribers) },
+  { NULL, 0, 0 },
+};
+
+static void
+radiocell_get_props(RadioCell *radiocell, GPtrArray *props)
+{
+  text_get_attributes(radiocell->text, &radiocell->attrs);
+  object_get_props_from_offsets(&radiocell->poly.object,
+                                radiocell_offsets, props);
+}
+
+static void
+radiocell_set_props(RadioCell *radiocell, GPtrArray *props)
+{
+  object_set_props_from_offsets(&radiocell->poly.object,
+                                radiocell_offsets, props);
+  apply_textattr_properties(props, radiocell->text,
+			    "text", &radiocell->attrs);
+  radiocell_update_data(radiocell);
+}
+
+static real
+radiocell_distance_from(RadioCell *radiocell, Point *point)
+{
+  return polyshape_distance_from(&radiocell->poly, point,
+				 radiocell->line_width);
+}
+
+static void
+radiocell_select(RadioCell *radiocell, Point *clicked_point,
+		 DiaRenderer *interactive_renderer)
+{
+  text_set_cursor(radiocell->text, clicked_point, interactive_renderer);
+  text_grab_focus(radiocell->text, &radiocell->poly.object);
+  polyshape_update_data(&radiocell->poly);
+}
+
+static ObjectChange*
+radiocell_move_handle(RadioCell *radiocell, Handle *handle,
+		      Point *to, ConnectionPoint *cp,
+		      HandleMoveReason reason, ModifierKeys modifiers)
+{
+  real distance = distance_point_point(&handle->pos, to);
+  gboolean larger = distance_point_point(&handle->pos, &radiocell->cp.pos) <
+    distance_point_point(to, &radiocell->cp.pos);
+
+  /* TODO: this flickers terribly */
+  radiocell->radius += distance * (larger? 1: -1);
+  if (radiocell->radius < 1.)
+    radiocell->radius = 1.;
+  radiocell_update_data(radiocell);
+
+  return NULL;
+}
+
+static ObjectChange*
+radiocell_move(RadioCell *radiocell, Point *to)
+{
+  polyshape_move(&radiocell->poly, to);
+  radiocell->cp.pos = *to;
+  radiocell->cp.pos.x -= radiocell->radius;
+  radiocell_update_data(radiocell);
+
+  return NULL;
+}
+
+static void
+radiocell_draw(RadioCell *radiocell, DiaRenderer *renderer)
+{
+  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+  PolyShape *poly;
+  Point *points;
+  int n;
+
+  assert(radiocell != NULL);
+  assert(renderer != NULL);
+
+  poly = &radiocell->poly;
+  points = &poly->points[0];
+  n = poly->numpoints;
+
+  if (radiocell->show_background) {
+    renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
+    renderer_ops->fill_polygon(renderer, points, n, &radiocell->fill_colour);
+  }
+  renderer_ops->set_linecaps(renderer, LINECAPS_BUTT);
+  renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
+  renderer_ops->set_linestyle(renderer, radiocell->line_style);
+  renderer_ops->set_linewidth(renderer, radiocell->line_width);
+  renderer_ops->set_dashlength(renderer, radiocell->dashlength);
+  renderer_ops->draw_polygon(renderer, points, n, &radiocell->line_colour);
+
+  text_draw(radiocell->text, renderer);
+}
+
+static void
+radiocell_update_data(RadioCell *radiocell)
+{
+  PolyShape *poly = &radiocell->poly;
+  Object *obj = &poly->object;
+  ElementBBExtras *extra = &poly->extra_spacing;
+  Rectangle text_box;
+  Point textpos;
+  int i;
+  /* not exactly a regular hexagon, but this fits better in the grid */
+  Point points[] = { {  1., 0. }, {  .5,  .75 }, { -.5,  .75 },
+		     { -1., 0. }, { -.5, -.75 }, {  .5, -.75 } };
+
+  /* TODO: the CP is invisible and does not yet work */
+  radiocell->cp.pos.x = (poly->points[0].x + poly->points[3].x) / 2.;
+  radiocell->cp.pos.y = poly->points[0].y;
+
+  for (i = 0; i < 6; i++) {
+    poly->points[i] = radiocell->cp.pos;
+    poly->points[i].x += radiocell->radius * points[i].x;
+    poly->points[i].y += radiocell->radius * points[i].y;
+  }
+
+  /* Add bounding box for text: */
+  text_calc_boundingbox(radiocell->text, NULL);
+  textpos.x = (poly->points[0].x + poly->points[3].x) / 2.;
+  textpos.y = poly->points[0].y -
+    (radiocell->text->height * (radiocell->text->numlines - 1) +
+     radiocell->text->descent) / 2.;
+  text_set_position(radiocell->text, &textpos);
+  text_calc_boundingbox(radiocell->text, &text_box);
+  polyshape_update_data(poly);
+  extra->border_trans = radiocell->line_width / 2.0;
+  polyshape_update_boundingbox(poly);
+  rectangle_union(&obj->bounding_box, &text_box);
+  obj->position = poly->points[0];
+}
+
+static Object *
+radiocell_create(Point *startpoint,
+		 void *user_data,
+		 Handle **handle1,
+		 Handle **handle2)
+{
+  RadioCell *radiocell;
+  PolyShape *poly;
+  Object *obj;
+  DiaFont *font;
+
+  radiocell = g_new0(RadioCell, 1);
+  poly = &radiocell->poly;
+  obj = &poly->object;
+  obj->type = &radiocell_type;
+  obj->ops = &radiocell_ops;
+  obj->can_parent = TRUE;
+
+  radiocell->celltype = MACRO_CELL;
+  radiocell->radius = 4.;
+  radiocell->subscribers = 1000;
+
+  /* do not use default_properties.show_background here */
+  radiocell->show_background = FALSE;
+  radiocell->fill_colour = color_white;
+  radiocell->line_colour = color_black;
+  radiocell->line_width = RADIOCELL_LINEWIDTH;
+  attributes_get_default_line_style(&radiocell->line_style,
+				    &radiocell->dashlength);
+
+  font = dia_font_new_from_style(DIA_FONT_MONOSPACE, RADIOCELL_FONTHEIGHT);
+  radiocell->text = new_text("", font, RADIOCELL_FONTHEIGHT, startpoint,
+			     &color_black, ALIGN_CENTER);
+  dia_font_unref(font);
+  text_get_attributes(radiocell->text, &radiocell->attrs);
+
+  polyshape_init(poly, 6);
+
+  object_add_connectionpoint(&poly->object, &radiocell->cp);
+  obj->connections[0] = &radiocell->cp;
+  radiocell->cp.object = obj;
+  radiocell->cp.connected = NULL;
+  radiocell->cp.directions = DIR_ALL;
+  radiocell->cp.pos = *startpoint;
+  radiocell->cp.pos.x -= radiocell->radius;
+
+  radiocell_update_data(radiocell);
+  *handle1 = poly->object.handles[0];
+  *handle2 = poly->object.handles[2];
+  return &radiocell->poly.object;
+}
+
+static void
+radiocell_destroy(RadioCell *radiocell)
+{
+  text_destroy(radiocell->text);
+  polyshape_destroy(&radiocell->poly);
+}
+
+static Object *
+radiocell_load(ObjectNode obj_node, int version, const char *filename)
+{
+  return object_load_using_properties(&radiocell_type,
+                                      obj_node, version, filename);
+}

UMTS-network.dia.bz2



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] Mail converted by Mofo Magic and the Flying D

 
All trademarks and copyrights are the property of their respective owners.

Other Directory Sites: SeekWonder | Directory Owners Forum

GuideSMACK