diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Reticle.c | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/generic/Reticle.c b/generic/Reticle.c new file mode 100644 index 0000000..d59088c --- /dev/null +++ b/generic/Reticle.c @@ -0,0 +1,494 @@ +/* + * Reticle.c -- Implementation of Reticle item. + * + * Authors : Patrick Lecoanet. + * Creation date : Mon Feb 1 12:13:24 1999 + * + * $Id$ + */ + +/* + * Copyright (c) 1993 - 1999 CENA, Patrick Lecoanet -- + * + * This code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This code 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this code; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include "Types.h" +#include "WidgetInfo.h" +#include "Item.h" +#include "Geo.h" +#include "Draw.h" + + +#define /* void */ SQUARE(/* int */ x) ((x) * (x)) + + +static const char rcsid[] = "$Id$"; +static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; + + +/* + ********************************************************************************** + * + * Specific Reticle item record + * + ********************************************************************************** + */ + +typedef struct _ReticleItemStruct { + ItemStruct header; + + /* Public data */ + RadarPoint pos; /* Origin world coordinates */ + RadarColor line_color; /* circle color */ + RadarColor bright_line_color; /* intermediate circle color */ + int first_radius; /* first world radius */ + int step_size; /* step world size */ + int period; /* bright circle period */ + int num_circles; /* num cercles max */ + LineStyle line_style; /* circles lines styles */ + LineStyle bright_line_style; + + /* Private data */ + RadarPoint dev; /* item device coordinate */ + RadarDim first_radius_dev; /* first device radius */ + RadarDim step_size_dev; /* steps device size */ +} ReticleItemStruct, *ReticleItem; + + +static RadarAttrConfig reticle_attrs[] = { + { RADAR_CONFIG_COLOR, "-brightlinecolor", NULL, + Tk_Offset(ReticleItemStruct, bright_line_color), 0, RADAR_DRAW_FLAG, False }, + { RADAR_CONFIG_LINE_STYLE, "-brightlinestyle", NULL, + Tk_Offset(ReticleItemStruct, bright_line_style), 0, RADAR_DRAW_FLAG, False }, + { RADAR_CONFIG_BOOL, "-composerotation", NULL, + Tk_Offset(ReticleItemStruct, header.flags), COMPOSE_ROTATION_BIT, + RADAR_COORDS_FLAG, False }, + { RADAR_CONFIG_BOOL, "-composescale", NULL, + Tk_Offset(ReticleItemStruct, header.flags), COMPOSE_SCALE_BIT, + RADAR_COORDS_FLAG, False }, + { RADAR_CONFIG_DIM, "-stepsize", NULL, + Tk_Offset(ReticleItemStruct, step_size), 0, + RADAR_COORDS_FLAG, False }, + { RADAR_CONFIG_DIM, "-firstradius", NULL, + Tk_Offset(ReticleItemStruct, first_radius), 0, + RADAR_COORDS_FLAG, False }, + { RADAR_CONFIG_COLOR, "-linecolor", NULL, + Tk_Offset(ReticleItemStruct, line_color), 0, RADAR_DRAW_FLAG, False }, + { RADAR_CONFIG_LINE_STYLE, "-linestyle", NULL, + Tk_Offset(ReticleItemStruct, line_style), 0, RADAR_DRAW_FLAG, False }, + { RADAR_CONFIG_UINT, "-numcircles", NULL, + Tk_Offset(ReticleItemStruct, num_circles), 0, + RADAR_COORDS_FLAG, False }, + { RADAR_CONFIG_UINT, "-period", NULL, + Tk_Offset(ReticleItemStruct, period), 0, RADAR_DRAW_FLAG, False }, + { RADAR_CONFIG_POINT, "-position", NULL, + Tk_Offset(ReticleItemStruct, pos), 0, + RADAR_COORDS_FLAG, False}, + { RADAR_CONFIG_PRI, "-priority", NULL, + Tk_Offset(ReticleItemStruct, header.priority), 0, + RADAR_DRAW_FLAG|RADAR_REPICK_FLAG, False }, + { RADAR_CONFIG_BOOL, "-sensitive", NULL, + Tk_Offset(ReticleItemStruct, header.flags), SENSITIVE_BIT, + RADAR_REPICK_FLAG, False }, + { RADAR_CONFIG_TAGS, "-tags", NULL, + Tk_Offset(ReticleItemStruct, header.tags), 0, 0, False }, + { RADAR_CONFIG_BOOL, "-visible", NULL, + Tk_Offset(ReticleItemStruct, header.flags), VISIBLE_BIT, + RADAR_DRAW_FLAG|RADAR_REPICK_FLAG|RADAR_VIS_FLAG, False }, + + { RADAR_CONFIG_END, NULL, NULL, 0, 0, 0 } +}; + + +/* + ********************************************************************************** + * + * Init -- + * + ********************************************************************************** + */ +static int +Init(Item item, + int *argc, + Arg **args) +{ + ReticleItem reticle = (ReticleItem) item; + WidgetInfo *wi = item->wi; + + SET(item->flags, VISIBLE_BIT); + CLEAR(item->flags, SENSITIVE_BIT); + SET(item->flags, COMPOSE_ROTATION_BIT); + SET(item->flags, COMPOSE_SCALE_BIT); + item->priority = DEFAULT_RETICLE_PRIORITY; + item->part_sensitive = 0; + reticle->line_color = RadarGetColorByValue(wi->win, wi->fore_color); + reticle->bright_line_color = RadarGetColorByValue(wi->win, wi->fore_color); + reticle->first_radius = DEFAULT_RETICLE_STEP_SIZE; + reticle->step_size = DEFAULT_RETICLE_STEP_SIZE; + reticle->period = DEFAULT_RETICLE_PERIOD; + reticle->num_circles = RADAR_ANY_CIRCLES; + reticle->line_style = LINE_SIMPLE; + reticle->bright_line_style = LINE_SIMPLE; + reticle->pos.x = 0; + reticle->pos.y = 0; + reticle->dev.x = 0; + reticle->dev.y = 0; + reticle->first_radius_dev = 0; + reticle->step_size_dev = 0; + + return RADAR_OK; +} + + +/* + ********************************************************************************** + * + * Clone -- + * + ********************************************************************************** + */ +static void +Clone(Item item) +{ + WidgetInfo *wi = item->wi; + ReticleItem reticle = (ReticleItem) item; + + reticle->line_color = RadarGetColorByValue(wi->win, reticle->line_color); + reticle->bright_line_color = RadarGetColorByValue(wi->win, + reticle->bright_line_color); +} + + +/* + ********************************************************************************** + * + * Destroy -- + * + ********************************************************************************** + */ +static void +Destroy(Item item) +{ + ReticleItem reticle = (ReticleItem) item; + + RadarFreeColor(reticle->line_color); + RadarFreeColor(reticle->bright_line_color); +} + + +/* + ********************************************************************************** + * + * Configure -- + * + ********************************************************************************** + */ +static int +Configure(Item item, + int argc, + RadarAttrList argv, + int *flags) +{ + if (ITEM_P.ConfigureAttributes((char *)item, -1, argc, argv, flags) == RADAR_ERROR) { + return RADAR_ERROR; + } + + return RADAR_OK; +} + + +/* + ********************************************************************************** + * + * Query -- + * + ********************************************************************************** + */ +static int +Query(Item item, + int argc, + RadarAttrList argv) +{ + if (ITEM_P.QueryAttribute((char *) item, -1, argv[0]) == RADAR_ERROR) { + return RADAR_ERROR; + } + + return RADAR_OK; +} + + +/* + ********************************************************************************** + * + * ComputeCoordinates -- + * + ********************************************************************************** + */ +static void +ComputeCoordinates(Item item, + RadarBool force) +{ + WidgetInfo *wi = item->wi; + ReticleItem reticle = (ReticleItem) item; + RadarDim half_width; + RadarPoint p, xp; + + /* Compute center device coordinates */ + RadarTransformPoint(wi->current_transfo, &reticle->pos, &reticle->dev); + p.x = reticle->pos.x + reticle->step_size; + p.y = 0; + RadarTransformPoint(wi->current_transfo, &p, &xp); + reticle->step_size_dev = xp.x - reticle->dev.x; + p.x = reticle->pos.x + reticle->first_radius; + RadarTransformPoint(wi->current_transfo, &p, &xp); + reticle->first_radius_dev = xp.x - reticle->dev.x; + + /* Reticle bounding box is radar bounding box or depends on num_circles */ + if (reticle->num_circles == RADAR_ANY_CIRCLES) { + item->item_bounding_box.orig.x = 0; + item->item_bounding_box.orig.y = 0; + item->item_bounding_box.corner.x = wi->width; + item->item_bounding_box.corner.y = wi->height; + } + else { + half_width = reticle->first_radius_dev + + (reticle->num_circles - 1) * reticle->step_size_dev; + item->item_bounding_box.orig.x = reticle->dev.x - half_width; + item->item_bounding_box.orig.y = reticle->dev.y - half_width; + item->item_bounding_box.corner.x = item->item_bounding_box.orig.y + (2 * half_width); + item->item_bounding_box.corner.y = item->item_bounding_box.orig.y + (2 * half_width); + } +} + + +/* + ********************************************************************************** + * + * ToArea -- + * Tell if the object is entirely outside (-1), + * entirely inside (1) or in between (0). + * + ********************************************************************************** + */ +static int +ToArea(Item item, + RadarBBox *area, + Tk_Uid tag_uid, + int enclosed, + RadarBool report) +{ + return -1; +} + + +/* + ********************************************************************************** + * + * Draw -- + * + ********************************************************************************** + */ +static void +Draw(Item item) +{ + WidgetInfo *wi = item->wi; + ReticleItem reticle = (ReticleItem) item; + RadarDim radius = reticle->first_radius_dev; + RadarDim radius_max_dev; + XGCValues values; + unsigned int i; + RadarDim l1, l2, l3, l4; +/* int count = 0;*/ + + /* Compute radius max */ + l1 = (RadarDim) hypot(wi->damaged_area.orig.x - reticle->dev.x, + wi->damaged_area.orig.y - reticle->dev.y); + l2 = (RadarDim) hypot(wi->damaged_area.corner.x - reticle->dev.x, + wi->damaged_area.orig.y - reticle->dev.y); + l3 = (RadarDim) hypot(wi->damaged_area.orig.x - reticle->dev.x, + wi->damaged_area.corner.y - reticle->dev.y); + l4 = (RadarDim) hypot(wi->damaged_area.corner.x - reticle->dev.x, + wi->damaged_area.corner.y - reticle->dev.y); + radius_max_dev = MAX(MAX(l1,l2), MAX(l3, l4)); + + if (reticle->num_circles > 0) { + radius_max_dev = MIN(radius_max_dev, reticle->first_radius_dev + + (reticle->num_circles - 1) * reticle->step_size_dev); + } + + while (radius <= radius_max_dev) { + SetLineStyle(wi->dpy, wi->gc, reticle->line_style); + values.foreground = RadarPixel(reticle->line_color); + values.line_width = 0; + values.fill_style = FillSolid; + XChangeGC(wi->dpy, wi->gc, GCForeground | GCLineWidth | GCFillStyle, &values); + for (i = 1; (radius <= radius_max_dev && i < reticle->period); i++) { + if ((reticle->dev.x >= wi->damaged_area.orig.x - radius) && + (reticle->dev.x <= wi->damaged_area.corner.x + radius) && + (reticle->dev.y >= wi->damaged_area.orig.y - radius) && + (reticle->dev.y <= wi->damaged_area.corner.y + radius)) { + XDrawArc(wi->dpy, wi->draw_buffer, wi->gc, + reticle->dev.x - (RadarPos) radius, reticle->dev.y - (RadarPos) radius, + (RadarPos) radius * 2 - 1, (RadarPos) radius * 2 - 1, + 0, 360 * 64); +/* count++;*/ + } + radius += (reticle->step_size_dev); + } + if ((radius <= radius_max_dev) && + (reticle->dev.x >= wi->damaged_area.orig.x - radius) && + (reticle->dev.x <= wi->damaged_area.corner.x + radius) && + (reticle->dev.y >= wi->damaged_area.orig.y - radius) && + (reticle->dev.y <= wi->damaged_area.corner.y + radius)) { + SetLineStyle(wi->dpy, wi->gc, reticle->bright_line_style); + values.foreground = RadarPixel(reticle->bright_line_color); + values.line_width = 0; + values.fill_style = FillSolid; + XChangeGC(wi->dpy, wi->gc, GCForeground | GCLineWidth | GCFillStyle, &values); + XDrawArc(wi->dpy, wi->draw_buffer, wi->gc, + reticle->dev.x - (RadarPos) radius, reticle->dev.y - (RadarPos) radius, + (RadarPos) radius * 2 - 1, (RadarPos) radius * 2 - 1, 0, 360 * 64); + /*count++;*/ + } + radius += (reticle->step_size_dev); + } +/*printf("# circles drawn: %d\n", count);*/ +} + + +/* + ********************************************************************************** + * + * IsSensitive -- + * + ********************************************************************************** + */ +static RadarBool +IsSensitive(Item item, + int item_part) +{ + return (ISSET(item->flags, SENSITIVE_BIT) && + item->parent->class->IsSensitive(item->parent, RADAR_NO_PART)); +} + + +/* + ********************************************************************************** + * + * Pick -- + * Nothing to pick, we are almost transparent. + * + ********************************************************************************** + */ +static double +Pick(Item item, + RadarPoint *p, + Item start_item, + int aperture, + Item *a_item, + int *part) +{ + return 1e40; +} + + +/* + ********************************************************************************** + * + * Coords -- + * Return or edit the item center. + * + ********************************************************************************** + */ +static int +Coords(Item item, + int index, + int cmd, + RadarPoint **pts, + int *num_pts) +{ + ReticleItem reticle = (ReticleItem) item; + + if ((cmd == COORDS_ADD) || (cmd == COORDS_ADD_LAST) || (cmd == COORDS_REMOVE)) { + Tcl_AppendResult(item->wi->interp, + " reticles can't add or remove vertices", NULL); + return RADAR_ERROR; + } + else if ((cmd == COORDS_REPLACE) || (cmd == COORDS_REPLACE_ALL)) { + if (*num_pts == 0) { + Tcl_AppendResult(item->wi->interp, + " coords command need 1 point on reticles", NULL); + return RADAR_ERROR; + } + reticle->pos = (*pts)[0]; + ITEM.Invalidate(item, RADAR_COORDS_FLAG); + } + else if ((cmd == COORDS_READ) || (cmd == COORDS_READ_ALL)) { + *num_pts = 1; + *pts = &reticle->pos; + } + return RADAR_OK; +} + + +/* + ********************************************************************************** + * + * PostScript -- + * + ********************************************************************************** + */ +static void +PostScript(Item item, + PostScriptInfo ps_info) +{ +} + + +/* + ********************************************************************************** + * + * Exported functions struct -- + * + ********************************************************************************** + */ +static ItemClassStruct RETICLE_ITEM_CLASS = { + sizeof(ReticleItemStruct), + False, + False, + False, + "reticle", + reticle_attrs, + Init, + Clone, + Destroy, + Configure, + Query, + NULL, + NULL, + NULL, + Coords, + ComputeCoordinates, + ToArea, + Draw, + IsSensitive, + Pick, + PostScript +}; + +RadarItemClassId RadarReticle = (RadarItemClassId) &RETICLE_ITEM_CLASS; |