aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/Reticle.c494
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;