diff options
Diffstat (limited to 'generic/Track.c')
-rw-r--r-- | generic/Track.c | 2372 |
1 files changed, 0 insertions, 2372 deletions
diff --git a/generic/Track.c b/generic/Track.c deleted file mode 100644 index 63686c4..0000000 --- a/generic/Track.c +++ /dev/null @@ -1,2372 +0,0 @@ -/* - * Track.c -- Implementation of Track and WayPoint items. - * - * Authors : Patrick Lecoanet. - * Creation date : - * - * $Id$ - */ - -/* - * Copyright (c) 1993 - 2005 CENA, Patrick Lecoanet -- - * - * See the file "Copyright" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - */ - - -#include "Types.h" -#include "Track.h" -#include "Draw.h" -#include "Geo.h" -#include "Item.h" -#include "Group.h" -#include "WidgetInfo.h" -#include "Image.h" -#include "tkZinc.h" - -#include <ctype.h> -#include <stdlib.h> - - -static const char rcsid[] = "$Id$"; -static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; - -/* - * Define this to enable overlap manager setting - * the label distance rho. - */ -#undef DP - -/* - * Some default values -*/ -#define DEFAULT_MARKER_SIZE 0 -#define DEFAULT_LABEL_ANGLE 20 -#define DEFAULT_LABEL_DISTANCE 50 -#define DEFAULT_LINE_WIDTH 1 -#define DEFAULT_LABEL_PREFERRED_ANGLE 0 -#define DEFAULT_CONVERGENCE_STYLE 0 - -#define SPEED_VECTOR_PICKING_THRESHOLD 5 /* In pixels */ - -/* - * Sets a threshold for calculating distance from label_dx, label_dy. - * Above this threshold value, the module is discarded, label_distance - * is preferred. - */ -#define LABEL_DISTANCE_THRESHOLD 5 - -#define MARKER_FILLED_BIT 1 << 0 -#define FILLED_HISTORY_BIT 1 << 1 -#define DOT_MIXED_HISTORY_BIT 1 << 2 -#define CIRCLE_HISTORY_BIT 1 << 3 -#define SV_MARK_BIT 1 << 4 -#define SV_TICKS_BIT 1 << 5 -#define POLAR_BIT 1 << 6 -#define FROZEN_LABEL_BIT 1 << 7 -#define LAST_AS_FIRST_BIT 1 << 8 -#define HISTORY_VISIBLE_BIT 1 << 9 - -#define CURRENT_POSITION -2 -#define LEADER -3 -#define CONNECTION -4 -#define SPEED_VECTOR -5 - - -/* -********************************************************************************** -* -* Specific Track item record -* -********************************************************************************** -*/ -typedef struct { - ZnPoint world; /* world coord of pos */ - ZnPoint dev; /* dev coord of pos */ - ZnBool visible; -} HistoryStruct, *History; - -typedef struct _TrackItemStruct { - ZnItemStruct header; - - /* Public data */ - unsigned short flags; - ZnImage symbol; /* item symbol */ - ZnGradient *symbol_color; - int label_angle; /* Label angle from track. */ - ZnDim label_distance; /* Label distance from track. */ - ZnDim label_dx; /* Label dx/dy from track. */ - ZnDim label_dy; - int label_preferred_angle; - int label_convergence_style; - Tk_Anchor label_anchor; - ZnLeaderAnchors leader_anchors; /* Spec of the leader attachment */ - ZnGradient *leader_color; /* leader color */ - ZnLineStyle leader_style; - ZnLineShape leader_shape; - ZnLineEnd leader_first_end; - ZnLineEnd leader_last_end; - ZnDim leader_width; - ZnDim marker_size; /* world size of error circle */ - ZnGradient *marker_color; /* error circle color */ - ZnLineStyle marker_style; /* error circle style */ - ZnImage marker_fill_pattern; /* error circle fill pattern */ - ZnGradient *connection_color; /* connection color */ - ZnLineStyle connection_style; - ZnDim connection_width; - ZnGradient *speed_vector_color; /* s. v. color */ - ZnPoint pos; /* item world coordinates */ - ZnPoint speed_vector; /* s. v. slope in world coord */ - ZnDim speed_vector_width; - ZnGradient *history_color; - ZnDim history_width; - - /* Private data */ - ZnFieldSetStruct field_set; - ZnPoint dev; /* device coords of current pos */ - ZnPoint speed_vector_dev; /* s. v. end in device coord */ - ZnDim marker_size_dev; /* dev size of error circle */ - ZnList history; /* pos list */ - ZnList leader_points; -} TrackItemStruct, *TrackItem; - - -static ZnAttrConfig track_attrs[] = { - { ZN_CONFIG_BOOL, "-circlehistory", NULL, - Tk_Offset(TrackItemStruct, flags), CIRCLE_HISTORY_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-composealpha", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_COMPOSE_ALPHA_BIT, - ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-composerotation", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_COMPOSE_ROTATION_BIT, - ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-composescale", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_COMPOSE_SCALE_BIT, - ZN_COORDS_FLAG, False }, - { ZN_CONFIG_ITEM, "-connecteditem", NULL, - Tk_Offset(TrackItemStruct, header.connected_item), 0, - ZN_COORDS_FLAG|ZN_ITEM_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-connectioncolor", NULL, - Tk_Offset(TrackItemStruct, connection_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-connectionsensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(CONNECTION), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_LINE_STYLE, "-connectionstyle", NULL, - Tk_Offset(TrackItemStruct, connection_style), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-connectionwidth", NULL, - Tk_Offset(TrackItemStruct, connection_width), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-filledhistory", NULL, - Tk_Offset(TrackItemStruct, flags), FILLED_HISTORY_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-filledmarker", NULL, - Tk_Offset(TrackItemStruct, flags), MARKER_FILLED_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-frozenlabel", NULL, - Tk_Offset(TrackItemStruct, flags), FROZEN_LABEL_BIT, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-historycolor", NULL, - Tk_Offset(TrackItemStruct, history_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-historywidth", NULL, - Tk_Offset(TrackItemStruct, history_width), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_ANCHOR, "-labelanchor", NULL, - Tk_Offset(TrackItemStruct, label_anchor), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_ANGLE, "-labelangle", NULL, - Tk_Offset(TrackItemStruct, label_angle), 0, - ZN_COORDS_FLAG|ZN_POLAR_FLAG, False }, - { ZN_CONFIG_UINT, "-labelconvergencestyle", NULL, - Tk_Offset(TrackItemStruct, label_convergence_style), 0, 0, False }, - { ZN_CONFIG_DIM, "-labeldistance", NULL, - Tk_Offset(TrackItemStruct, label_distance), 0, - ZN_COORDS_FLAG|ZN_POLAR_FLAG, False }, - { ZN_CONFIG_DIM, "-labeldx", NULL, - Tk_Offset(TrackItemStruct, label_dx), 0, - ZN_COORDS_FLAG|ZN_CARTESIAN_FLAG, False }, - { ZN_CONFIG_DIM, "-labeldy", NULL, - Tk_Offset(TrackItemStruct, label_dy), 0, - ZN_COORDS_FLAG|ZN_CARTESIAN_FLAG, False }, - { ZN_CONFIG_LABEL_FORMAT, "-labelformat", NULL, - Tk_Offset(TrackItemStruct, field_set.label_format), 0, - ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_ANGLE, "-labelpreferredangle", NULL, - Tk_Offset(TrackItemStruct, label_preferred_angle), 0, 0, False }, - { ZN_CONFIG_BOOL, "-lastasfirst", NULL, - Tk_Offset(TrackItemStruct, flags), LAST_AS_FIRST_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_LEADER_ANCHORS, "-leaderanchors", NULL, - Tk_Offset(TrackItemStruct, leader_anchors), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-leadercolor", NULL, - Tk_Offset(TrackItemStruct, leader_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_LINE_END, "-leaderfirstend", NULL, - Tk_Offset(TrackItemStruct, leader_first_end), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_LINE_END, "-leaderlastend", NULL, - Tk_Offset(TrackItemStruct, leader_last_end), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-leadersensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(LEADER), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_LINE_STYLE, "-leaderstyle", NULL, - Tk_Offset(TrackItemStruct, leader_style), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_LINE_SHAPE, "-leadershape", NULL, - Tk_Offset(TrackItemStruct, leader_shape), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_DIM, "-leaderwidth", NULL, - Tk_Offset(TrackItemStruct, leader_width), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-markercolor", NULL, - Tk_Offset(TrackItemStruct, marker_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BITMAP, "-markerfillpattern", NULL, - Tk_Offset(TrackItemStruct, marker_fill_pattern), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-markersize", NULL, - Tk_Offset(TrackItemStruct, marker_size), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_LINE_STYLE, "-markerstyle", NULL, - Tk_Offset(TrackItemStruct, marker_style), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-mixedhistory", NULL, - Tk_Offset(TrackItemStruct, flags), DOT_MIXED_HISTORY_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_UINT, "-numfields", NULL, - Tk_Offset(TrackItemStruct, field_set.num_fields), 0, 0, True }, - { ZN_CONFIG_POINT, "-position", NULL, Tk_Offset(TrackItemStruct, pos), 0, - ZN_COORDS_FLAG|ZN_MOVED_FLAG, False}, - { ZN_CONFIG_PRI, "-priority", NULL, - Tk_Offset(TrackItemStruct, header.priority), 0, - ZN_DRAW_FLAG|ZN_REPICK_FLAG, False }, - { ZN_CONFIG_BOOL, "-sensitive", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_SENSITIVE_BIT, ZN_REPICK_FLAG, False }, - { ZN_CONFIG_POINT, "-speedvector", NULL, Tk_Offset(TrackItemStruct, speed_vector), 0, - ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-speedvectorcolor", NULL, - Tk_Offset(TrackItemStruct, speed_vector_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-speedvectormark", NULL, - Tk_Offset(TrackItemStruct, flags), SV_MARK_BIT, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-speedvectorsensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(SPEED_VECTOR), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_BOOL, "-speedvectorticks", NULL, - Tk_Offset(TrackItemStruct, flags), SV_TICKS_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-speedvectorwidth", NULL, - Tk_Offset(TrackItemStruct, speed_vector_width), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BITMAP, "-symbol", NULL, - Tk_Offset(TrackItemStruct, symbol), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-symbolcolor", NULL, - Tk_Offset(TrackItemStruct, symbol_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-symbolsensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(CURRENT_POSITION), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_TAG_LIST, "-tags", NULL, - Tk_Offset(TrackItemStruct, header.tags), 0, 0, False }, - { ZN_CONFIG_BOOL, "-visible", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_VISIBLE_BIT, - ZN_DRAW_FLAG|ZN_REPICK_FLAG|ZN_VIS_FLAG, False }, - { ZN_CONFIG_BOOL, "-historyvisible", NULL, - Tk_Offset(TrackItemStruct, flags), HISTORY_VISIBLE_BIT, ZN_COORDS_FLAG, False }, - - { ZN_CONFIG_END, NULL, NULL, 0, 0, 0, False } -}; - -static ZnAttrConfig wp_attrs[] = { - { ZN_CONFIG_BOOL, "-composealpha", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_COMPOSE_ALPHA_BIT, - ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-composerotation", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_COMPOSE_ROTATION_BIT, - ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-composescale", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_COMPOSE_SCALE_BIT, - ZN_COORDS_FLAG, False }, - { ZN_CONFIG_ITEM, "-connecteditem", NULL, - Tk_Offset(TrackItemStruct, header.connected_item), 0, - ZN_COORDS_FLAG|ZN_ITEM_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-connectioncolor", NULL, - Tk_Offset(TrackItemStruct, connection_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-connectionsensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(CONNECTION), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_LINE_STYLE, "-connectionstyle", NULL, - Tk_Offset(TrackItemStruct, connection_style), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-connectionwidth", NULL, - Tk_Offset(TrackItemStruct, connection_width), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-filledmarker", NULL, - Tk_Offset(TrackItemStruct, flags), MARKER_FILLED_BIT, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_ANCHOR, "-labelanchor", NULL, - Tk_Offset(TrackItemStruct, label_anchor), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_ANGLE, "-labelangle", NULL, - Tk_Offset(TrackItemStruct, label_angle), 0, - ZN_COORDS_FLAG|ZN_POLAR_FLAG, False }, - { ZN_CONFIG_DIM, "-labeldistance", NULL, - Tk_Offset(TrackItemStruct, label_distance), 0, - ZN_COORDS_FLAG|ZN_POLAR_FLAG, False }, - { ZN_CONFIG_DIM, "-labeldx", NULL, - Tk_Offset(TrackItemStruct, label_dx), 0, - ZN_COORDS_FLAG|ZN_CARTESIAN_FLAG, False }, - { ZN_CONFIG_DIM, "-labeldy", NULL, - Tk_Offset(TrackItemStruct, label_dy), 0, - ZN_COORDS_FLAG|ZN_CARTESIAN_FLAG, False }, - { ZN_CONFIG_LABEL_FORMAT, "-labelformat", NULL, - Tk_Offset(TrackItemStruct, field_set.label_format), 0, - ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_LEADER_ANCHORS, "-leaderanchors", NULL, - Tk_Offset(TrackItemStruct, leader_anchors), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-leadercolor", NULL, - Tk_Offset(TrackItemStruct, leader_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_LINE_END, "-leaderfirstend", NULL, - Tk_Offset(TrackItemStruct, leader_first_end), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_LINE_END, "-leaderlastend", NULL, - Tk_Offset(TrackItemStruct, leader_last_end), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-leadersensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(LEADER), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_LINE_SHAPE, "-leadershape", NULL, - Tk_Offset(TrackItemStruct, leader_shape), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_LINE_STYLE, "-leaderstyle", NULL, - Tk_Offset(TrackItemStruct, leader_style), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-leaderwidth", NULL, - Tk_Offset(TrackItemStruct, leader_width), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-markercolor", NULL, - Tk_Offset(TrackItemStruct, marker_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BITMAP, "-markerfillpattern", NULL, - Tk_Offset(TrackItemStruct, marker_fill_pattern), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-markersize", NULL, - Tk_Offset(TrackItemStruct, marker_size), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_LINE_STYLE, "-markerstyle", NULL, - Tk_Offset(TrackItemStruct, marker_style), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_UINT, "-numfields", NULL, - Tk_Offset(TrackItemStruct, field_set.num_fields), 0, 0, True }, - { ZN_CONFIG_POINT, "-position", NULL, Tk_Offset(TrackItemStruct, pos), 0, - ZN_COORDS_FLAG, False}, - { ZN_CONFIG_PRI, "-priority", NULL, - Tk_Offset(TrackItemStruct, header.priority), 0, - ZN_DRAW_FLAG|ZN_REPICK_FLAG, False }, - { ZN_CONFIG_BOOL, "-sensitive", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_SENSITIVE_BIT, ZN_REPICK_FLAG, False }, - { ZN_CONFIG_BITMAP, "-symbol", NULL, - Tk_Offset(TrackItemStruct, symbol), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-symbolcolor", NULL, - Tk_Offset(TrackItemStruct, symbol_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-symbolsensitive", NULL, - Tk_Offset(TrackItemStruct, header.part_sensitive), ZnPartToBit(CURRENT_POSITION), - ZN_REPICK_FLAG, False }, - { ZN_CONFIG_TAG_LIST, "-tags", NULL, - Tk_Offset(TrackItemStruct, header.tags), 0, 0, False }, - { ZN_CONFIG_BOOL, "-visible", NULL, - Tk_Offset(TrackItemStruct, header.flags), ZN_VISIBLE_BIT, - ZN_DRAW_FLAG|ZN_REPICK_FLAG|ZN_VIS_FLAG, False }, - - { ZN_CONFIG_END, NULL, NULL, 0, 0, 0, False } -}; - - - -/* -********************************************************************************** -* -* Init -- -* -********************************************************************************** -*/ -static int -Init(ZnItem item, - int *argc, - Tcl_Obj *CONST *args[]) -{ - TrackItem track = (TrackItem) item; - ZnFieldSet field_set = &track->field_set; - ZnWInfo *wi = item->wi; - int num_fields; - - /*printf("size of a track = %d\n", sizeof(TrackItemStruct));*/ - - SET(item->flags, ZN_VISIBLE_BIT); - SET(item->flags, ZN_SENSITIVE_BIT); - SET(item->flags, ZN_COMPOSE_ALPHA_BIT); - SET(item->flags, ZN_COMPOSE_ROTATION_BIT); - SET(item->flags, ZN_COMPOSE_SCALE_BIT); - SET(item->part_sensitive, ZnPartToBit(CURRENT_POSITION)); - SET(item->part_sensitive, ZnPartToBit(LEADER)); - SET(item->part_sensitive, ZnPartToBit(CONNECTION)); - SET(item->part_sensitive, ZnPartToBit(SPEED_VECTOR)); - track->symbol_color = ZnGetGradientByValue(wi->fore_color); - track->symbol = ZnGetImageByValue(wi->track_symbol, NULL, NULL); - track->label_anchor = TK_ANCHOR_CENTER; - track->label_angle = DEFAULT_LABEL_ANGLE; - track->label_distance = DEFAULT_LABEL_DISTANCE; - SET(track->flags, POLAR_BIT); - CLEAR(track->flags, FROZEN_LABEL_BIT); - - track->label_preferred_angle = DEFAULT_LABEL_PREFERRED_ANGLE; - track->label_convergence_style = DEFAULT_CONVERGENCE_STYLE ; - - track->leader_anchors = NULL; - track->leader_color = ZnGetGradientByValue(wi->fore_color); - track->leader_style = ZN_LINE_SIMPLE; - track->leader_shape = ZN_LINE_STRAIGHT; - track->leader_width = DEFAULT_LINE_WIDTH; - track->connection_color = ZnGetGradientByValue(wi->fore_color); - track->connection_style = ZN_LINE_SIMPLE; - track->connection_width = DEFAULT_LINE_WIDTH; - track->marker_color = ZnGetGradientByValue(wi->fore_color); - track->marker_style = ZN_LINE_SIMPLE; - track->marker_fill_pattern = ZnUnspecifiedImage; - track->speed_vector_color = ZnGetGradientByValue(wi->fore_color); - track->history_color = ZnGetGradientByValue(wi->fore_color); - track->history_width = 8; - CLEAR(track->flags, MARKER_FILLED_BIT); - SET(track->flags, FILLED_HISTORY_BIT); - CLEAR(track->flags, DOT_MIXED_HISTORY_BIT); - CLEAR(track->flags, CIRCLE_HISTORY_BIT); - CLEAR(track->flags, LAST_AS_FIRST_BIT); - CLEAR(track->flags, SV_MARK_BIT); - CLEAR(track->flags, SV_TICKS_BIT); - - if (item->class == ZnTrack) { - item->priority = 1; - SET(track->flags, HISTORY_VISIBLE_BIT); - track->marker_size = DEFAULT_MARKER_SIZE; - track->speed_vector.x = 0; - track->speed_vector.y = 0; - track->speed_vector_width = DEFAULT_LINE_WIDTH; - } - else { - item->priority = 1; - CLEAR(track->flags, HISTORY_VISIBLE_BIT); - track->marker_size = 0; - track->speed_vector.x = 0.0; - track->speed_vector.y = 10.0; - } - field_set->item = item; - field_set->label_format = NULL; - /* - * Then try to see if some fields are needed. - */ - if ((*argc > 0) && (Tcl_GetString((*args)[0])[0] != '-') && - (Tcl_GetIntFromObj(wi->interp, (*args)[0], &num_fields) != TCL_ERROR)) { - field_set->num_fields = num_fields; - *args += 1; - *argc -= 1; - ZnFIELD.InitFields(field_set); - } - else { - Tcl_AppendResult(wi->interp, " number of fields expected", NULL); - return TCL_ERROR; - } - - track->pos.x = 0; - track->pos.y = 0; - track->field_set.label_pos.x = 0; - track->field_set.label_pos.y = 0; - track->leader_first_end = NULL; - track->leader_last_end = NULL; - - track->history = NULL; - track->dev.x = 0; - track->dev.y = 0; - track->speed_vector_dev.x = 0; - track->speed_vector_dev.y = 0; - track->marker_size_dev = 0; - track->leader_points = NULL; - - return TCL_OK; -} - - -/* -********************************************************************************** -* -* Clone -- -* -********************************************************************************** -*/ -static void -Clone(ZnItem item) -{ - TrackItem track = (TrackItem) item; - - if (track->history) { - track->history = ZnListDuplicate(track->history); - } - track->dev.x = 0; - track->dev.y = 0; - track->speed_vector_dev.x = 0; - track->speed_vector_dev.y = 0; - track->marker_size_dev = 0; - if (track->leader_points) { - track->leader_points = ZnListDuplicate(track->leader_points); - } - if (track->leader_first_end) { - ZnLineEndDuplicate(track->leader_first_end); - } - if (track->leader_last_end) { - ZnLineEndDuplicate(track->leader_last_end); - } - - ZnFIELD.CloneFields(&track->field_set); - track->field_set.item = item; - - /* - * We get all shared resources, colors bitmaps. - */ - track->symbol_color = ZnGetGradientByValue(track->symbol_color); - track->leader_color = ZnGetGradientByValue(track->leader_color); - track->connection_color = ZnGetGradientByValue(track->connection_color); - track->marker_color = ZnGetGradientByValue(track->marker_color); - track->speed_vector_color = ZnGetGradientByValue(track->speed_vector_color); - track->history_color = ZnGetGradientByValue(track->history_color); - if (track->symbol != ZnUnspecifiedImage) { - track->symbol = ZnGetImageByValue(track->symbol, NULL, NULL); - } - if (track->marker_fill_pattern != ZnUnspecifiedImage) { - track->marker_fill_pattern = ZnGetImageByValue(track->marker_fill_pattern, NULL, NULL); - } -} - - -/* -********************************************************************************** -* -* Destroy -- -* -********************************************************************************** -*/ -static void -Destroy(ZnItem item) -{ - TrackItem track = (TrackItem) item; - - if (track->leader_points) { - ZnListFree(track->leader_points); - } - if (track->leader_first_end) { - ZnLineEndDelete(track->leader_first_end); - } - if (track->leader_last_end) { - ZnLineEndDelete(track->leader_last_end); - } - - if (track->history) { - ZnListFree(track->history); - } - - /* - * Release shared resources. - */ - ZnFreeGradient(track->symbol_color); - ZnFreeGradient(track->leader_color); - ZnFreeGradient(track->connection_color); - ZnFreeGradient(track->marker_color); - ZnFreeGradient(track->speed_vector_color); - ZnFreeGradient(track->history_color); - if (track->symbol != ZnUnspecifiedImage) { - ZnFreeImage(track->symbol, NULL, NULL); - track->symbol = ZnUnspecifiedImage; - } - if (track->marker_fill_pattern != ZnUnspecifiedImage) { - ZnFreeImage(track->marker_fill_pattern, NULL, NULL); - track->marker_fill_pattern = ZnUnspecifiedImage; - } - - ZnFIELD.FreeFields(&track->field_set); -} - - -/* -********************************************************************************** -* -* Configure -- -* -********************************************************************************** -*/ -static void -AddToHistory(TrackItem track, - ZnPoint old_pos) -{ - ZnWInfo *wi = ((ZnItem) track)->wi; - - if (track->history) { - HistoryStruct hist; - - hist.world = old_pos; - hist.dev = track->dev; - hist.visible = True; - ZnListAdd(track->history, &hist, ZnListHead); - ZnListTruncate(track->history, wi->track_managed_history_size); - } - else { - /* We do not shift the first time we move as the preceding position - * is not valid. */ - /*printf("creating history\n");*/ - track->history = ZnListNew(wi->track_managed_history_size+1, - sizeof(HistoryStruct)); - } -} - -static int -Configure(ZnItem item, - int argc, - Tcl_Obj *CONST argv[], - int *flags) -{ - TrackItem track = (TrackItem) item; - ZnWInfo *wi = item->wi; - ZnItem old_connected; - ZnPoint old_pos; - - old_pos = track->pos; - old_connected = item->connected_item; - - if (ZnConfigureAttributes(wi, item, item, track_attrs, argc, argv, flags) == TCL_ERROR) { - return TCL_ERROR; - } - - if (track->label_angle < 0) { - track->label_angle = 360 + track->label_angle; - } - - /* - * Adapt to the new label locating system. - */ - if (ISSET(*flags, ZN_POLAR_FLAG)) { - SET(track->flags, POLAR_BIT); - ZnGroupSetCallOm(item->parent, True); - } - else if (ISSET(*flags, ZN_CARTESIAN_FLAG)) { - CLEAR(track->flags, POLAR_BIT); - ZnGroupSetCallOm(item->parent, True); - } - - if (ISSET(*flags, ZN_ITEM_FLAG)) { - /* - * If the new connected item is not appropriate back up - * to the old one. - */ - if ((item->connected_item == ZN_NO_ITEM) || - (((item->connected_item->class == ZnTrack) || - (item->connected_item->class == ZnWayPoint)) && - (item->parent == item->connected_item->parent))) { - ZnITEM.UpdateItemDependency(item, old_connected); - } - else { - item->connected_item = old_connected; - } - } - - if (ISSET(*flags, ZN_VIS_FLAG)) { - /* Record the change to trigger the overlap manager latter */ - if ((item->class == ZnTrack) && ISSET(item->flags, ZN_VISIBLE_BIT)) { - ZnGroupSetCallOm(item->parent, True); - } - } - - /* If the current position has changed, shift the past pos. */ - if (ISSET(*flags, ZN_MOVED_FLAG)) { - if (item->class == ZnTrack) { - AddToHistory(track, old_pos); - ZnGroupSetCallOm(item->parent, True); - } - } - - return TCL_OK; -} - - -/* -********************************************************************************** -* -* Query -- -* -********************************************************************************** -*/ -static int -Query(ZnItem item, - int argc, - Tcl_Obj *CONST argv[]) -{ - if (ZnQueryAttribute(item->wi->interp, item, track_attrs, argv[0]) == TCL_ERROR) { - return TCL_ERROR; - } - - return TCL_OK; -} - - -/* -********************************************************************************** -* -* ComputeCoordinates -- -* -********************************************************************************** -*/ -static void -ComputeCoordinates(ZnItem item, - ZnBool force) -{ - ZnWInfo *wi = item->wi; - TrackItem track = (TrackItem) item; - ZnFieldSet field_set = &track->field_set; - ZnItem c_item; - History hist; - ZnPoint old_label_pos, old_pos, p, xp; - ZnDim old_label_width, old_label_height; - ZnReal rotation; - ZnBBox bbox; - ZnPoint *points; - unsigned int num_points, num_acc_pos, i; - int alignment; - int w2=0, h2=0, w=0, h=0; - - ZnResetBBox(&item->item_bounding_box); - old_label_pos = field_set->label_pos; - old_label_width = field_set->label_width; - old_label_height = field_set->label_height; - - old_pos = track->dev; - - ZnTransformPoint(wi->current_transfo, &track->pos, &track->dev); - track->dev.x = ZnNearestInt(track->dev.x); - track->dev.y = ZnNearestInt(track->dev.y); - /*printf("track pos %g %g --> %g %g\n", track->pos.x, track->pos.y, track->dev.x, track->dev.y);*/ - if (track->symbol != ZnUnspecifiedImage) { - ZnSizeOfImage(track->symbol, &w, &h); - /*printf("taille symbole %d %d\n", w, h);*/ - w2 = (w+1)/2; - h2 = (h+1)/2; - bbox.orig.x = track->dev.x - w2; - bbox.orig.y = track->dev.y - h2; - bbox.corner.x = bbox.orig.x + w; - bbox.corner.y = bbox.orig.y + h; - - ZnAddBBoxToBBox(&item->item_bounding_box, &bbox); - } - - /* Here we approximate the past position sizes to the size - of the current position. They are actually smaller but who - care :-). In fact it is even worse as we use the overall - information from the symbol font. - */ - if ((item->class == ZnTrack) && track->history) { - unsigned int visible_history_size; - /* - * Trunc the visible history to the managed size. - */ - ZnListTruncate(track->history, wi->track_managed_history_size); - visible_history_size = (ISSET(track->flags, HISTORY_VISIBLE_BIT) ? - wi->track_visible_history_size : 0); - - ZnResetBBox(&bbox); - w = (int) track->history_width; - w2 = (w+1)/2; - num_acc_pos = ZnListSize(track->history); - hist = ZnListArray(track->history); - for (i = 0; i < num_acc_pos; i++) { - ZnTransformPoint(wi->current_transfo, &hist[i].world, &hist[i].dev); - if ((i < visible_history_size) && (hist[i].visible)) { - bbox.orig.x = hist[i].dev.x - w2; - bbox.orig.y = hist[i].dev.y - w2; - bbox.corner.x = bbox.orig.x + w; - bbox.corner.y = bbox.orig.y + w; - ZnAddBBoxToBBox(&item->item_bounding_box, &bbox); - } - } - } - - /* - * Compute the speed vector end. - */ - if (item->class == ZnTrack) { - p.x = track->pos.x + track->speed_vector.x * wi->speed_vector_length; - p.y = track->pos.y + track->speed_vector.y * wi->speed_vector_length; - ZnTransformPoint(wi->current_transfo, &p, &track->speed_vector_dev); - track->speed_vector_dev.x = ZnNearestInt(track->speed_vector_dev.x); - track->speed_vector_dev.y = ZnNearestInt(track->speed_vector_dev.y); - if (ISSET(track->flags, SV_MARK_BIT)) { - int w = (int) track->speed_vector_width + 1; - ZnAddPointToBBox(&item->item_bounding_box, - track->speed_vector_dev.x - w, - track->speed_vector_dev.y - w); - ZnAddPointToBBox(&item->item_bounding_box, - track->speed_vector_dev.x + w, - track->speed_vector_dev.y + w); - } - else { - ZnAddPointToBBox(&item->item_bounding_box, track->speed_vector_dev.x, - track->speed_vector_dev.y); - } - } - - /* - * Take care of the connection between items. - */ - c_item = item->connected_item; - if ((c_item != ZN_NO_ITEM) && (track->connection_width > 0)) { - w2 = (int) track->connection_width/2; - ZnAddPointToBBox(&item->item_bounding_box, track->dev.x-w2, track->dev.y-w2); - ZnAddPointToBBox(&item->item_bounding_box, ((TrackItem)c_item)->dev.x+w2, - ((TrackItem)c_item)->dev.y+w2); - } - - /* - * Compute the size of the circular marker. - */ - p.x = track->pos.x + track->marker_size; - p.y = track->pos.y; - ZnTransformPoint(wi->current_transfo, &p, &xp); - xp.x = xp.x - track->dev.x; - xp.y = xp.y - track->dev.y; - track->marker_size_dev = sqrt(xp.x*xp.x + xp.y*xp.y); - track->marker_size_dev = ZnNearestInt(track->marker_size_dev); - if (track->marker_size_dev > PRECISION_LIMIT) { - ZnAddPointToBBox(&item->item_bounding_box, - track->dev.x - (ZnPos) track->marker_size_dev, - track->dev.y - (ZnPos) track->marker_size_dev); - ZnAddPointToBBox(&item->item_bounding_box, - track->dev.x + (ZnPos) track->marker_size_dev, - track->dev.y + (ZnPos) track->marker_size_dev); - } - - /* Compute the new label bounding box. */ - if (field_set->label_format && field_set->num_fields) { - ZnDim bb_width, bb_height; - ZnReal rho, dist; - ZnPoint leader_end; - int it; - - ZnFIELD.GetLabelBBox(field_set, &bb_width, &bb_height); - /* - * Compute the label position. - */ - if (ISSET(track->flags, POLAR_BIT)) { - rho = track->label_distance; - /* - * Compute heading after applying the transform. - */ - ZnTransfoDecompose(wi->current_transfo, NULL, NULL, &rotation, NULL); - /*printf("rotation=%g, heading=%g, angle=%d\n", rotation, - ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y), - track->label_angle);*/ - rotation = ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y)-rotation; - it = 0; - while (1) { - ZnPointPolarToCartesian(rotation, rho, (ZnReal) track->label_angle, - &track->label_dx, &track->label_dy); - field_set->label_pos.x = track->dev.x + track->label_dx; - field_set->label_pos.y = track->dev.y - track->label_dy; - ZnAnchor2Origin(&field_set->label_pos, bb_width, bb_height, - track->label_anchor, &field_set->label_pos); - ZnResetBBox(&bbox); - ZnAddPointToBBox(&bbox, field_set->label_pos.x, field_set->label_pos.y); - ZnAddPointToBBox(&bbox, field_set->label_pos.x + bb_width, field_set->label_pos.y + bb_height); - dist = ZnRectangleToPointDist(&bbox, &track->dev); - dist = track->label_distance - dist; - if (ABS(dist) < 1.0 || it > 5) { - break; - } - it++; - rho += dist; - } - } - else { - field_set->label_pos.x = track->dev.x + track->label_dx; - field_set->label_pos.y = track->dev.y - track->label_dy; - ZnAnchor2Origin(&field_set->label_pos, bb_width, bb_height, - track->label_anchor, &field_set->label_pos); - } - field_set->label_pos.x = ZnNearestInt(field_set->label_pos.x); - field_set->label_pos.y = ZnNearestInt(field_set->label_pos.y); - - /* - * Need to compensate for GL thick lines - */ -#ifdef GL -#define CORR 1 -#else -#define CORR 0 -#endif - ZnAddPointToBBox(&item->item_bounding_box, field_set->label_pos.x - CORR, field_set->label_pos.y - CORR); - ZnAddPointToBBox(&item->item_bounding_box, - field_set->label_pos.x + (ZnPos) bb_width + CORR, - field_set->label_pos.y + (ZnPos) bb_height + CORR); -#undef CORR - - /* - * Process the leader. - */ - if (track->leader_width > 0) { - int left_x, left_y, right_x, right_y; - ZnPoint end_points[ZN_LINE_END_POINTS]; - - /* - * Compute the actual leader end in the label. - */ - if (track->leader_anchors) { - left_x = track->leader_anchors->left_x; - right_x = track->leader_anchors->right_x; - left_y = track->leader_anchors->left_y; - right_y = track->leader_anchors->right_y; - } - else { - left_x = right_x = left_y = right_y = 50; - } - if (track->label_angle >= 270 || track->label_angle < 90) { - if (track->leader_anchors && (left_y < 0)) { - ZnFIELD.GetFieldBBox(field_set, (unsigned int) left_x, &bbox); - leader_end.x = bbox.orig.x; - leader_end.y = bbox.corner.y; - } - else { - leader_end.x = field_set->label_pos.x + left_x*bb_width/100; - leader_end.y = field_set->label_pos.y + left_y*bb_height/100; - } - alignment = ZN_AA_LEFT; - } - else { - if (track->leader_anchors && (right_y < 0)) { - ZnFIELD.GetFieldBBox(field_set, (unsigned int) right_x, &bbox); - leader_end.x = bbox.corner.x; - leader_end.y = bbox.corner.y; - } - else { - leader_end.x = field_set->label_pos.x + right_x*bb_width/100; - leader_end.y = field_set->label_pos.y + right_y*bb_height/100; - } - alignment = ZN_AA_RIGHT; - } - - ZnFIELD.SetFieldsAutoAlign(field_set, alignment); - - /* Clip the leader on the label's fields */ - ZnFIELD.LeaderToLabel(field_set, &track->dev, &leader_end); - - /* Setup leader shape points */ - if (!track->leader_points) { - track->leader_points = ZnListNew(ZN_LINE_SHAPE_POINTS, sizeof(ZnPoint)); - } - ZnLineShapePoints(&track->dev, &leader_end, track->leader_width, - track->leader_shape, &bbox, track->leader_points); - ZnAddBBoxToBBox(&item->item_bounding_box, &bbox); - points = (ZnPoint *) ZnListArray(track->leader_points); - num_points = ZnListSize(track->leader_points); - - /* Setup leader ends */ - if (track->leader_first_end != NULL) { - ZnGetLineEnd(&points[0], &points[1], track->leader_width, - CapRound, track->leader_first_end, end_points); - ZnAddPointsToBBox(&item->item_bounding_box, end_points, ZN_LINE_END_POINTS); - } - if (track->leader_last_end != NULL) { - ZnGetLineEnd(&points[num_points-1], &points[num_points-2], track->leader_width, - CapRound, track->leader_last_end, end_points); - ZnAddPointsToBBox(&item->item_bounding_box, end_points, ZN_LINE_END_POINTS); - } - } - } - - /* Update connected items. */ - if ((old_label_pos.x != field_set->label_pos.x) || - (old_label_pos.y != field_set->label_pos.y) || - (old_label_width != field_set->label_width) || - (old_label_height != field_set->label_height) || - (old_pos.x != track->dev.x) || - (old_pos.y != track->dev.y)) { - /* Update connected items */ - SET(item->flags, ZN_UPDATE_DEPENDENT_BIT); - } -} - - -/* -********************************************************************************** -* -* ToArea -- -* Tell if the object is entirely outside (-1), -* entirely inside (1) or in between (0). -* -********************************************************************************** -*/ -static int -ToArea(ZnItem item, - ZnToArea ta) -{ - TrackItem track = (TrackItem) item; - int inside; - int width, height; - ZnDim lwidth, lheight; - ZnBBox bbox, *area = ta->area; - ZnPoint pts[2]; - - /* - * Try the current position. - */ - ZnResetBBox(&bbox); - if (track->symbol != ZnUnspecifiedImage) { - ZnSizeOfImage(track->symbol, &width, &height); - bbox.orig.x = track->dev.x-(width+1)/2; - bbox.orig.y = track->dev.y-(height+1)/2; - bbox.corner.x = bbox.orig.x + width; - bbox.corner.y = bbox.orig.y + height; - } - inside = ZnBBoxInBBox(&bbox, area); - if (inside == 0) { - /*printf("track pos\n");*/ - return 0; - } - - /* - * Try the fields. - */ - ZnFIELD.GetLabelBBox(&track->field_set, &lwidth, &lheight); - if ((lwidth > 0.0) && (lheight > 0.0)) { - if (ZnFIELD.FieldsToArea(&track->field_set, area) != inside) { - return 0; - } - } - - /* - * Try the leader. - */ - if (track->field_set.label_format && (track->leader_width > 0)) { - ZnPoint end_points[ZN_LINE_END_POINTS]; - ZnPoint *points; - unsigned int num_points; - - points = (ZnPoint *) ZnListArray(track->leader_points); - num_points = ZnListSize(track->leader_points); - lwidth = track->leader_width > 1 ? track->leader_width : 0; - if (ZnPolylineInBBox(points, num_points, lwidth, - CapRound, JoinRound, area) != inside) { - /*printf("track leader\n");*/ - return 0; - } - if (track->leader_first_end != NULL) { - ZnGetLineEnd(&points[0], &points[1], track->leader_width, - CapRound, track->leader_first_end, end_points); - if (ZnPolygonInBBox(end_points, ZN_LINE_END_POINTS, area, NULL) != inside) { - /*printf("track leader\n");*/ - return 0; - } - } - if (track->leader_last_end != NULL) { - ZnGetLineEnd(&points[num_points-1], &points[num_points-2], track->leader_width, - CapRound, track->leader_last_end, end_points); - if (ZnPolygonInBBox(end_points, ZN_LINE_END_POINTS, area, NULL) != inside) { - /*printf("track leader\n");*/ - return 0; - } - } - } - - /* - * Try the speed vector. - */ - if ((item->class == ZnTrack) && (track->speed_vector_width > 0)) { - pts[0] = track->dev; - pts[1] = track->speed_vector_dev; - lwidth = track->speed_vector_width > 1 ? track->speed_vector_width : 0; - if (ZnPolylineInBBox(pts, 2, lwidth, CapRound, JoinRound, area) != inside) { - /*printf("track speed vector\n");*/ - return 0; - } - } - - /* - * Try the connection. - */ - if ((item->connected_item != ZN_NO_ITEM) && (track->connection_width > 0)) { - pts[0] = track->dev; - pts[1] = ((TrackItem) item->connected_item)->dev; - lwidth = track->connection_width > 1 ? track->connection_width : 0; - if (ZnPolylineInBBox(pts, 2, lwidth, CapRound, JoinRound, area) != inside) { - /*printf("track connection\n");*/ - return 0; - } - } - - return inside; -} - - -/* -********************************************************************************** -* -* Draw -- -* -********************************************************************************** -*/ -static void -Draw(ZnItem item) -{ - ZnWInfo *wi = item->wi; - TrackItem track = (TrackItem) item; - ZnItem c_item; - XGCValues values; - History hist; - unsigned int h_side_size, side_size, width=0, height=0; - unsigned int i, nb_hist, num_acc_pos; - int x, y; - - /* Draw the marker */ - if (track->marker_size_dev != 0) { - ZnSetLineStyle(wi, track->marker_style); - values.foreground = ZnGetGradientPixel(track->marker_color, 0.0); - values.line_width = 0; - if (ISSET(track->flags, MARKER_FILLED_BIT)) { - if (track->marker_fill_pattern == ZnUnspecifiedImage) { - /* Fill solid */ - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCFillStyle | GCLineWidth | GCForeground, &values); - } - else { - /* Fill stippled */ - values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(track->marker_fill_pattern, wi->win); - XChangeGC(wi->dpy, wi->gc, - GCFillStyle | GCStipple | GCLineWidth | GCForeground, &values); - } - XFillArc(wi->dpy, wi->draw_buffer, wi->gc, - (int) (track->dev.x - (ZnPos) track->marker_size_dev), - (int) (track->dev.y - (ZnPos) track->marker_size_dev), - (unsigned int) track->marker_size_dev * 2, - (unsigned int) track->marker_size_dev * 2, - 0, 360 * 64); - } - else { - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCFillStyle | GCLineWidth | GCForeground, &values); - XDrawArc(wi->dpy, wi->draw_buffer, wi->gc, - (int) (track->dev.x - (ZnPos) track->marker_size_dev), - (int) (track->dev.y - (ZnPos) track->marker_size_dev), - (unsigned int) (track->marker_size_dev * 2), - (unsigned int) (track->marker_size_dev * 2), - 0, 360 * 64); - } - } - - /* - * Draw the connection. - */ - c_item = item->connected_item; - if ((c_item != ZN_NO_ITEM) && (track->connection_width > 0)) { - ZnPoint pts[2]; - - pts[0] = track->dev; - pts[1] = ((TrackItem) item->connected_item)->dev; - ZnDrawLineShape(wi, pts, 2, track->connection_style, - ZnGetGradientPixel(track->connection_color, 0.0), - track->connection_width, ZN_LINE_STRAIGHT); - } - - /* - * Draw the speed vector. - */ - if ((item->class == ZnTrack) && (track->speed_vector_width > 0)) { - values.foreground = ZnGetGradientPixel(track->speed_vector_color, 0.0); - values.line_width = (int) (track->speed_vector_width > 1 ? track->speed_vector_width : 0); - values.line_style = LineSolid; - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, - GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, &values); - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - (int) track->dev.x, - (int) track->dev.y, - (int) track->speed_vector_dev.x, - (int) track->speed_vector_dev.y); - } - - /* - * Draw the leader. - */ - if (track->field_set.label_format && (track->leader_width > 0)) { - ZnPoint end_points[ZN_LINE_END_POINTS]; - XPoint xpoints[ZN_LINE_END_POINTS]; - ZnPoint *points; - unsigned int num_points; - - points = (ZnPoint *) ZnListArray(track->leader_points); - num_points = ZnListSize(track->leader_points); - ZnDrawLineShape(wi, points, num_points, track->leader_style, - ZnGetGradientPixel(track->leader_color, 0.0), - track->leader_width, track->leader_shape); - if (track->leader_first_end != NULL) { - ZnGetLineEnd(&points[0], &points[1], track->leader_width, - CapRound, track->leader_first_end, end_points); - for (i = 0; i < ZN_LINE_END_POINTS; i++) { - xpoints[i].x = (short) end_points[i].x; - xpoints[i].y = (short) end_points[i].y; - } - XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, xpoints, ZN_LINE_END_POINTS, - Nonconvex, CoordModeOrigin); - } - if (track->leader_last_end != NULL) { - ZnGetLineEnd(&points[num_points-1], &points[num_points-2], track->leader_width, - CapRound, track->leader_last_end, end_points); - for (i = 0; i < ZN_LINE_END_POINTS; i++) { - xpoints[i].x = (short) end_points[i].x; - xpoints[i].y = (short) end_points[i].y; - } - XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, xpoints, ZN_LINE_END_POINTS, - Nonconvex, CoordModeOrigin); - } - } - - if (track->symbol != ZnUnspecifiedImage) { - ZnSizeOfImage(track->symbol, &width, &height); - } - - /* - * Draw the history, current pos excepted. - */ - if ((item->class == ZnTrack) && track->history) { - unsigned int visible_history_size; - - visible_history_size = (ISSET(track->flags, HISTORY_VISIBLE_BIT) ? - wi->track_visible_history_size : 0); - - values.foreground = ZnGetGradientPixel(track->history_color, 0.0); - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCForeground|GCFillStyle, &values); - if (ISCLEAR(track->flags, FILLED_HISTORY_BIT)) { - values.line_width = 0; - values.line_style = LineSolid; - XChangeGC(wi->dpy, wi->gc, GCLineWidth | GCLineStyle, &values); - } - num_acc_pos = MIN(visible_history_size, ZnListSize(track->history)); - hist = ZnListArray(track->history); - side_size = (int) track->history_width; - - for (i = 0, nb_hist = 0; i < num_acc_pos; i++) { - if (ISSET(track->flags, LAST_AS_FIRST_BIT) && - (i == visible_history_size-1)) { - values.foreground = ZnGetGradientPixel(track->symbol_color, 0.0); - XChangeGC(wi->dpy, wi->gc, GCForeground, &values); - } - side_size--; - side_size = MAX(1, side_size); - h_side_size = (side_size+1)/2; - if (hist[i].visible) { - if (ISSET(track->flags, DOT_MIXED_HISTORY_BIT) && !(nb_hist++ % 2)) { - x = (int) hist[i].dev.x; - y = (int) hist[i].dev.y; - /* Draw a point (portability layer doesn't define a XDrawPoint) */ - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, x, y, x, y); - } - else { - x = ((int) hist[i].dev.x) - h_side_size; - y = ((int) hist[i].dev.y) - h_side_size; - if (ISSET(track->flags, CIRCLE_HISTORY_BIT)) { - if (ISSET(track->flags, FILLED_HISTORY_BIT)) { - XFillArc(wi->dpy, wi->draw_buffer, wi->gc, - x, y, side_size, side_size, 0, 360*64); - } - else { - XDrawArc(wi->dpy, wi->draw_buffer, wi->gc, - x, y, side_size - 1, side_size - 1, 0, 360*64); - } - } - else { - if (ISSET(track->flags, FILLED_HISTORY_BIT)) { - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, - x, y, side_size, side_size); - } - else { - XDrawRectangle(wi->dpy, wi->draw_buffer, wi->gc, - x, y, side_size - 1, side_size - 1); - } - } - } - } - } - } - - /* - * Draw the current position using a pattern for Tk. - */ - if (track->symbol != ZnUnspecifiedImage) { - x = ((int) track->dev.x) - (width+1)/2; - y = ((int) track->dev.y) - (height+1)/2; - values.foreground = ZnGetGradientPixel(track->symbol_color, 0.0); - values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(track->symbol, wi->win); - values.ts_x_origin = x; - values.ts_y_origin = y; - XChangeGC(wi->dpy, wi->gc, - GCForeground|GCFillStyle|GCStipple|GCTileStipXOrigin|GCTileStipYOrigin, - &values); - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, x, y, width, height); - } - - /* - * Draw the label. - */ - ZnFIELD.DrawFields(&track->field_set); -} - - -/* -********************************************************************************** -* -* Render -- -* -********************************************************************************** -*/ -#ifdef GL -struct MarkerCBData { - ZnPoint *p; - int num; - ZnReal size; - ZnPoint center; -}; - -static void -MarkerRenderCB(void *closure) -{ - struct MarkerCBData *cbd = (struct MarkerCBData *) closure; - int i; - - glBegin(GL_TRIANGLE_FAN); - glVertex2d(cbd->center.x, cbd->center.y); - for (i = 0; i < cbd->num; i++) { - glVertex2d(cbd->center.x + cbd->p[i].x*cbd->size, - cbd->center.y + cbd->p[i].y*cbd->size); - } - glEnd(); -} - -static void -Render(ZnItem item) -{ - ZnWInfo *wi = item->wi; - TrackItem track = (TrackItem) item; - TrackItem c_item; - History hist; - unsigned int h_side_size, side_size, width=0, height=0; - unsigned int i, j, nb_hist, num_acc_pos; - unsigned short alpha; - XColor *color; - ZnPoint *points; - unsigned int num_points; - ZnReal x0, y0, size; - - /* Draw the marker */ - if (track->marker_size_dev != 0) { - points = ZnGetCirclePoints(3, ZN_CIRCLE_MEDIUM, 0.0, 2*M_PI, &num_points, NULL); - x0 = track->dev.x; - y0 = track->dev.y; - size = track->marker_size_dev; - if (ISSET(track->flags, MARKER_FILLED_BIT)) { - ZnBBox bbox; - struct MarkerCBData cbd; - - cbd.center.x = x0; - cbd.center.y = y0; - cbd.num = num_points; - cbd.size = size; - cbd.p = points; - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (track->marker_fill_pattern != ZnUnspecifiedImage) { /* Fill stippled */ - ZnResetBBox(&bbox); - ZnAddPointToBBox(&bbox, track->dev.x-size, track->dev.y-size); - ZnAddPointToBBox(&bbox, track->dev.x+size, track->dev.y+size); - ZnRenderTile(wi, track->marker_fill_pattern, track->marker_color, - MarkerRenderCB, &cbd, (ZnPoint *) &bbox); - } - else { - color = ZnGetGradientColor(track->marker_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - MarkerRenderCB(&cbd); - } - } - else { - glLineWidth(1.0); - ZnSetLineStyle(wi, track->marker_style); - glBegin(GL_LINE_LOOP); - for (i = 0; i < num_points; i++) { - glVertex2d(x0 + points[i].x*size, y0 + points[i].y*size); - } - glEnd(); - } - } - - /* - * Draw the connection. - */ - c_item = (TrackItem) item->connected_item; - if ((c_item != ZN_NO_ITEM) && (track->connection_width > 0)) { - color = ZnGetGradientColor(track->connection_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glLineWidth((GLfloat)track->connection_width); - glBegin(GL_LINES); - glVertex2d(track->dev.x, track->dev.y); - glVertex2d(c_item->dev.x, c_item->dev.y); - glEnd(); - } - - /* - * Draw the speed vector. - */ - if ((item->class == ZnTrack) && (track->speed_vector_width > 0)) { - unsigned int num_clips=0, svlength=0; - ZnReal svxstep=0, svystep=0; - GLfloat ticksize=0; - - color = ZnGetGradientColor(track->speed_vector_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glLineWidth((GLfloat)track->speed_vector_width); - - /* - * Turn off AA to obtain a square point precisely defined - */ - if (ISSET(track->flags, SV_TICKS_BIT) || - ISSET(track->flags, SV_MARK_BIT)) { - glDisable(GL_POINT_SMOOTH); - - if (ISSET(track->flags, SV_TICKS_BIT)) { - num_clips = ZnListSize(wi->clip_stack); - ticksize = 3; - svlength = (int) wi->speed_vector_length; - svxstep = (track->speed_vector_dev.x-track->dev.x)/svlength; - svystep = (track->speed_vector_dev.y-track->dev.y)/svlength; - glPointSize(ticksize); - ZnGlStartClip(num_clips, False); - glBegin(GL_POINTS); - for (i = 1; i < svlength; i++) { - glVertex2d(track->dev.x + i*svxstep, track->dev.y + i*svystep); - } - glEnd(); - ZnGlRenderClipped(); - } - } - - glBegin(GL_LINES); - glVertex2d(track->dev.x, track->dev.y); - glVertex2d(track->speed_vector_dev.x, track->speed_vector_dev.y); - glEnd(); - - if (ISSET(track->flags, SV_MARK_BIT)) { - glPointSize((GLfloat) (track->speed_vector_width + 2.0)); - glBegin(GL_POINTS); - glVertex2d(track->speed_vector_dev.x, track->speed_vector_dev.y); - glEnd(); - } - - if (ISSET(track->flags, SV_TICKS_BIT) || - ISSET(track->flags, SV_MARK_BIT)) { - glEnable(GL_POINT_SMOOTH); - - if (ISSET(track->flags, SV_TICKS_BIT)) { - glPointSize(ticksize); - ZnGlRestoreStencil(num_clips, False); - glBegin(GL_POINTS); - for (i = 1; i < svlength; i++) { - glVertex2d(track->dev.x + i*svxstep, track->dev.y + i*svystep); - } - glEnd(); - ZnGlEndClip(num_clips); - } - } - } - - /* - * Draw the leader. - */ - if (track->field_set.label_format && (track->leader_width > 0)) { - points = ZnListArray(track->leader_points); - num_points = ZnListSize(track->leader_points); - ZnRenderPolyline(wi, - points, num_points, track->leader_width, - track->leader_style, CapRound, JoinRound, - track->leader_first_end, track->leader_last_end, - track->leader_color); - } - - if (track->symbol != ZnUnspecifiedImage) { - ZnSizeOfImage(track->symbol, &width, &height); - } - - /* - * Draw the history, current pos excepted. - */ - if ((item->class == ZnTrack) && track->history) { - unsigned int visible_history_size; - - visible_history_size = (ISSET(track->flags, HISTORY_VISIBLE_BIT) ? - wi->track_visible_history_size : 0); - - points = ZnGetCirclePoints(3, ZN_CIRCLE_COARSE, 0.0, 2*M_PI, &num_points, NULL); - color = ZnGetGradientColor(track->history_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glLineWidth(1.0); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - num_acc_pos = MIN(visible_history_size, ZnListSize(track->history)); - hist = ZnListArray(track->history); - side_size = (int) track->history_width; - /* - * Turning off line and point smoothing - * to enhance ;-) history drawing. - */ - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POINT_SMOOTH); - for (i = 0, nb_hist = 0; i < num_acc_pos; i++) { - if (ISSET(track->flags, LAST_AS_FIRST_BIT) && - (i == visible_history_size-1)) { - color = ZnGetGradientColor(track->symbol_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - } - side_size--; - side_size = MAX(1, side_size); - h_side_size = (side_size+1)/2; - if (hist[i].visible) { - x0 = hist[i].dev.x; - y0 = hist[i].dev.y; - if ((ISSET(track->flags, DOT_MIXED_HISTORY_BIT) && !(nb_hist++ % 2)) || - (side_size == 1)) { - glPointSize(1.0); - glBegin(GL_POINTS); - glVertex2d(x0, y0); - glEnd(); - } - else { - if (ISSET(track->flags, CIRCLE_HISTORY_BIT)) { - if (ISSET(track->flags, FILLED_HISTORY_BIT)) { - glPointSize((GLfloat) side_size); - glBegin(GL_POINTS); - glVertex2d(x0, y0); - glEnd(); - } - else { -#if 1 - glBegin(GL_LINE_LOOP); - for (j = 0; j < num_points; j++) { - glVertex2d(x0 + points[j].x*h_side_size, - y0 + points[j].y*h_side_size); - } - glEnd(); -#else - RenderHollowDot(wi, &hist[i].dev, side_size+1); -#endif - } - } - else { - if (ISSET(track->flags, FILLED_HISTORY_BIT)) { - glBegin(GL_QUADS); - glVertex2d(x0 - h_side_size, y0 - h_side_size); - glVertex2d(x0 - h_side_size, y0 + h_side_size); - glVertex2d(x0 + h_side_size, y0 + h_side_size); - glVertex2d(x0 + h_side_size, y0 - h_side_size); - glEnd(); - } - else { - glBegin(GL_LINE_LOOP); - glVertex2d(x0 - h_side_size, y0 - h_side_size); - glVertex2d(x0 - h_side_size, y0 + h_side_size); - glVertex2d(x0 + h_side_size, y0 + h_side_size); - glVertex2d(x0 + h_side_size, y0 - h_side_size); - glEnd(); - } - } - } - } - } - glEnable(GL_LINE_SMOOTH); - glEnable(GL_POINT_SMOOTH); - } - - /* - * Draw the current position using a pattern. - */ - if (track->symbol != ZnUnspecifiedImage) { - ZnPoint p; - - p.x = track->dev.x - (width+1)/2; - p.y = track->dev.y - (height+1)/2; - ZnRenderIcon(wi, track->symbol, track->symbol_color, &p, True); - } - - /* - * Render the label. - */ - ZnFIELD.RenderFields(&track->field_set); -} -#else -static void -Render(ZnItem item) -{ -} -#endif - - -/* -********************************************************************************** -* -* IsSensitive -- -* -********************************************************************************** -*/ -static ZnBool -IsSensitive(ZnItem item, - int item_part) -{ - if (ISCLEAR(item->flags, ZN_SENSITIVE_BIT) || - !item->parent->class->IsSensitive(item->parent, ZN_NO_PART)) { - return False; - } - - if (item_part < ZN_NO_PART) { - return ISSET(item->part_sensitive, ZnPartToBit(item_part)); - } - else if (item_part >= 0) { - return ZnFIELD.IsFieldSensitive(&((TrackItem) item)->field_set, item_part); - } - else if (item_part == ZN_NO_PART) { - return ISSET(item->flags, ZN_SENSITIVE_BIT); - } - return True; -} - - -/* -********************************************************************************** -* -* Pick -- -* -********************************************************************************** -*/ -static double -Pick(ZnItem item, - ZnPick ps) -{ - TrackItem track = (TrackItem) item; - ZnItem c_item; - ZnBBox bbox; - double dist=0, new_dist; - ZnPoint *points, *p = ps->point; - int num_points, i; - int width=0, height=0; - double width_2; - int best_part; - ZnPoint pts[2]; - - /* - * Try one of the fields. - */ - dist = ZnFIELD.FieldsPick(&track->field_set, p, &best_part); - if (dist <= 0.0) { - goto report0; - } - - /* - * Try the current position symbol. - */ - ZnResetBBox(&bbox); - if (track->symbol != ZnUnspecifiedImage) { - ZnSizeOfImage(track->symbol, &width, &height); - bbox.orig.x = track->dev.x-(width+1)/2; - bbox.orig.y = track->dev.y-(height+1)/2; - bbox.corner.x = bbox.orig.x + width; - bbox.corner.y = bbox.orig.y + height; - } - - new_dist = ZnRectangleToPointDist(&bbox, p); - if (new_dist < dist) { - best_part = CURRENT_POSITION; - dist = new_dist; - } - if (dist <= 0.0) { - goto report0; - } - - /* - * Try the leader. - */ - if (track->field_set.label_format && (track->leader_width > 0) && - track->leader_points) { - ZnPoint end_points[ZN_LINE_END_POINTS]; - - width_2 = (track->leader_width>1) ? ((double) track->leader_width)/2.0 : 0; - points = (ZnPoint *) ZnListArray(track->leader_points); - num_points = ZnListSize(track->leader_points)-1; - for (i = 0; i < num_points; i++) { - new_dist = ZnLineToPointDist(&points[i], &points[i+1], p, NULL); - new_dist -= width_2; - if (new_dist < dist) { - best_part = LEADER; - dist = new_dist; - } - if (dist <= 0.0) { - goto report0; - } - } - if (track->leader_first_end != NULL) { - ZnGetLineEnd(&points[0], &points[1], track->leader_width, - CapRound, track->leader_first_end, end_points); - new_dist = ZnPolygonToPointDist(end_points, ZN_LINE_END_POINTS, p); - if (new_dist < dist) { - best_part = LEADER; - dist = new_dist; - } - if (dist <= 0.0) { - goto report0; - } - } - if (track->leader_last_end != NULL) { - ZnGetLineEnd(&points[num_points-1], &points[num_points-2], track->leader_width, - CapRound, track->leader_last_end, end_points); - new_dist = ZnPolygonToPointDist(end_points, ZN_LINE_END_POINTS, p); - if (new_dist < dist) { - best_part = LEADER; - dist = new_dist; - } - if (dist <= 0.0) { - goto report0; - } - } - } - - /* - * Try the speed vector. - */ - if ((item->class == ZnTrack) && (track->speed_vector_width > 0)) { - pts[0] = track->dev; - pts[1] = track->speed_vector_dev; - new_dist = ZnPolylineToPointDist(pts, 2, track->speed_vector_width, - CapRound, JoinRound, p); - if (new_dist < dist) { - best_part = SPEED_VECTOR; - dist = new_dist; - } - if (dist <= 0.0) { - goto report0; - } - } - - /* - * Try the connection. - */ - c_item = item->connected_item; - if ((c_item != ZN_NO_ITEM) && (track->connection_width > 0)) { - pts[0] = track->dev; - pts[1] = ((TrackItem) item->connected_item)->dev; - new_dist = ZnPolylineToPointDist(pts, 2, track->connection_width, - CapRound, JoinRound, p); - if (new_dist < dist) { - dist = new_dist; - best_part = CONNECTION; - } - if (dist <= 0.0) { - report0: - dist = 0.0; - } - } - - /* printf("track %d reporting part %d, distance %lf\n", - item->id, best_part, dist); */ - ps->a_part = best_part; - return dist; -} - - -/* -********************************************************************************** -* -* PostScript -- -* -********************************************************************************** -*/ -static int -PostScript(ZnItem item, - ZnBool prepass, - ZnBBox *area) -{ - return TCL_OK; -} - - -#ifdef ATC -/* -********************************************************************************** -* -* ZnSendTrackToOm -- -* -********************************************************************************** -*/ -/* - * TODO: - * - * The tracks should be identified by their ids not their - * structure pointer. This would enable an easy interface - * between the overlap manager and the applications when - * dealing with tracks. - */ -void * -ZnSendTrackToOm(void *ptr, - void *item, - int *x, - int *y, - int *sv_dx, - int *sv_dy, - /*int *label_x, - int *label_y, - int *label_width, - int *label_height,*/ - int *rho, - int *theta, - int *visibility, - int *locked, - int *preferred_angle, - int *convergence_style) -{ - ZnWInfo *wi = (ZnWInfo *) ptr; - ZnItem current_item = (ZnItem) item; - TrackItem track; - ZnBBox zn_bbox, bbox; - ZnBool to_be_sent; - - int rho_derived ; - - zn_bbox.orig.x = zn_bbox.orig.y = 0; - zn_bbox.corner.x = wi->width; - zn_bbox.corner.y = wi->height; - - if (current_item == ZN_NO_ITEM) { - current_item = ZnGroupHead(wi->om_group); - } - else { - current_item = current_item->next; - } - - while (current_item != ZN_NO_ITEM) { - to_be_sent = current_item->class == ZnTrack; - - /* We send invisibles items because the current algorithm - take care of the age of the tracks. - to_be_sent &= ISSET(current_item->flags, ZN_VISIBLE_BIT);*/ - - ZnIntersectBBox(&zn_bbox, ¤t_item->item_bounding_box, &bbox); - to_be_sent &= !ZnIsEmptyBBox(&bbox); - - if (to_be_sent) { - track = (TrackItem) current_item; - - *x = (int) track->dev.x; - *y = wi->height - ((int) track->dev.y); - - /* - * We must send world values for speed vector deltas as device - * equivalents can be null. But then if the image is rotated this - * is nonsense. - */ - *sv_dx = (int) track->speed_vector.x; - *sv_dy = (int) track->speed_vector.y; - - /* Fri Oct 13 15:16:38 2000 - *label_x = track->field_set.label_pos.x; - *label_y = wi->height - track->field_set.label_pos.y; - if (track->field_set.label_format) { - ZnDim bb_width, bb_height; - - ZnFIELD.GetLabelBBox(&track->field_set, &bb_width, &bb_height); - *label_width = bb_width; - *label_height = bb_height; - } - else { - *label_width = 0; - *label_height = 0; - } - */ - - /* - * Trial to fix rho drift due to ZnPointPolarToCartesian - * roundoff error. - */ - rho_derived = (int) sqrt(track->label_dx*track->label_dx + - track->label_dy*track->label_dy); -#ifdef DP - if (ABS(rho_derived - track->label_distance) < LABEL_DISTANCE_THRESHOLD) { - /* The error is narrow so value discarded */ - *rho = track->label_distance ; - } - else { - /* Means a user change has been performed on label_dx label_dy */ - *rho = rho_derived ; - } -#else - *rho = rho_derived; -#endif - *theta = track->label_angle; - *visibility = (ISSET(current_item->flags, ZN_VISIBLE_BIT) ? 1 : 0 ); - *locked = (ISSET(track->flags, FROZEN_LABEL_BIT) ? 1 : 0); - *preferred_angle = track->label_preferred_angle; - *convergence_style = track->label_convergence_style; - break; - } - - current_item = current_item->next; - } - - return (void *) current_item; -} - - -/* -********************************************************************************** -* -* ZnSetLabelAngleFromOm -- -* -********************************************************************************** -*/ -void -ZnSetLabelAngleFromOm(void *ptr, /* No longer in use. */ - void *item, - int rho, - int theta) -{ - TrackItem track = (TrackItem) item; - - theta %= 360; - if (theta < 0) { - theta += 360; - } - if (ISCLEAR(track->flags, FROZEN_LABEL_BIT) && (track->label_angle != theta)) { - track->label_angle = theta; -#ifdef DP - track->label_distance = rho; -#endif - SET(track->flags, POLAR_BIT); - ZnITEM.Invalidate((ZnItem) item, ZN_COORDS_FLAG); - /* ZnGroupSetCallOm(((ZnItem)item)->parent, True);*/ - } -} - - -/* -********************************************************************************** -* -* ZnQueryLabelPosition -- OverlapMan query the widget about what would be the -* label position if label_angle is theta -* -********************************************************************************** -*/ -void -ZnQueryLabelPosition(void *ptr, /* No longer in use. */ - void *item, - int theta, - int *x, - int *y, - int *w, - int *h) -{ - ZnItem it = (ZnItem) item; - ZnWInfo *wi = it->wi; - TrackItem track = (TrackItem) it; - - if (track->field_set.label_format) { - ZnDim bb_width, bb_height; - ZnDim delta_x, delta_y; - ZnReal heading; - - /* - * !! BUG !! This doesn't work if the current transform has some rotation. - */ - heading = ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y); - ZnPointPolarToCartesian(heading, track->label_distance, (ZnReal) theta, &delta_x, &delta_y); - ZnFIELD.GetLabelBBox(&track->field_set, &bb_width, &bb_height); - /* - * !! BUG !! This assume a label placing relative to the center anchor. - * We must fix this by taking into account the label anchor. - */ - *x = (int) track->dev.x + (int) (delta_x - bb_width/2); - *y = (int) track->dev.y - (int) (delta_y + bb_height/2); - *y = ((int) wi->height) - *y; - *w = (int) bb_width; - *h = (int) bb_height; - } - else { - *x = *y = *w = *h = 0; - } -} -#endif - - -/* -********************************************************************************** -* -* ZnSetHistoryVisibility -- PLC - not yet implemented -* -********************************************************************************** -*/ -void -ZnSetHistoryVisibility(ZnItem item, - int index, - ZnBool visible) -{ -} - - -/* -********************************************************************************** -* -* ZnTruncHistory -- PLC - not yet interfaced -* -********************************************************************************** -*/ -void -ZnTruncHistory(ZnItem item) -{ - TrackItem track = (TrackItem) item; - - if (track->history) { - int size = ZnListSize (track->history); - History hist_tbl = ZnListArray (track->history); - while (size--) { - hist_tbl[size].visible = False; - } - ZnITEM.Invalidate(item, ZN_COORDS_FLAG); - } -} - - -/* -********************************************************************************** -* -* GetFieldSet -- -* -********************************************************************************** -*/ -static ZnFieldSet -GetFieldSet(ZnItem item) -{ - return &((TrackItem) item)->field_set; -} - - -/* -********************************************************************************** -* -* GetAnchor -- -* -********************************************************************************** -*/ -static void -GetAnchor(ZnItem item, - Tk_Anchor anchor, - ZnPoint *p) -{ - ZnFieldSet field_set = &((TrackItem) item)->field_set; - ZnDim width, height; - - if (field_set->label_format) { - ZnFIELD.GetLabelBBox(field_set, &width, &height); - ZnOrigin2Anchor(&field_set->label_pos, width, height, anchor, p); - } - else { - p->x = p->y = 0.0; - } -} - - -/* -********************************************************************************** -* -* Coords -- -* Return or edit the item position. -* -********************************************************************************** -*/ -static int -Coords(ZnItem item, - int contour, - int index, - int cmd, - ZnPoint **pts, - char **controls, - unsigned int *num_pts) -{ - TrackItem track = (TrackItem) item; - - if ((cmd == ZN_COORDS_ADD) || (cmd == ZN_COORDS_ADD_LAST) || (cmd == ZN_COORDS_REMOVE)) { - Tcl_AppendResult(item->wi->interp, " ", - item->class->name, "s can't add or remove vertices", NULL); - return TCL_ERROR; - } - else if ((cmd == ZN_COORDS_REPLACE) || (cmd == ZN_COORDS_REPLACE_ALL)) { - if (*num_pts == 0) { - Tcl_AppendResult(item->wi->interp, - " coords command need 1 point on ", - item->class->name, "s", NULL); - return TCL_ERROR; - } - if (item->class == ZnTrack) { - AddToHistory(track, track->pos); - } - track->pos = (*pts)[0]; - ZnITEM.Invalidate(item, ZN_COORDS_FLAG); - } - else if ((cmd == ZN_COORDS_READ) || (cmd == ZN_COORDS_READ_ALL)) { - *num_pts = 1; - *pts = &track->pos; - } - return TCL_OK; -} - - -/* -********************************************************************************** -* -* Part -- -* Convert a private part from/to symbolic representation. -* -********************************************************************************** -*/ -static int -Part(ZnItem item, - Tcl_Obj **part_spec, - int *part) -{ - char *part_str=""; - int c; - char *end; - - if (*part_spec) { - part_str = Tcl_GetString(*part_spec); - if (strlen(part_str) == 0) { - *part = ZN_NO_PART; - } - else if (isdigit(part_str[0])) { - *part = strtol(part_str, &end, 0); - if ((*end != 0) || (*part < 0) || - ((unsigned int) *part >= ((TrackItem) item)->field_set.num_fields)) { - goto part_error; - } - } - else { - c = part_str[0]; - if ((c == 'c') && (strcmp(part_str, "connection") == 0)) { - *part = CONNECTION; - } - else if ((c == 'l') && (strcmp(part_str, "leader") == 0)) { - *part = LEADER; - } - else if ((c == 'p') && (strcmp(part_str, "position") == 0)) { - *part = CURRENT_POSITION; - } - else if ((c == 's') && (strcmp(part_str, "speedvector") == 0)) { - if (item->class != ZnTrack) { - goto part_error; - } - *part = SPEED_VECTOR; - } - else { - part_error: - Tcl_AppendResult(item->wi->interp, " invalid item part specification", NULL); - return TCL_ERROR; - } - } - } - else { - if (*part >= 0) { - *part_spec = Tcl_NewIntObj(*part); - } - else { - part_str = ""; - switch (*part) { - default: - case ZN_NO_PART: - break; - case CURRENT_POSITION: - part_str = "position"; - break; - case LEADER: - part_str = "leader"; - break; - case CONNECTION: - part_str = "connection"; - break; - case SPEED_VECTOR: - if (item->class == ZnTrack) { - part_str = "speedvector"; - break; - } - } - if (part_str[0]) { - *part_spec = Tcl_NewStringObj(part_str, -1); - } - } - } - return TCL_OK; -} - - -/* -********************************************************************************** -* -* Index -- -* Parse a text index and return its value and aa -* error status (standard Tcl result). -* -********************************************************************************** -*/ -static int -Index(ZnItem item, - int field, - Tcl_Obj *index_spec, - int *index) -{ - return ZnFIELD.FieldIndex(&((TrackItem) item)->field_set, field, - index_spec, index); -} - - -/* -********************************************************************************** -* -* InsertChars -- -* -********************************************************************************** -*/ -static void -InsertChars(ZnItem item, - int field, - int *index, - char *chars) -{ - if (ZnFIELD.FieldInsertChars(&((TrackItem) item)->field_set, - field, index, chars)) { - ZnITEM.Invalidate(item, ZN_COORDS_FLAG); - } -} - - -/* -********************************************************************************** -* -* DeleteChars -- -* -********************************************************************************** -*/ -static void -DeleteChars(ZnItem item, - int field, - int *first, - int *last) -{ - if (ZnFIELD.FieldDeleteChars(&((TrackItem) item)->field_set, - field, first, last)) { - ZnITEM.Invalidate(item, ZN_COORDS_FLAG); - } -} - - -/* -********************************************************************************** -* -* Cursor -- -* -********************************************************************************** -*/ -static void -TrackCursor(ZnItem item, - int field, - int index) -{ - ZnFIELD.FieldCursor(&((TrackItem) item)->field_set, field, index); -} - - -/* -********************************************************************************** -* -* Selection -- -* -********************************************************************************** -*/ -static int -Selection(ZnItem item, - int field, - int offset, - char *chars, - int max_chars) -{ - return ZnFIELD.FieldSelection(&((TrackItem) item)->field_set, field, - offset, chars, max_chars); -} - - -/* -********************************************************************************** -* -* Exported functions struct -- -* -********************************************************************************** -*/ -/* - * Track -position attribute is not handled the same way as other - * interface items like texts, icons and such, as it make little sense - * to change the local transform of a track. It is always processed as - * a point in the coordinate system of the track's parent. It is the same - * for the points in the history and the speed vector end. - */ -static ZnItemClassStruct TRACK_ITEM_CLASS = { - "track", - sizeof(TrackItemStruct), - track_attrs, - 4, /* num_parts */ - ZN_CLASS_HAS_ANCHORS|ZN_CLASS_ONE_COORD, /* flags */ - -1, - Init, - Clone, - Destroy, - Configure, - Query, - GetFieldSet, - GetAnchor, - NULL, /* GetClipVertices */ - NULL, /* GetContours */ - Coords, - InsertChars, - DeleteChars, - TrackCursor, - Index, - Part, - Selection, - NULL, /* Contour */ - ComputeCoordinates, - ToArea, - Draw, - Render, - IsSensitive, - Pick, - NULL, /* PickVertex */ - PostScript -}; - -static ZnItemClassStruct WAY_POINT_ITEM_CLASS = { - "waypoint", - sizeof(TrackItemStruct), - wp_attrs, - 3, /* num_parts */ - ZN_CLASS_HAS_ANCHORS|ZN_CLASS_ONE_COORD, /* flags */ - -1, - Init, - Clone, - Destroy, - Configure, - Query, - GetFieldSet, - GetAnchor, - NULL, /* GetClipVertices */ - NULL, /* GetContours */ - Coords, - InsertChars, - DeleteChars, - TrackCursor, - Index, - Part, - Selection, - NULL, /* Contour */ - ComputeCoordinates, - ToArea, - Draw, - Render, - IsSensitive, - Pick, - NULL, /* PickVertex */ - PostScript -}; - -ZnItemClassId ZnTrack = (ZnItemClassId) &TRACK_ITEM_CLASS; -ZnItemClassId ZnWayPoint = (ZnItemClassId) &WAY_POINT_ITEM_CLASS; |