[dia] Bug 587319 - UML Lifeline: usability improvements
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] Bug 587319 - UML Lifeline: usability improvements
- Date: Thu, 23 Jun 2011 20:50:11 +0000 (UTC)
commit 1e43eb7280481a97d084b75787d912fda7cafbf2
Author: Hans Breuer <hans breuer org>
Date: Thu Jun 23 22:35:17 2011 +0200
Bug 587319 - UML Lifeline: usability improvements
Resize box while maintaining connection points distance.
Add/remove connection points no longer vertical symmetric,
it is only adding at the height were clicked/moved.
Fix size regression with older files (added after 0-97).
objects/UML/lifeline.c | 152 +++++++++++++++++++++++++++++------------------
1 files changed, 94 insertions(+), 58 deletions(-)
---
diff --git a/objects/UML/lifeline.c b/objects/UML/lifeline.c
index ef5c3f4..40d854a 100644
--- a/objects/UML/lifeline.c
+++ b/objects/UML/lifeline.c
@@ -38,16 +38,19 @@
typedef struct _Lifeline Lifeline;
+#define LIFELINE_NUM_HANDLES 5
+#define LIFELINE_NUM_STD_CPS 7
struct _Lifeline {
Connection connection;
- ConnectionPoint connections[7]; /* 7Âth cp position is at rbot handle location
+ ConnectionPoint connections[LIFELINE_NUM_STD_CPS]; /* 7Âth cp position is at rbot handle location
(this is useful to attach another lifeline
just below this one in case of an object
activated more than once in a sequence diagram.)*/
Handle boxbot_handle;
Handle boxtop_handle;
+ Handle boxmid_handle;
/* these are _relative_ to endpoints[0] */
real rtop, rbot;
@@ -82,6 +85,7 @@ struct _Lifeline {
#define HANDLE_BOXTOP (HANDLE_CUSTOM1)
#define HANDLE_BOXBOT (HANDLE_CUSTOM2)
+#define HANDLE_BOXMID (HANDLE_CUSTOM3)
static ObjectChange* lifeline_move_handle(Lifeline *lifeline, Handle *handle,
Point *to, ConnectionPoint *cp,
@@ -108,6 +112,15 @@ static DiaMenu *lifeline_get_object_menu(Lifeline *lifeline,
Point *clickedpoint);
+typedef enum {
+ LIFELINE_CHANGE_ADD = 0x01,
+ LIFELINE_CHANGE_DEL = 0x02,
+ LIFELINE_CHANGE_INC = 0x03,
+ LIFELINE_CHANGE_DEC = 0x04,
+ LIFELINE_CHANGE_DEF = 0x05
+} LifelineChangeType;
+
+static ObjectChange *lifeline_create_change(Lifeline *lifeline, LifelineChangeType changetype, Point *clicked);
static ObjectTypeOps lifeline_type_ops =
{
@@ -195,6 +208,15 @@ lifeline_set_props(Lifeline *lifeline, GPtrArray *props)
object_set_props_from_offsets(&lifeline->connection.object,
lifeline_offsets, props);
+ /* This magic is necessary to correctly load data
+ from old lifeline behavior. It calculates the
+ cp_distance in function of saved rtop-rbot distance and
+ num of cp.
+ ( It's just the inverse of lifeline_rect_size :)
+ */
+ lifeline->cp_distance = (lifeline->rbot - lifeline->rtop)
+ / (lifeline->northwest->num_connections + 1 +
+ lifeline->southwest->num_connections + 1);
lifeline_update_data(lifeline);
}
@@ -216,7 +238,8 @@ lifeline_distance_from(Lifeline *lifeline, Point *point)
static inline real
lifeline_rect_size(Lifeline *lifeline)
{
- return ( (real)(lifeline->northwest->num_connections+1) * 2.0 * lifeline->cp_distance );
+ return ( (lifeline->northwest->num_connections+1) * lifeline->cp_distance
+ + (lifeline->southwest->num_connections+1) * lifeline->cp_distance);
}
static void
@@ -226,6 +249,12 @@ lifeline_select(Lifeline *lifeline, Point *clicked_point,
connection_update_handles(&lifeline->connection);
}
+static gboolean
+lifeline_point_above_mid (Lifeline *lifeline,
+ Point *pt)
+{
+ return (pt->y < lifeline->boxmid_handle.pos.y);
+}
/*!
* Moving handles of a lifeline
*
@@ -254,7 +283,28 @@ lifeline_move_handle(Lifeline *lifeline, Handle *handle,
/* distance between upper handle and boxtop must not be smaller than zero */
dy = to->y - conn->endpoints[0].y;
if (dy > lifeline_rect_size(lifeline)) {
- lifeline->rbot = dy;
+ real dist = dy - lifeline->rbot;
+ real di, df;
+
+ df = modf (dist, &di);
+ /* the integer part gives the number of points to add or remove */
+ if (fabs (di) > 0) {
+ int ni = (int)di;
+
+ if (lifeline_point_above_mid (lifeline, to) ?
+ lifeline->northeast->num_connections + ni > 0 :
+ lifeline->southeast->num_connections + ni > 0)
+ return lifeline_create_change (lifeline, ni > 0 ? LIFELINE_CHANGE_ADD : LIFELINE_CHANGE_DEL, to);
+ else
+ return NULL;
+ }
+ }
+ } else if (handle->id == HANDLE_BOXMID) {
+ /* the box can not move over the top - same logic, but old movement behavior as above */
+ real dist = (to->y - handle->pos.y); /* the potential movement */
+ if (dist > 0 ||
+ -dist < lifeline->rtop) {
+ lifeline->rbot += dist;
lifeline->rtop = lifeline->rbot - lifeline_rect_size(lifeline);
}
} else if (handle->id == HANDLE_BOXTOP) {
@@ -381,18 +431,10 @@ lifeline_draw(Lifeline *lifeline, DiaRenderer *renderer)
/* DiaObject menu handling */
-typedef enum {
- LIFELINE_CHANGE_ADD = 0x01,
- LIFELINE_CHANGE_DEL = 0x02,
- LIFELINE_CHANGE_INC = 0x03,
- LIFELINE_CHANGE_DEC = 0x04,
- LIFELINE_CHANGE_DEF = 0x05
-} LifelineChangeType;
-
typedef struct {
ObjectChange obj_change;
- ObjectChange *northeast,*southeast,*northwest,*southwest;
+ ObjectChange *east, *west;
real cp_distance_change;
LifelineChangeType type;
} LifelineChange;
@@ -401,10 +443,8 @@ static void
lifeline_change_apply(LifelineChange *change, DiaObject *obj)
{
if( change->type == LIFELINE_CHANGE_ADD || change->type == LIFELINE_CHANGE_DEL ) {
- change->northwest->apply(change->northwest,obj);
- change->southwest->apply(change->southwest,obj);
- change->northeast->apply(change->northeast,obj);
- change->southeast->apply(change->southeast,obj);
+ change->west->apply(change->west,obj);
+ change->east->apply(change->east,obj);
} else {
((Lifeline*)obj)->cp_distance += change->cp_distance_change;
}
@@ -415,10 +455,8 @@ static void
lifeline_change_revert(LifelineChange *change, DiaObject *obj)
{
if( change->type == LIFELINE_CHANGE_ADD || change->type == LIFELINE_CHANGE_DEL ) {
- change->northwest->revert(change->northwest,obj);
- change->southwest->revert(change->southwest,obj);
- change->northeast->revert(change->northeast,obj);
- change->southeast->revert(change->southeast,obj);
+ change->west->revert(change->west,obj);
+ change->east->revert(change->east,obj);
} else {
((Lifeline*)obj)->cp_distance -= change->cp_distance_change;
}
@@ -428,21 +466,13 @@ static void
lifeline_change_free(LifelineChange *change)
{
if( change->type == LIFELINE_CHANGE_ADD || change->type == LIFELINE_CHANGE_DEL ) {
- if (change->northeast->free)
- change->northeast->free(change->northeast);
- g_free(change->northeast);
-
- if (change->northwest->free)
- change->northwest->free(change->northwest);
- g_free(change->northwest);
+ if (change->east->free)
+ change->east->free(change->east);
+ g_free(change->east);
- if (change->southeast->free)
- change->southeast->free(change->southeast);
- g_free(change->southeast);
-
- if (change->southwest->free)
- change->southwest->free(change->southwest);
- g_free(change->southwest);
+ if (change->west->free)
+ change->west->free(change->west);
+ g_free(change->west);
}
}
@@ -460,16 +490,22 @@ lifeline_create_change(Lifeline *lifeline, LifelineChangeType changetype, Point
switch( vc->type )
{
case LIFELINE_CHANGE_ADD:
- vc->northeast = connpointline_add_point(lifeline->northeast,clicked);
- vc->northwest = connpointline_add_point(lifeline->northwest,clicked);
- vc->southeast = connpointline_add_point(lifeline->southeast,clicked);
- vc->southwest = connpointline_add_point(lifeline->southwest,clicked);
+ if (lifeline_point_above_mid (lifeline, clicked)) {
+ vc->east = connpointline_add_point(lifeline->northeast,clicked);
+ vc->west = connpointline_add_point(lifeline->northwest,clicked);
+ } else {
+ vc->east = connpointline_add_point(lifeline->southeast,clicked);
+ vc->west = connpointline_add_point(lifeline->southwest,clicked);
+ }
break;
case LIFELINE_CHANGE_DEL:
- vc->northeast = connpointline_remove_point(lifeline->northeast,clicked);
- vc->southwest = connpointline_remove_point(lifeline->southwest,clicked);
- vc->southeast = connpointline_remove_point(lifeline->southeast,clicked);
- vc->northwest = connpointline_remove_point(lifeline->northwest,clicked);
+ if (lifeline_point_above_mid (lifeline, clicked)) {
+ vc->east = connpointline_remove_point(lifeline->northeast,clicked);
+ vc->west = connpointline_remove_point(lifeline->northwest,clicked);
+ } else {
+ vc->east = connpointline_remove_point(lifeline->southeast,clicked);
+ vc->west = connpointline_remove_point(lifeline->southwest,clicked);
+ }
break;
case LIFELINE_CHANGE_INC:
vc->cp_distance_change = LIFELINE_CP_DISTANCE_INCREASE_FACTOR;
@@ -516,13 +552,14 @@ lifeline_get_object_menu(Lifeline *lifeline, Point *clickedpoint)
/* Set entries sensitive/selected etc here */
g_assert( (lifeline->northwest->num_connections ==
lifeline->northeast->num_connections) ||
- (lifeline->northwest->num_connections ==
- lifeline->southwest->num_connections) ||
(lifeline->southwest->num_connections ==
lifeline->southeast->num_connections) );
object_menu_items[0].active = 1;
- object_menu_items[1].active = (lifeline->northeast->num_connections > 0);
+ if (lifeline_point_above_mid (lifeline, clickedpoint))
+ object_menu_items[1].active = (lifeline->northeast->num_connections > 0);
+ else
+ object_menu_items[1].active = (lifeline->southeast->num_connections > 0);
return &object_menu;
}
@@ -552,7 +589,7 @@ lifeline_create(Point *startpoint,
obj->type = &lifeline_type;
obj->ops = &lifeline_ops;
- connection_init(conn, 4, 7);
+ connection_init(conn, LIFELINE_NUM_HANDLES, LIFELINE_NUM_STD_CPS);
lifeline->line_color = attributes_get_foreground();
lifeline->fill_color = attributes_get_background();
@@ -574,11 +611,17 @@ lifeline_create(Point *startpoint,
lifeline->boxtop_handle.connected_to = NULL;
obj->handles[3] = &lifeline->boxtop_handle;
+ lifeline->boxmid_handle.id = HANDLE_BOXMID;
+ lifeline->boxmid_handle.type = HANDLE_MINOR_CONTROL;
+ lifeline->boxmid_handle.connect_type = HANDLE_NONCONNECTABLE;
+ lifeline->boxmid_handle.connected_to = NULL;
+ obj->handles[4] = &lifeline->boxmid_handle;
+
/* Only the start point should be connectable */
obj->handles[1]->connect_type = HANDLE_NONCONNECTABLE;
/* Connection points */
- for (i=0;i<7;i++) {
+ for (i=0;i<LIFELINE_NUM_STD_CPS;i++) {
obj->connections[i] = &lifeline->connections[i];
lifeline->connections[i].object = obj;
lifeline->connections[i].connected = NULL;
@@ -633,6 +676,9 @@ lifeline_update_data(Lifeline *lifeline)
p2.x = p1.x;
p2.y = conn->endpoints[0].y + lifeline->rbot;
lifeline->boxbot_handle.pos = p2;
+ /* middle handle - between the cpls */
+ lifeline->boxmid_handle.pos.x = p1.x;
+ lifeline->boxmid_handle.pos.y = p1.y + (lifeline->cp_distance * (lifeline->northwest->num_connections + 1));
connection_update_handles(conn);
@@ -663,7 +709,7 @@ lifeline_update_data(Lifeline *lifeline)
pmw.x = pnw.x;
pme.x = pne.x;
- pmw.y = pme.y = (p1.y + p2.y)/2.0;
+ pmw.y = pme.y = (p1.y + lifeline->cp_distance * (lifeline->northwest->num_connections+1));
lifeline->connections[6].pos.x = conn->endpoints[0].x;
lifeline->connections[6].pos.y = conn->endpoints[0].y + lifeline->rbot;
@@ -700,15 +746,5 @@ lifeline_load(ObjectNode obj_node, int version, const char *filename)
obj_node,version,filename);
lifeline = (Lifeline*)obj;
- /* This magic is necessary to correctly load data
- from old lifeline behavior. It calculates the
- cp_distance in function of saved rtop-rbot distance and
- num of cp.
- ( It's just the inverse of lifeline_rect_size :)
- */
- if (lifeline)
- lifeline->cp_distance = (lifeline->rbot - lifeline->rtop)
- / ((lifeline->northwest->num_connections + 1) * 2.0);
-
return obj;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]