• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


コミットメタ情報

リビジョン6dd3ff6dc6138118aaede44dec6c7d3b59aafb18 (tree)
日時2004-05-06 17:01:45
作者Lars Clausen <lclausen@src....>
コミッターLars Clausen

ログメッセージ

Forgot to add these files.

変更サマリ

差分

--- /dev/null
+++ b/objects/network/basestation.c
@@ -0,0 +1,430 @@
1+/* Dia -- an diagram creation/manipulation program
2+ * Copyright (C) 1998 Alexander Larsson
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; either version 2 of the License, or
7+ * (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program; if not, write to the Free Software
16+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17+ */
18+
19+/* Copyright 2003, W. Borgert <debacle@debian.org>
20+ copied a lot from UML/actor.c */
21+
22+#ifdef HAVE_CONFIG_H
23+#include <config.h>
24+#endif
25+
26+#include <assert.h>
27+#include <math.h>
28+#include <string.h>
29+
30+#include "intl.h"
31+#include "object.h"
32+#include "element.h"
33+#include "diarenderer.h"
34+#include "attributes.h"
35+#include "text.h"
36+#include "properties.h"
37+
38+#include "pixmaps/basestation.xpm"
39+
40+typedef struct _Basestation Basestation;
41+struct _Basestation {
42+ Element element;
43+
44+ ConnectionPoint connections[8];
45+
46+ Color line_colour;
47+ Color fill_colour;
48+
49+ Text *text;
50+ TextAttributes attrs;
51+
52+ int sectors; /* oftenly 3 or 4, always >= 1, but
53+ check is missing */
54+};
55+
56+#define BASESTATION_WIDTH 0.8
57+#define BASESTATION_HEIGHT 4.0
58+#define BASESTATION_LINEWIDTH 0.1
59+
60+static real basestation_distance_from(Basestation *basestation,
61+ Point *point);
62+static void basestation_select(Basestation *basestation,
63+ Point *clicked_point,
64+ DiaRenderer *interactive_renderer);
65+static ObjectChange
66+ *basestation_move_handle(Basestation *basestation, Handle *handle,
67+ Point *to, ConnectionPoint *cp,
68+ HandleMoveReason reason,
69+ ModifierKeys modifiers);
70+static ObjectChange *basestation_move(Basestation *basestation, Point *to);
71+static void basestation_draw(Basestation *basestation,
72+ DiaRenderer *renderer);
73+static Object *basestation_create(Point *startpoint,
74+ void *user_data,
75+ Handle **handle1,
76+ Handle **handle2);
77+static void basestation_destroy(Basestation *basestation);
78+static Object *basestation_load(ObjectNode obj_node,
79+ int version,
80+ const char *filename);
81+static PropDescription
82+ *basestation_describe_props(Basestation *basestation);
83+static void basestation_get_props(Basestation *basestation,
84+ GPtrArray *props);
85+static void basestation_set_props(Basestation *basestation,
86+ GPtrArray *props);
87+static void basestation_update_data(Basestation *basestation);
88+
89+static ObjectTypeOps basestation_type_ops =
90+ {
91+ (CreateFunc) basestation_create,
92+ (LoadFunc) basestation_load,
93+ (SaveFunc) object_save_using_properties,
94+ (GetDefaultsFunc) NULL,
95+ (ApplyDefaultsFunc) NULL
96+ };
97+
98+ObjectType basestation_type =
99+ {
100+ "Network - Base Station", /* name */
101+ 0, /* version */
102+ (char **) basestation_xpm, /* pixmap */
103+
104+ &basestation_type_ops /* ops */
105+ };
106+
107+static ObjectOps basestation_ops = {
108+ (DestroyFunc) basestation_destroy,
109+ (DrawFunc) basestation_draw,
110+ (DistanceFunc) basestation_distance_from,
111+ (SelectFunc) basestation_select,
112+ (CopyFunc) object_copy_using_properties,
113+ (MoveFunc) basestation_move,
114+ (MoveHandleFunc) basestation_move_handle,
115+ (GetPropertiesFunc) object_create_props_dialog,
116+ (ApplyPropertiesFunc) object_apply_props_from_dialog,
117+ (ObjectMenuFunc) NULL,
118+ (DescribePropsFunc) basestation_describe_props,
119+ (GetPropsFunc) basestation_get_props,
120+ (SetPropsFunc) basestation_set_props,
121+};
122+
123+static PropDescription basestation_props[] = {
124+ ELEMENT_COMMON_PROPERTIES,
125+ PROP_STD_LINE_COLOUR,
126+ PROP_STD_FILL_COLOUR,
127+ PROP_STD_TEXT_FONT,
128+ PROP_STD_TEXT_HEIGHT,
129+ PROP_STD_TEXT_COLOUR,
130+ PROP_STD_TEXT_ALIGNMENT,
131+ { "text", PROP_TYPE_TEXT, 0, N_("Text"), NULL, NULL },
132+ { "sectors", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
133+ N_("Sectors"), NULL, NULL },
134+ PROP_DESC_END
135+};
136+
137+static PropDescription *
138+basestation_describe_props(Basestation *basestation)
139+{
140+ if (basestation_props[0].quark == 0) {
141+ prop_desc_list_calculate_quarks(basestation_props);
142+ }
143+ return basestation_props;
144+}
145+
146+static PropOffset basestation_offsets[] = {
147+ ELEMENT_COMMON_PROPERTIES_OFFSETS,
148+ {"line_colour", PROP_TYPE_COLOUR, offsetof(Basestation, line_colour)},
149+ {"fill_colour", PROP_TYPE_COLOUR, offsetof(Basestation, fill_colour)},
150+ {"text", PROP_TYPE_TEXT, offsetof(Basestation, text)},
151+ {"text_font", PROP_TYPE_FONT, offsetof(Basestation, attrs.font)},
152+ {"text_height", PROP_TYPE_REAL, offsetof(Basestation, attrs.height)},
153+ {"text_colour", PROP_TYPE_COLOUR, offsetof(Basestation, attrs.color)},
154+ {"text_alignment", PROP_TYPE_ENUM,
155+ offsetof(Basestation, attrs.alignment)},
156+ {"sectors", PROP_TYPE_INT, offsetof(Basestation, sectors)},
157+ { NULL, 0, 0 },
158+};
159+
160+static void
161+basestation_get_props(Basestation * basestation, GPtrArray *props)
162+{
163+ text_get_attributes(basestation->text,&basestation->attrs);
164+ object_get_props_from_offsets(&basestation->element.object,
165+ basestation_offsets,props);
166+}
167+
168+static void
169+basestation_set_props(Basestation *basestation, GPtrArray *props)
170+{
171+ object_set_props_from_offsets(&basestation->element.object,
172+ basestation_offsets, props);
173+ apply_textattr_properties(props,basestation->text,
174+ "text", &basestation->attrs);
175+ basestation_update_data(basestation);
176+}
177+
178+static real
179+basestation_distance_from(Basestation *basestation, Point *point)
180+{
181+ Object *obj = &basestation->element.object;
182+ return distance_rectangle_point(&obj->bounding_box, point);
183+}
184+
185+static void
186+basestation_select(Basestation *basestation, Point *clicked_point,
187+ DiaRenderer *interactive_renderer)
188+{
189+ text_set_cursor(basestation->text, clicked_point, interactive_renderer);
190+ text_grab_focus(basestation->text, &basestation->element.object);
191+ element_update_handles(&basestation->element);
192+}
193+
194+static ObjectChange*
195+basestation_move_handle(Basestation *basestation, Handle *handle,
196+ Point *to, ConnectionPoint *cp,
197+ HandleMoveReason reason, ModifierKeys modifiers)
198+{
199+ assert(basestation!=NULL);
200+ assert(handle!=NULL);
201+ assert(to!=NULL);
202+
203+ assert(handle->id < 8);
204+
205+ return NULL;
206+}
207+
208+static ObjectChange*
209+basestation_move(Basestation *basestation, Point *to)
210+{
211+ Element *elem = &basestation->element;
212+
213+ elem->corner = *to;
214+ elem->corner.x -= elem->width/2.0;
215+ elem->corner.y -= elem->height / 2.0;
216+
217+ basestation_update_data(basestation);
218+
219+ return NULL;
220+}
221+
222+static void
223+basestation_draw(Basestation *basestation, DiaRenderer *renderer)
224+{
225+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
226+ Element *elem;
227+ real x, y, w, h;
228+ real r = BASESTATION_WIDTH/2.0;
229+ Point ct, cb, p1, p2;
230+ Point points[6];
231+
232+ assert(basestation != NULL);
233+ assert(renderer != NULL);
234+
235+ elem = &basestation->element;
236+
237+ x = elem->corner.x;
238+ y = elem->corner.y + r;
239+ w = elem->width;
240+ h = elem->height - r;
241+
242+ renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
243+ renderer_ops->set_linejoin(renderer, LINEJOIN_ROUND);
244+ renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
245+ renderer_ops->set_linewidth(renderer, BASESTATION_LINEWIDTH);
246+
247+ ct.x = x + w/2.0;
248+ ct.y = y + r/2.0;
249+ cb.x = ct.x;
250+ cb.y = ct.y + h - r;
251+
252+ /* antenna 1 */
253+ points[0] = ct; points[0].x -= r/4.0; points[0].y -= 3.0*r/4.0;
254+ points[1] = ct; points[1].x += r/4.0; points[1].y -= 3.0*r/4.0;
255+ points[2] = ct; points[2].x += r/4.0; points[2].y += 1.0;
256+ points[3] = ct; points[3].x -= r/4.0; points[3].y += 1.0;
257+ renderer_ops->fill_polygon(renderer, points, 4,
258+ &basestation->fill_colour);
259+ renderer_ops->draw_polygon(renderer, points, 4,
260+ &basestation->line_colour);
261+ /* bottom */
262+ renderer_ops->fill_ellipse(renderer, &cb, r, r/2.0,
263+ &basestation->fill_colour);
264+ renderer_ops->draw_arc(renderer, &cb, r, r/2.0, 180, 0,
265+ &basestation->line_colour);
266+ /* bar */
267+ p1 = ct;
268+ p1.x -= r/2.0;
269+ p2 = cb;
270+ p2.x += r/2.0;
271+ renderer_ops->fill_rect(renderer, &p1, &p2,
272+ &basestation->fill_colour);
273+ p2.x -= r;
274+ renderer_ops->draw_line(renderer, &p1, &p2,
275+ &basestation->line_colour);
276+ p1.x += r;
277+ p2.x += r;
278+ renderer_ops->draw_line(renderer, &p1, &p2,
279+ &basestation->line_colour);
280+ /* top */
281+ renderer_ops->fill_ellipse(renderer, &ct, r, r/2.0,
282+ &basestation->fill_colour);
283+ renderer_ops->draw_ellipse(renderer, &ct, r, r/2.0,
284+ &basestation->line_colour);
285+ /* antenna 2 */
286+ points[0] = ct; points[0].x += r/4.0; points[0].y -= 0;
287+ points[1] = ct; points[1].x += 3.0*r/4.0; points[1].y -= r/2.0;
288+ points[2] = ct; points[2].x += 3.0*r/4.0; points[2].y += 1.0 - r/2.0;
289+ points[3] = ct; points[3].x += r/4.0; points[3].y += 1.0;
290+ renderer_ops->fill_polygon(renderer, points, 4,
291+ &basestation->fill_colour);
292+ renderer_ops->draw_polygon(renderer, points, 4,
293+ &basestation->line_colour);
294+ /* antenna 3 */
295+ points[0] = ct; points[0].x -= r/4.0; points[0].y -= 0;
296+ points[1] = ct; points[1].x -= 3.0*r/4.0; points[1].y -= r/2.0;
297+ points[2] = ct; points[2].x -= 3.0*r/4.0; points[2].y += 1.0 - r/2.0;
298+ points[3] = ct; points[3].x -= r/4.0; points[3].y += 1.0;
299+ renderer_ops->fill_polygon(renderer, points, 4,
300+ &basestation->fill_colour);
301+ renderer_ops->draw_polygon(renderer, points, 4,
302+ &basestation->line_colour);
303+ text_draw(basestation->text, renderer);
304+}
305+
306+static void
307+basestation_update_data(Basestation *basestation)
308+{
309+ Element *elem = &basestation->element;
310+ Object *obj = &elem->object;
311+ Rectangle text_box;
312+ Point p;
313+
314+ text_calc_boundingbox(basestation->text, &text_box);
315+
316+ elem->width = BASESTATION_WIDTH;
317+ elem->height = BASESTATION_HEIGHT+basestation->text->height;
318+
319+ /* Update connections: */
320+ basestation->connections[0].pos.x = elem->corner.x;
321+ basestation->connections[0].pos.y = elem->corner.y;
322+ basestation->connections[0].directions = DIR_NORTH|DIR_WEST;
323+ basestation->connections[1].pos.x = elem->corner.x + elem->width / 2.0;
324+ basestation->connections[1].pos.y = elem->corner.y;
325+ basestation->connections[1].directions = DIR_NORTH;
326+ basestation->connections[2].pos.x = elem->corner.x + elem->width;
327+ basestation->connections[2].pos.y = elem->corner.y;
328+ basestation->connections[2].directions = DIR_NORTH|DIR_EAST;
329+ basestation->connections[3].pos.x = elem->corner.x;
330+ basestation->connections[3].pos.y = elem->corner.y + elem->height / 2.0;
331+ basestation->connections[3].directions = DIR_WEST;
332+ basestation->connections[4].pos.x = elem->corner.x + elem->width;
333+ basestation->connections[4].pos.y = elem->corner.y + elem->height / 2.0;
334+ basestation->connections[4].directions = DIR_EAST;
335+ basestation->connections[5].pos.x = elem->corner.x;
336+ basestation->connections[5].pos.y = elem->corner.y + elem->height;
337+ basestation->connections[5].directions = DIR_SOUTH|DIR_WEST;
338+ basestation->connections[6].pos.x = elem->corner.x + elem->width / 2.0;
339+ basestation->connections[6].pos.y = elem->corner.y + elem->height;
340+ basestation->connections[6].directions = DIR_SOUTH;
341+ basestation->connections[7].pos.x = elem->corner.x + elem->width;
342+ basestation->connections[7].pos.y = elem->corner.y + elem->height;
343+ basestation->connections[7].directions = DIR_SOUTH|DIR_EAST;
344+
345+ element_update_boundingbox(elem);
346+
347+ p = elem->corner;
348+ p.x += elem->width/2;
349+ p.y += elem->height + basestation->text->ascent;
350+ text_set_position(basestation->text, &p);
351+
352+ /* Add bounding box for text: */
353+ rectangle_union(&obj->bounding_box, &text_box);
354+
355+ obj->position = elem->corner;
356+ obj->position.x += elem->width/2.0;
357+ obj->position.y += elem->height/2.0;
358+
359+ element_update_handles(elem);
360+}
361+
362+static Object *
363+basestation_create(Point *startpoint,
364+ void *user_data,
365+ Handle **handle1,
366+ Handle **handle2)
367+{
368+ Basestation *basestation;
369+ Element *elem;
370+ Object *obj;
371+ Point p;
372+ DiaFont *font;
373+ int i;
374+
375+ basestation = g_new0(Basestation, 1);
376+ elem = &basestation->element;
377+ obj = &elem->object;
378+
379+ obj->type = &basestation_type;
380+ obj->ops = &basestation_ops;
381+ elem->corner = *startpoint;
382+ elem->width = BASESTATION_WIDTH;
383+ elem->height = BASESTATION_HEIGHT;
384+
385+ font = dia_font_new_from_style (DIA_FONT_MONOSPACE, 0.8);
386+ p = *startpoint;
387+ p.y += BASESTATION_HEIGHT -
388+ dia_font_descent(_("Base Station"), font, 0.8);
389+
390+ basestation->text = new_text(_("Base Station"),
391+ font, 0.8, &p, &color_black, ALIGN_CENTER);
392+ dia_font_unref(font);
393+ text_get_attributes(basestation->text,&basestation->attrs);
394+ basestation->line_colour = color_black;
395+ basestation->fill_colour = color_white;
396+ basestation->sectors = 3;
397+
398+ element_init(elem, 8, 8);
399+
400+ for (i=0; i<8; i++) {
401+ obj->connections[i] = &basestation->connections[i];
402+ basestation->connections[i].object = obj;
403+ basestation->connections[i].connected = NULL;
404+ }
405+ elem->extra_spacing.border_trans = BASESTATION_LINEWIDTH/2.0;
406+ basestation_update_data(basestation);
407+
408+ for (i=0; i<8; i++) {
409+ obj->handles[i]->type = HANDLE_NON_MOVABLE;
410+ }
411+
412+ *handle1 = NULL;
413+ *handle2 = NULL;
414+ return &basestation->element.object;
415+}
416+
417+static void
418+basestation_destroy(Basestation *basestation)
419+{
420+ text_destroy(basestation->text);
421+
422+ element_destroy(&basestation->element);
423+}
424+
425+static Object *
426+basestation_load(ObjectNode obj_node, int version, const char *filename)
427+{
428+ return object_load_using_properties(&basestation_type,
429+ obj_node, version, filename);
430+}
--- /dev/null
+++ b/objects/network/pixmaps/basestation.xpm
@@ -0,0 +1,28 @@
1+/* XPM */
2+static char * basestation_xpm[] = {
3+"22 22 3 1",
4+" c None",
5+". c #000000",
6+"+ c #FFFFFF",
7+" . . ",
8+" .. . .. ",
9+" .+.+.+. ",
10+" .+.+.+. ",
11+" .+.+.+. ",
12+" .+.+.+. ",
13+" ..+.. ",
14+" .+. ",
15+" .+. ",
16+" .+. ",
17+" .+. ",
18+" .+. ",
19+" .+. ",
20+" .+. ",
21+" .+. ",
22+" .+. ",
23+" .+. ",
24+" .+. ",
25+" .+. ",
26+" .+. ",
27+" .+. ",
28+" . "};
--- /dev/null
+++ b/objects/network/pixmaps/radiocell.xpm
@@ -0,0 +1,28 @@
1+/* XPM */
2+static char * radiocell_xpm[] = {
3+"22 22 3 1",
4+" c None",
5+". c #000000",
6+"+ c #FFFFFF",
7+" ",
8+" .......... ",
9+" .++++++++++. ",
10+" .++++++++++. ",
11+" .++++++++++++. ",
12+" .++++++++++++++. ",
13+" .++++++++++++++. ",
14+" .++++++++++++++++. ",
15+" .++++++++++++++++++. ",
16+" .++++++++++++++++++. ",
17+".++++++++++++++++++++.",
18+".++++++++++++++++++++.",
19+" .++++++++++++++++++. ",
20+" .++++++++++++++++++. ",
21+" .++++++++++++++++. ",
22+" .++++++++++++++. ",
23+" .++++++++++++++. ",
24+" .++++++++++++. ",
25+" .++++++++++. ",
26+" .++++++++++. ",
27+" .......... ",
28+" "};
--- /dev/null
+++ b/objects/network/radiocell.c
@@ -0,0 +1,380 @@
1+/* Dia -- an diagram creation/manipulation program
2+ * Copyright (C) 1998 Alexander Larsson
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; either version 2 of the License, or
7+ * (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program; if not, write to the Free Software
16+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17+ */
18+
19+/* Copyright 2003, W. Borgert <debacle@debian.org>
20+ copied a lot from UML/large_package.c and standard/polygon.c */
21+
22+#ifdef HAVE_CONFIG_H
23+#include <config.h>
24+#endif
25+
26+#include <assert.h>
27+#include <math.h>
28+#include <string.h>
29+
30+#include "intl.h"
31+#include "object.h"
32+#include "polyshape.h"
33+#include "diarenderer.h"
34+#include "attributes.h"
35+#include "text.h"
36+#include "properties.h"
37+
38+#include "network.h"
39+
40+#include "pixmaps/radiocell.xpm"
41+
42+/* TODO? no visual effect ATM, but useful anyway */
43+typedef enum {
44+ MACRO_CELL,
45+ MICRO_CELL,
46+ PICO_CELL,
47+} CellType;
48+
49+/* TODO: add different cell technologies, like GSM, UMTS, ... */
50+
51+typedef struct _RadioCell RadioCell;
52+
53+struct _RadioCell {
54+ PolyShape poly; /* always 1st! */
55+ CellType celltype;
56+ real radius; /* pseudo-radius */
57+ ConnectionPoint cp; /* connection point in the center */
58+ Color line_colour;
59+ LineStyle line_style;
60+ real dashlength;
61+ real line_width;
62+ gboolean show_background;
63+ Color fill_colour;
64+ Text *text;
65+ TextAttributes attrs;
66+ int subscribers; /* number of subscribers in this cell,
67+ always >= 0, but check is missing */
68+};
69+
70+#define RADIOCELL_LINEWIDTH 0.1
71+#define RADIOCELL_FONTHEIGHT 0.8
72+
73+static real radiocell_distance_from(RadioCell *radiocell, Point *point);
74+static void radiocell_select(RadioCell *radiocell, Point *clicked_point,
75+ DiaRenderer *interactive_renderer);
76+static ObjectChange* radiocell_move_handle(RadioCell *radiocell,
77+ Handle *handle,
78+ Point *to, ConnectionPoint *cp,
79+ HandleMoveReason reason,
80+ ModifierKeys modifiers);
81+static ObjectChange* radiocell_move(RadioCell *radiocell, Point *to);
82+static void radiocell_draw(RadioCell *radiocell, DiaRenderer *renderer);
83+static Object *radiocell_create(Point *startpoint,
84+ void *user_data,
85+ Handle **handle1,
86+ Handle **handle2);
87+static void radiocell_destroy(RadioCell *radiocell);
88+static void radiocell_update_data(RadioCell *radiocell);
89+static PropDescription *radiocell_describe_props(RadioCell *radiocell);
90+static void radiocell_get_props(RadioCell *radiocell, GPtrArray *props);
91+static void radiocell_set_props(RadioCell *radiocell, GPtrArray *props);
92+static Object *radiocell_load(ObjectNode obj_node, int version,
93+ const char *filename);
94+
95+static ObjectTypeOps radiocell_type_ops =
96+{
97+ (CreateFunc) radiocell_create,
98+ (LoadFunc) radiocell_load,
99+ (SaveFunc) object_save_using_properties,
100+ (GetDefaultsFunc) NULL,
101+ (ApplyDefaultsFunc) NULL
102+};
103+
104+ObjectType radiocell_type =
105+{
106+ "Network - Radio Cell", /* name */
107+ 0, /* version */
108+ (char **) radiocell_xpm, /* pixmap */
109+
110+ &radiocell_type_ops /* ops */
111+};
112+
113+static ObjectOps radiocell_ops = {
114+ (DestroyFunc) radiocell_destroy,
115+ (DrawFunc) radiocell_draw,
116+ (DistanceFunc) radiocell_distance_from,
117+ (SelectFunc) radiocell_select,
118+ (CopyFunc) object_copy_using_properties,
119+ (MoveFunc) radiocell_move,
120+ (MoveHandleFunc) radiocell_move_handle,
121+ (GetPropertiesFunc) object_create_props_dialog,
122+ (ApplyPropertiesFunc) object_apply_props_from_dialog,
123+ (ObjectMenuFunc) NULL,
124+ (DescribePropsFunc) radiocell_describe_props,
125+ (GetPropsFunc) radiocell_get_props,
126+ (SetPropsFunc) radiocell_set_props
127+};
128+
129+static PropEnumData prop_cell_type_data[] = {
130+ { N_("Macro Cell"), MACRO_CELL },
131+ { N_("Micro Cell"), MICRO_CELL },
132+ { N_("Pico Cell"), PICO_CELL },
133+ { NULL, 0}
134+};
135+
136+static PropDescription radiocell_props[] = {
137+ POLYSHAPE_COMMON_PROPERTIES,
138+ { "radius", PROP_TYPE_REAL, 0, N_("Radius"), NULL, NULL },
139+ { "celltype", PROP_TYPE_ENUM, PROP_FLAG_VISIBLE,
140+ N_("Cell Type:"), NULL, prop_cell_type_data },
141+ PROP_STD_LINE_WIDTH,
142+ PROP_STD_LINE_COLOUR,
143+ PROP_STD_LINE_STYLE,
144+ PROP_STD_FILL_COLOUR,
145+ PROP_STD_SHOW_BACKGROUND,
146+ { "text", PROP_TYPE_TEXT, 0, N_("Text"), NULL, NULL },
147+ PROP_STD_TEXT_FONT,
148+ PROP_STD_TEXT_HEIGHT,
149+ PROP_STD_TEXT_COLOUR,
150+ PROP_STD_TEXT_ALIGNMENT,
151+ { "subscribers", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
152+ N_("Subscribers"), NULL, NULL },
153+ PROP_DESC_END
154+};
155+
156+static PropDescription *
157+radiocell_describe_props(RadioCell *radiocell)
158+{
159+ if (radiocell_props[0].quark == 0) {
160+ prop_desc_list_calculate_quarks(radiocell_props);
161+ }
162+ return radiocell_props;
163+}
164+
165+static PropOffset radiocell_offsets[] = {
166+ POLYSHAPE_COMMON_PROPERTIES_OFFSETS,
167+ { "radius", PROP_TYPE_REAL, offsetof(RadioCell, radius) },
168+ { "celltype", PROP_TYPE_ENUM, offsetof(RadioCell, celltype) },
169+ { "line_width", PROP_TYPE_REAL, offsetof(RadioCell, line_width) },
170+ { "line_colour", PROP_TYPE_COLOUR, offsetof(RadioCell, line_colour) },
171+ { "line_style", PROP_TYPE_LINESTYLE,
172+ offsetof(RadioCell, line_style), offsetof(RadioCell, dashlength) },
173+ { "fill_colour", PROP_TYPE_COLOUR, offsetof(RadioCell, fill_colour) },
174+ { "show_background", PROP_TYPE_BOOL,
175+ offsetof(RadioCell, show_background) },
176+ { "text", PROP_TYPE_TEXT, offsetof(RadioCell, text) },
177+ { "text_font", PROP_TYPE_FONT, offsetof(RadioCell, attrs.font) },
178+ { "text_height", PROP_TYPE_REAL, offsetof(RadioCell, attrs.height) },
179+ { "text_colour", PROP_TYPE_COLOUR, offsetof(RadioCell, attrs.color) },
180+ { "text_alignment", PROP_TYPE_ENUM,
181+ offsetof(RadioCell, attrs.alignment) },
182+ { "subscribers", PROP_TYPE_INT, offsetof(RadioCell, subscribers) },
183+ { NULL, 0, 0 },
184+};
185+
186+static void
187+radiocell_get_props(RadioCell *radiocell, GPtrArray *props)
188+{
189+ text_get_attributes(radiocell->text, &radiocell->attrs);
190+ object_get_props_from_offsets(&radiocell->poly.object,
191+ radiocell_offsets, props);
192+}
193+
194+static void
195+radiocell_set_props(RadioCell *radiocell, GPtrArray *props)
196+{
197+ object_set_props_from_offsets(&radiocell->poly.object,
198+ radiocell_offsets, props);
199+ apply_textattr_properties(props, radiocell->text,
200+ "text", &radiocell->attrs);
201+ radiocell_update_data(radiocell);
202+}
203+
204+static real
205+radiocell_distance_from(RadioCell *radiocell, Point *point)
206+{
207+ return polyshape_distance_from(&radiocell->poly, point,
208+ radiocell->line_width);
209+}
210+
211+static void
212+radiocell_select(RadioCell *radiocell, Point *clicked_point,
213+ DiaRenderer *interactive_renderer)
214+{
215+ text_set_cursor(radiocell->text, clicked_point, interactive_renderer);
216+ text_grab_focus(radiocell->text, &radiocell->poly.object);
217+ polyshape_update_data(&radiocell->poly);
218+}
219+
220+static ObjectChange*
221+radiocell_move_handle(RadioCell *radiocell, Handle *handle,
222+ Point *to, ConnectionPoint *cp,
223+ HandleMoveReason reason, ModifierKeys modifiers)
224+{
225+ real distance = distance_point_point(&handle->pos, to);
226+ gboolean larger = distance_point_point(&handle->pos, &radiocell->cp.pos) <
227+ distance_point_point(to, &radiocell->cp.pos);
228+
229+ /* TODO: this flickers terribly */
230+ radiocell->radius += distance * (larger? 1: -1);
231+ if (radiocell->radius < 1.)
232+ radiocell->radius = 1.;
233+ radiocell_update_data(radiocell);
234+
235+ return NULL;
236+}
237+
238+static ObjectChange*
239+radiocell_move(RadioCell *radiocell, Point *to)
240+{
241+ polyshape_move(&radiocell->poly, to);
242+ radiocell->cp.pos = *to;
243+ radiocell->cp.pos.x -= radiocell->radius;
244+ radiocell_update_data(radiocell);
245+
246+ return NULL;
247+}
248+
249+static void
250+radiocell_draw(RadioCell *radiocell, DiaRenderer *renderer)
251+{
252+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
253+ PolyShape *poly;
254+ Point *points;
255+ int n;
256+
257+ assert(radiocell != NULL);
258+ assert(renderer != NULL);
259+
260+ poly = &radiocell->poly;
261+ points = &poly->points[0];
262+ n = poly->numpoints;
263+
264+ if (radiocell->show_background) {
265+ renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
266+ renderer_ops->fill_polygon(renderer, points, n, &radiocell->fill_colour);
267+ }
268+ renderer_ops->set_linecaps(renderer, LINECAPS_BUTT);
269+ renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
270+ renderer_ops->set_linestyle(renderer, radiocell->line_style);
271+ renderer_ops->set_linewidth(renderer, radiocell->line_width);
272+ renderer_ops->set_dashlength(renderer, radiocell->dashlength);
273+ renderer_ops->draw_polygon(renderer, points, n, &radiocell->line_colour);
274+
275+ text_draw(radiocell->text, renderer);
276+}
277+
278+static void
279+radiocell_update_data(RadioCell *radiocell)
280+{
281+ PolyShape *poly = &radiocell->poly;
282+ Object *obj = &poly->object;
283+ ElementBBExtras *extra = &poly->extra_spacing;
284+ Rectangle text_box;
285+ Point textpos;
286+ int i;
287+ /* not exactly a regular hexagon, but this fits better in the grid */
288+ Point points[] = { { 1., 0. }, { .5, .75 }, { -.5, .75 },
289+ { -1., 0. }, { -.5, -.75 }, { .5, -.75 } };
290+
291+ /* TODO: the CP is invisible and does not yet work */
292+ radiocell->cp.pos.x = (poly->points[0].x + poly->points[3].x) / 2.;
293+ radiocell->cp.pos.y = poly->points[0].y;
294+
295+ for (i = 0; i < 6; i++) {
296+ poly->points[i] = radiocell->cp.pos;
297+ poly->points[i].x += radiocell->radius * points[i].x;
298+ poly->points[i].y += radiocell->radius * points[i].y;
299+ }
300+
301+ /* Add bounding box for text: */
302+ text_calc_boundingbox(radiocell->text, NULL);
303+ textpos.x = (poly->points[0].x + poly->points[3].x) / 2.;
304+ textpos.y = poly->points[0].y -
305+ (radiocell->text->height * (radiocell->text->numlines - 1) +
306+ radiocell->text->descent) / 2.;
307+ text_set_position(radiocell->text, &textpos);
308+ text_calc_boundingbox(radiocell->text, &text_box);
309+ polyshape_update_data(poly);
310+ extra->border_trans = radiocell->line_width / 2.0;
311+ polyshape_update_boundingbox(poly);
312+ rectangle_union(&obj->bounding_box, &text_box);
313+ obj->position = poly->points[0];
314+}
315+
316+static Object *
317+radiocell_create(Point *startpoint,
318+ void *user_data,
319+ Handle **handle1,
320+ Handle **handle2)
321+{
322+ RadioCell *radiocell;
323+ PolyShape *poly;
324+ Object *obj;
325+ DiaFont *font;
326+
327+ radiocell = g_new0(RadioCell, 1);
328+ poly = &radiocell->poly;
329+ obj = &poly->object;
330+ obj->type = &radiocell_type;
331+ obj->ops = &radiocell_ops;
332+ obj->can_parent = TRUE;
333+
334+ radiocell->celltype = MACRO_CELL;
335+ radiocell->radius = 4.;
336+ radiocell->subscribers = 1000;
337+
338+ /* do not use default_properties.show_background here */
339+ radiocell->show_background = FALSE;
340+ radiocell->fill_colour = color_white;
341+ radiocell->line_colour = color_black;
342+ radiocell->line_width = RADIOCELL_LINEWIDTH;
343+ attributes_get_default_line_style(&radiocell->line_style,
344+ &radiocell->dashlength);
345+
346+ font = dia_font_new_from_style(DIA_FONT_MONOSPACE, RADIOCELL_FONTHEIGHT);
347+ radiocell->text = new_text("", font, RADIOCELL_FONTHEIGHT, startpoint,
348+ &color_black, ALIGN_CENTER);
349+ dia_font_unref(font);
350+ text_get_attributes(radiocell->text, &radiocell->attrs);
351+
352+ polyshape_init(poly, 6);
353+
354+ object_add_connectionpoint(&poly->object, &radiocell->cp);
355+ obj->connections[0] = &radiocell->cp;
356+ radiocell->cp.object = obj;
357+ radiocell->cp.connected = NULL;
358+ radiocell->cp.directions = DIR_ALL;
359+ radiocell->cp.pos = *startpoint;
360+ radiocell->cp.pos.x -= radiocell->radius;
361+
362+ radiocell_update_data(radiocell);
363+ *handle1 = poly->object.handles[0];
364+ *handle2 = poly->object.handles[2];
365+ return &radiocell->poly.object;
366+}
367+
368+static void
369+radiocell_destroy(RadioCell *radiocell)
370+{
371+ text_destroy(radiocell->text);
372+ polyshape_destroy(&radiocell->poly);
373+}
374+
375+static Object *
376+radiocell_load(ObjectNode obj_node, int version, const char *filename)
377+{
378+ return object_load_using_properties(&radiocell_type,
379+ obj_node, version, filename);
380+}