Hello,
I have asked this before but somehow the discussion came to an end. So
I'll try again.
I'm trying to add a line style (Dashed) attribute to the box.c shape of
the SADT sheet.
I tried to use the diamond.c from the flowchart as a reference but I
can't get it to work.
If I double-click on the shape I can't select the line style attribute.
Hans, I have looked at the examples you have given me but I can't find
the error I'm making.
I like to extent my knowledge up to a point I can contribute to Dia. So
any help is greatly appreciated.
I added the code I tried.
In all the code I have check I never come across the PROP_FLAG_VISIBLE.
Thanks for your help.
Regards, Robert
On 30/08/11 20:27, Hans Breuer wrote:
At 29.08.2011 17:17, myken wrote:
Hello,
I'm trying to add a line style (Dashed) attribute to the box.c shape
of the SADT
sheet.
I tried to use the diamond.c from the flowchart as a reference but I
can't get
it to work.
If I double-click on the shape I can't select the line style attribute.
As I understand the structure of Dia I only need to change the box.c
file, right?
Yes.
As you see from the picture attached, I managed to add a source
identified
attribute to the properties menu but I can't make the line style
attribute appear.
Without the code /a patch) it is hard to guess. Maybe you are missing
the PROP_FLAG_VISIBLE?
Any hint's ? Thanks a lot. Regards Robert.
Look at some change which works (not linestyle but color, though):
http://git.gnome.org/browse/dia/commit/?id=aeb71aca5761bcd510296893720f12b77afc4e48
HTH,
Hans
-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to
get along without it. -- Dilbert
_______________________________________________
dia-list mailing list
dia-list@gnome.org
http://mail.gnome.org/mailman/listinfo/dia-list
FAQ at http://live.gnome.org/Dia/Faq
Main page at http://live.gnome.org/Dia
/* Dia -- an diagram creation/manipulation program
* Copyright (C) 1998 Alexander Larsson
*
* SADT Activity/Data box -- objects for drawing SADT diagrams.
* Copyright (C) 2000, 2001 Cyrille Chepelov
*
* Forked from Flowchart toolbox -- objects for drawing flowcharts.
* Copyright (C) 1999 James Henstridge.
*
* 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 "intl.h"
#include "object.h"
#include "element.h"
#include "connectionpoint.h"
#include "diarenderer.h"
#include "attributes.h"
#include "text.h"
#include "widgets.h"
#include "message.h"
#include "connpoint_line.h"
#include "color.h"
#include "properties.h"
#include "pixmaps/sadtbox.xpm"
#define DEFAULT_WIDTH 7.0
#define DEFAULT_HEIGHT 5.0
#define DEFAULT_BORDER 0.25
#define SADTBOX_LINE_WIDTH 0.10
#define SADTBOX_FG_COLOR color_black
#define SADTBOX_BG_COLOR color_white
typedef enum {
ANCHOR_MIDDLE,
ANCHOR_START,
ANCHOR_END
} AnchorShape;
typedef struct _Box {
Element element;
ConnPointLine *north,*south,*east,*west;
Text *text;
gchar *id;
gchar *sourceid;
real padding;
LineStyle line_style;
real dashlength;
TextAttributes attrs;
} Box;
static real sadtbox_distance_from(Box *box, Point *point);
static void sadtbox_select(Box *box, Point *clicked_point,
DiaRenderer *interactive_renderer);
static ObjectChange* sadtbox_move_handle(Box *box, Handle *handle,
Point *to, ConnectionPoint *cp,
HandleMoveReason reason,
ModifierKeys modifiers);
static ObjectChange* sadtbox_move(Box *box, Point *to);
static void sadtbox_draw(Box *box, DiaRenderer *renderer);
static void sadtbox_update_data(Box *box, AnchorShape horix, AnchorShape vert);
static DiaObject *sadtbox_create(Point *startpoint,
void *user_data,
Handle **handle1,
Handle **handle2);
static void sadtbox_destroy(Box *box);
static DiaObject *sadtbox_load(ObjectNode obj_node, int version,
const char *filename);
static DiaMenu *sadtbox_get_object_menu(Box *box, Point *clickedpoint);
static PropDescription *sadtbox_describe_props(Box *box);
static void sadtbox_get_props(Box *box, GPtrArray *props);
static void sadtbox_set_props(Box *box, GPtrArray *props);
static ObjectTypeOps mysadtbox_type_ops =
{
(CreateFunc) sadtbox_create,
(LoadFunc) sadtbox_load/*using_properties*/,
(SaveFunc) object_save_using_properties,
(GetDefaultsFunc) NULL,
(ApplyDefaultsFunc) NULL,
};
DiaObjectType mysadtbox_type =
{
"mySADT - myBox", /* name */
0, /* version */
(char **) sadtbox_xpm, /* pixmap */
&mysadtbox_type_ops /* ops */
};
static ObjectOps sadtbox_ops = {
(DestroyFunc) sadtbox_destroy,
(DrawFunc) sadtbox_draw,
(DistanceFunc) sadtbox_distance_from,
(SelectFunc) sadtbox_select,
(CopyFunc) object_copy_using_properties,
(MoveFunc) sadtbox_move,
(MoveHandleFunc) sadtbox_move_handle,
(GetPropertiesFunc) object_create_props_dialog,
(ApplyPropertiesDialogFunc) object_apply_props_from_dialog,
(ObjectMenuFunc) sadtbox_get_object_menu,
(DescribePropsFunc) sadtbox_describe_props,
(GetPropsFunc) sadtbox_get_props,
(SetPropsFunc) sadtbox_set_props,
(TextEditFunc) 0,
(ApplyPropertiesListFunc) object_apply_props,
};
static PropNumData text_padding_data = { 0.0, 10.0, 0.1 };
static PropDescription box_props[] = {
ELEMENT_COMMON_PROPERTIES,
{ "padding",PROP_TYPE_REAL,PROP_FLAG_VISIBLE,
N_("Text padding"), NULL, &text_padding_data},
{ "text", PROP_TYPE_TEXT, 0,NULL,NULL},
PROP_STD_TEXT_ALIGNMENT,
PROP_STD_TEXT_FONT,
PROP_STD_TEXT_HEIGHT,
PROP_STD_TEXT_COLOUR,
PROP_STD_LINE_STYLE,
{ "sourceid", PROP_TYPE_STRING, PROP_FLAG_VISIBLE|PROP_FLAG_DONT_MERGE,
N_("Source identifier"),
N_("The identifier which appears in the upper left corner of the Box")},
{ "id", PROP_TYPE_STRING, PROP_FLAG_VISIBLE|PROP_FLAG_DONT_MERGE,
N_("Activity/Data identifier"),
N_("The identifier which appears in the lower right corner of the Box")},
{ "cpl_north",PROP_TYPE_CONNPOINT_LINE, 0, NULL, NULL},
{ "cpl_west",PROP_TYPE_CONNPOINT_LINE, 0, NULL, NULL},
{ "cpl_south",PROP_TYPE_CONNPOINT_LINE, 0, NULL, NULL},
{ "cpl_east",PROP_TYPE_CONNPOINT_LINE, 0, NULL, NULL},
PROP_DESC_END
};
static PropDescription *
sadtbox_describe_props(Box *box)
{
if (box_props[0].quark == 0) {
prop_desc_list_calculate_quarks(box_props);
}
return box_props;
}
static PropOffset box_offsets[] = {
ELEMENT_COMMON_PROPERTIES_OFFSETS,
{ "padding",PROP_TYPE_REAL,offsetof(Box,padding)},
{ "text", PROP_TYPE_TEXT, offsetof(Box,text)},
{ "text_alignment",PROP_TYPE_ENUM,offsetof(Box,attrs.alignment)},
{ "text_font",PROP_TYPE_FONT,offsetof(Box,attrs.font)},
{ PROP_STDNAME_TEXT_HEIGHT,PROP_STDTYPE_TEXT_HEIGHT,offsetof(Box,attrs.height)},
{ "text_colour",PROP_TYPE_COLOUR,offsetof(Box,attrs.color)},
{ "line_style", PROP_TYPE_LINESTYLE,
offsetof(Box, line_style), offsetof(Box, dashlength) },
{ "sourceid", PROP_TYPE_STRING, offsetof(Box,sourceid)},
{ "id", PROP_TYPE_STRING, offsetof(Box,id)},
{ "cpl_north",PROP_TYPE_CONNPOINT_LINE, offsetof(Box,north)},
{ "cpl_west",PROP_TYPE_CONNPOINT_LINE, offsetof(Box,west)},
{ "cpl_south",PROP_TYPE_CONNPOINT_LINE, offsetof(Box,south)},
{ "cpl_east",PROP_TYPE_CONNPOINT_LINE, offsetof(Box,east)},
{NULL}
};
static void
sadtbox_get_props(Box *box, GPtrArray *props)
{
text_get_attributes(box->text,&box->attrs);
object_get_props_from_offsets(&box->element.object,
box_offsets,props);
}
static void
sadtbox_set_props(Box *box, GPtrArray *props)
{
object_set_props_from_offsets(&box->element.object,
box_offsets,props);
apply_textattr_properties(props,box->text,"text",&box->attrs);
sadtbox_update_data(box, ANCHOR_MIDDLE, ANCHOR_MIDDLE);
}
static real
sadtbox_distance_from(Box *box, Point *point)
{
Element *elem = &box->element;
Rectangle rect;
rect.left = elem->corner.x - SADTBOX_LINE_WIDTH/2;
rect.right = elem->corner.x + elem->width + SADTBOX_LINE_WIDTH/2;
rect.top = elem->corner.y - SADTBOX_LINE_WIDTH/2;
rect.bottom = elem->corner.y + elem->height + SADTBOX_LINE_WIDTH/2;
return distance_rectangle_point(&rect, point);
}
static void
sadtbox_select(Box *box, Point *clicked_point,
DiaRenderer *interactive_renderer)
{
text_set_cursor(box->text, clicked_point, interactive_renderer);
text_grab_focus(box->text, &box->element.object);
element_update_handles(&box->element);
}
static ObjectChange*
sadtbox_move_handle(Box *box, Handle *handle,
Point *to, ConnectionPoint *cp,
HandleMoveReason reason, ModifierKeys modifiers)
{
AnchorShape horiz = ANCHOR_MIDDLE, vert = ANCHOR_MIDDLE;
assert(box!=NULL);
assert(handle!=NULL);
assert(to!=NULL);
element_move_handle(&box->element, handle->id, to, cp, reason, modifiers);
switch (handle->id) {
case HANDLE_RESIZE_NW:
horiz = ANCHOR_END; vert = ANCHOR_END; break;
case HANDLE_RESIZE_N:
vert = ANCHOR_END; break;
case HANDLE_RESIZE_NE:
horiz = ANCHOR_START; vert = ANCHOR_END; break;
case HANDLE_RESIZE_E:
horiz = ANCHOR_START; break;
case HANDLE_RESIZE_SE:
horiz = ANCHOR_START; vert = ANCHOR_START; break;
case HANDLE_RESIZE_S:
vert = ANCHOR_START; break;
case HANDLE_RESIZE_SW:
horiz = ANCHOR_END; vert = ANCHOR_START; break;
case HANDLE_RESIZE_W:
horiz = ANCHOR_END; break;
default:
break;
}
sadtbox_update_data(box, horiz, vert);
return NULL;
}
static ObjectChange*
sadtbox_move(Box *box, Point *to)
{
box->element.corner = *to;
sadtbox_update_data(box, ANCHOR_MIDDLE, ANCHOR_MIDDLE);
return NULL;
}
static void
sadtbox_draw(Box *box, DiaRenderer *renderer)
{
DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
Point lr_corner,ul_corner,pos;
Element *elem;
real idfontheight, sourceidfontheight;
assert(box != NULL);
assert(renderer != NULL);
elem = &box->element;
lr_corner.x = elem->corner.x + elem->width;
lr_corner.y = elem->corner.y + elem->height;
ul_corner.x = elem->corner.x + SADTBOX_LINE_WIDTH + 0.4;
ul_corner.y = elem->corner.y + SADTBOX_LINE_WIDTH + 0.6;
renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
renderer_ops->fill_rect(renderer,
&elem->corner,
&lr_corner,
&SADTBOX_BG_COLOR);
renderer_ops->set_linewidth(renderer, SADTBOX_LINE_WIDTH);
renderer_ops->set_linestyle(renderer, box->line_style);
renderer_ops->set_dashlength(renderer, box->dashlength);
renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
renderer_ops->draw_rect(renderer,
&elem->corner,
&lr_corner,
&SADTBOX_FG_COLOR);
text_draw(box->text, renderer);
idfontheight = .75 * box->text->height;
renderer_ops->set_font(renderer, box->text->font, idfontheight);
pos = lr_corner;
pos.x -= .3 * idfontheight;
pos.y -= .3 * idfontheight;
renderer_ops->draw_string(renderer,
box->id,
&pos, ALIGN_RIGHT,
&box->text->color);
sourceidfontheight = .75 * box->text->height;
renderer_ops->set_font(renderer, box->text->font, sourceidfontheight);
pos = ul_corner;
pos.x -= .3 * sourceidfontheight;
pos.y -= .3 * sourceidfontheight;
renderer_ops->draw_string(renderer,
box->sourceid,
&pos, ALIGN_LEFT,
&box->text->color);
}
static void
sadtbox_update_data(Box *box, AnchorShape horiz, AnchorShape vert)
{
Element *elem = &box->element;
ElementBBExtras *extra = &elem->extra_spacing;
DiaObject *obj = &elem->object;
Point center, bottom_right;
Point p;
real width, height;
Point nw,ne,se,sw;
/* save starting points */
center = bottom_right = elem->corner;
center.x += elem->width/2;
bottom_right.x += elem->width;
center.y += elem->height/2;
bottom_right.y += elem->height;
text_calc_boundingbox(box->text, NULL);
width = box->text->max_width + box->padding*2;
height = box->text->height * box->text->numlines + box->padding*2;
if (width > elem->width) elem->width = width;
if (height > elem->height) elem->height = height;
/* move shape if necessary ... */
switch (horiz) {
case ANCHOR_MIDDLE:
elem->corner.x = center.x - elem->width/2; break;
case ANCHOR_END:
elem->corner.x = bottom_right.x - elem->width; break;
default:
break;
}
switch (vert) {
case ANCHOR_MIDDLE:
elem->corner.y = center.y - elem->height/2; break;
case ANCHOR_END:
elem->corner.y = bottom_right.y - elem->height; break;
default:
break;
}
p = elem->corner;
p.x += elem->width / 2.0;
p.y += elem->height / 2.0 - box->text->height * box->text->numlines / 2 +
box->text->ascent;
text_set_position(box->text, &p);
extra->border_trans = SADTBOX_LINE_WIDTH / 2.0;
element_update_boundingbox(elem);
obj->position = elem->corner;
element_update_handles(elem);
/* Update connections: */
nw = elem->corner;
se.x = elem->corner.x + elem->width;
se.y = elem->corner.y + elem->height;
ne.x = se.x;
ne.y = nw.y;
sw.y = se.y;
sw.x = nw.x;
connpointline_update(box->north);
connpointline_putonaline(box->north,&ne,&nw);
connpointline_update(box->west);
connpointline_putonaline(box->west,&nw,&sw);
connpointline_update(box->south);
connpointline_putonaline(box->south,&sw,&se);
connpointline_update(box->east);
connpointline_putonaline(box->east,&se,&ne);
}
static ConnPointLine *
sadtbox_get_clicked_border(Box *box, Point *clicked)
{
ConnPointLine *cpl;
real dist,dist2;
cpl = box->north;
dist = distance_line_point(&box->north->start,&box->north->end,0,clicked);
dist2 = distance_line_point(&box->west->start,&box->west->end,0,clicked);
if (dist2 < dist) {
cpl = box->west;
dist = dist2;
}
dist2 = distance_line_point(&box->south->start,&box->south->end,0,clicked);
if (dist2 < dist) {
cpl = box->south;
dist = dist2;
}
dist2 = distance_line_point(&box->east->start,&box->east->end,0,clicked);
if (dist2 < dist) {
cpl = box->east;
/*dist = dist2;*/
}
return cpl;
}
inline static ObjectChange *
sadtbox_create_change(Box *box, ObjectChange *inner, ConnPointLine *cpl) {
return (ObjectChange *)inner;
}
static ObjectChange *
sadtbox_add_connpoint_callback(DiaObject *obj, Point *clicked, gpointer data)
{
ObjectChange *change;
ConnPointLine *cpl;
Box *box = (Box *)obj;
cpl = sadtbox_get_clicked_border(box,clicked);
change = connpointline_add_point(cpl, clicked);
sadtbox_update_data((Box *)obj,ANCHOR_MIDDLE, ANCHOR_MIDDLE);
return sadtbox_create_change(box,change,cpl);
}
static ObjectChange *
sadtbox_remove_connpoint_callback(DiaObject *obj, Point *clicked, gpointer data)
{
ObjectChange *change;
ConnPointLine *cpl;
Box *box = (Box *)obj;
cpl = sadtbox_get_clicked_border(box,clicked);
change = connpointline_remove_point(cpl, clicked);
sadtbox_update_data((Box *)obj,ANCHOR_MIDDLE, ANCHOR_MIDDLE);
return sadtbox_create_change(box,change,cpl);
}
static DiaMenuItem object_menu_items[] = {
{ N_("Add connection point"), sadtbox_add_connpoint_callback, NULL, 1 },
{ N_("Delete connection point"), sadtbox_remove_connpoint_callback,
NULL, 1 },
};
static DiaMenu object_menu = {
N_("mySADT myBox"),
sizeof(object_menu_items)/sizeof(DiaMenuItem),
object_menu_items,
NULL
};
static DiaMenu *
sadtbox_get_object_menu(Box *box, Point *clickedpoint)
{
ConnPointLine *cpl;
cpl = sadtbox_get_clicked_border(box,clickedpoint);
/* Set entries sensitive/selected etc here */
object_menu_items[0].active = connpointline_can_add_point(cpl, clickedpoint);
object_menu_items[1].active = connpointline_can_remove_point(cpl, clickedpoint);
return &object_menu;
}
static DiaObject *
sadtbox_create(Point *startpoint,
void *user_data,
Handle **handle1,
Handle **handle2)
{
Box *box;
Element *elem;
DiaObject *obj;
Point p;
DiaFont* font;
box = g_malloc0(sizeof(Box));
elem = &box->element;
obj = &elem->object;
obj->type = &mysadtbox_type;
obj->ops = &sadtbox_ops;
elem->corner = *startpoint;
elem->width = DEFAULT_WIDTH;
elem->height = DEFAULT_HEIGHT;
box->padding = 0.5; /* default_values.padding; */
attributes_get_default_line_style(&box->line_style,&box->dashlength);
p = *startpoint;
p.x += elem->width / 2.0;
p.y += elem->height / 2.0 + /*default_properties.font_size*/ 0.8 / 2;
font = dia_font_new_from_style( DIA_FONT_SANS|DIA_FONT_BOLD ,0.8);
box->text = new_text("", font,
0.8, &p,
&color_black,
ALIGN_CENTER);
dia_font_unref(font);
text_get_attributes(box->text,&box->attrs);
box->id = g_strdup("A0"); /* should be made better.
Automatic counting ? */
box->sourceid = g_strdup("AC power");
element_init(elem, 8, 0);
box->north = connpointline_create(obj,4);
box->west = connpointline_create(obj,3);
box->south = connpointline_create(obj,1);
box->east = connpointline_create(obj,3);
box->element.extra_spacing.border_trans = SADTBOX_LINE_WIDTH/2.0;
sadtbox_update_data(box, ANCHOR_MIDDLE, ANCHOR_MIDDLE);
*handle1 = NULL;
*handle2 = obj->handles[7];
return &box->element.object;
}
static void
sadtbox_destroy(Box *box)
{
text_destroy(box->text);
connpointline_destroy(box->east);
connpointline_destroy(box->south);
connpointline_destroy(box->west);
connpointline_destroy(box->north);
g_free(box->id);
g_free(box->sourceid);
element_destroy(&box->element);
}
static DiaObject *
sadtbox_load(ObjectNode obj_node, int version, const char *filename)
{
return object_load_using_properties(&mysadtbox_type,
obj_node,version,filename);
}
_______________________________________________
dia-list mailing list
dia-list@gnome.org
http://mail.gnome.org/mailman/listinfo/dia-list
FAQ at http://live.gnome.org/Dia/Faq
Main page at http://live.gnome.org/Dia