aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--generic/Icon.c736
1 files changed, 736 insertions, 0 deletions
diff --git a/generic/Icon.c b/generic/Icon.c
new file mode 100644
index 0000000..b5f4de0
--- /dev/null
+++ b/generic/Icon.c
@@ -0,0 +1,736 @@
+/*
+ * Icon.c -- Implementation of Icon item.
+ *
+ * Authors : Patrick LECOANET
+ * Creation date : Sat Mar 25 13:53:39 1995
+ */
+
+/*
+ * 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 <malloc.h>
+
+#include "Item.h"
+#include "Geo.h"
+#include "Draw.h"
+#include "Types.h"
+#include "Image.h"
+#include "WidgetInfo.h"
+
+
+static const char rcsid[] = "$Id$";
+static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $";
+
+
+/*
+ **********************************************************************************
+ *
+ * Specific Icon item record
+ *
+ **********************************************************************************
+ */
+typedef struct _IconItemStruct {
+ ItemStruct header;
+
+ /* Public data */
+ RadarPoint pos;
+ char *image_name;
+ RadarAnchor anchor;
+ RadarAnchor connection_anchor;
+ Pixmap mask; /* Used only if the image is *NOT* specified */
+ RadarColor color; /* Used with the mask */
+
+ /* Private data */
+ RadarPoint pos_dev;
+ RadarImage image;
+} IconItemStruct, *IconItem;
+
+
+static RadarAttrConfig icon_attrs[] = {
+ { RADAR_CONFIG_ANCHOR, "-anchor", NULL,
+ Tk_Offset(IconItemStruct, anchor), 0, RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_COLOR, "-color", NULL,
+ Tk_Offset(IconItemStruct, color), 0, RADAR_DRAW_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-composerotation", NULL,
+ Tk_Offset(IconItemStruct, header.flags), COMPOSE_ROTATION_BIT,
+ RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-composescale", NULL,
+ Tk_Offset(IconItemStruct, header.flags), COMPOSE_SCALE_BIT,
+ RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_ITEM, "-connecteditem", NULL,
+ Tk_Offset(IconItemStruct, header.connected_item), 0,
+ RADAR_COORDS_FLAG|RADAR_ITEM_FLAG, False },
+ { RADAR_CONFIG_ANCHOR, "-connectionanchor", NULL,
+ Tk_Offset(IconItemStruct, connection_anchor), 0, RADAR_COORDS_FLAG, False },
+ { RADAR_CONFIG_IMAGE, "-image", NULL,
+ Tk_Offset(IconItemStruct, image_name), 0,
+ RADAR_COORDS_FLAG|RADAR_IMAGE_FLAG, False },
+ { RADAR_CONFIG_PATTERN, "-mask", NULL,
+ Tk_Offset(IconItemStruct, mask), 0, RADAR_DRAW_FLAG|RADAR_REPICK_FLAG, False },
+ { RADAR_CONFIG_POINT, "-position", NULL, Tk_Offset(IconItemStruct, pos), 0,
+ RADAR_COORDS_FLAG, False},
+ { RADAR_CONFIG_PRI, "-priority", NULL,
+ Tk_Offset(IconItemStruct, header.priority), 0,
+ RADAR_DRAW_FLAG|RADAR_REPICK_FLAG, False },
+ { RADAR_CONFIG_BOOL, "-sensitive", NULL,
+ Tk_Offset(IconItemStruct, header.flags), SENSITIVE_BIT,
+ RADAR_REPICK_FLAG, False },
+ { RADAR_CONFIG_TAGS, "-tags", NULL,
+ Tk_Offset(IconItemStruct, header.tags), 0, 0, False },
+ { RADAR_CONFIG_BOOL, "-visible", NULL,
+ Tk_Offset(IconItemStruct, header.flags), VISIBLE_BIT,
+ RADAR_DRAW_FLAG|RADAR_REPICK_FLAG|RADAR_VIS_FLAG, False },
+
+ { RADAR_CONFIG_END, NULL, NULL, 0, 0, 0 }
+};
+
+
+/*
+ **********************************************************************************
+ *
+ * IconImageChange --
+ *
+ **********************************************************************************
+ */
+static void
+IconImageChange(ClientData client_data,
+ int x,
+ int y,
+ int width,
+ int height,
+ int image_width,
+ int image_height)
+{
+ IconItem icon = (IconItem) client_data;
+
+ InvalidateImage(icon->image);
+ ITEM.Invalidate((Item) icon, RADAR_COORDS_FLAG);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Init --
+ *
+ **********************************************************************************
+ */
+static int
+Init(Item item,
+ int *argc,
+ Arg **args)
+{
+ WidgetInfo *wi = item->wi;
+ IconItem icon = (IconItem) item;
+
+ /* Init attributes */
+ SET(item->flags, VISIBLE_BIT);
+ SET(item->flags, SENSITIVE_BIT);
+ SET(item->flags, COMPOSE_ROTATION_BIT);
+ SET(item->flags, COMPOSE_SCALE_BIT);
+ item->priority = DEFAULT_ICON_PRIORITY;
+
+ icon->pos.x = icon->pos.y = 0.0;
+ icon->image_name = "";
+ icon->image = RadarUnspecifiedImage;
+ icon->anchor = RadarAnchorNW;
+ icon->connection_anchor = RadarAnchorSW;
+ icon->mask = RadarUnspecifiedPattern;
+ icon->color = RadarGetColorByValue(wi->win, wi->fore_color);
+
+ return RADAR_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Clone --
+ *
+ **********************************************************************************
+ */
+static void
+Clone(Item item)
+{
+ IconItem icon = (IconItem) item;
+ WidgetInfo *wi = item->wi;
+ char *text;
+
+ if (strlen(icon->image_name) != 0) {
+ text = RadarMalloc((strlen(icon->image_name) + 1) * sizeof(char));
+ strcpy(text, icon->image_name);
+ icon->image_name = text;
+ icon->image = Tk_GetImage(wi->interp, wi->win, icon->image_name,
+ IconImageChange, (ClientData) icon);
+ }
+ if (icon->mask != RadarUnspecifiedPattern) {
+ icon->mask = Tk_GetBitmap(wi->interp, wi->win,
+ Tk_NameOfBitmap(wi->dpy, icon->mask));
+ }
+ icon->color = RadarGetColorByValue(wi->win, icon->color);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Destroy --
+ *
+ **********************************************************************************
+ */
+static void
+Destroy(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ IconItem icon = (IconItem) item;
+
+ if (strlen(icon->image_name) != 0) {
+ RadarFree(icon->image_name);
+ }
+ if (icon->image != RadarUnspecifiedImage) {
+ Tk_FreeImage(icon->image);
+ icon->image = RadarUnspecifiedImage;
+ }
+ if (icon->mask != RadarUnspecifiedPattern) {
+ Tk_FreeBitmap(wi->dpy, icon->mask);
+ icon->mask = RadarUnspecifiedPattern;
+ }
+ RadarFreeColor(icon->color);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Configure --
+ *
+ **********************************************************************************
+ */
+static int
+Configure(Item item,
+ int argc,
+ RadarAttrList argv,
+ int *flags)
+{
+ IconItem icon = (IconItem) item;
+ WidgetInfo *wi = item->wi;
+ Item old_connected;
+
+ old_connected = item->connected_item;
+ if (ITEM_P.ConfigureAttributes((char *) item, -1, argc, argv, flags) == RADAR_ERROR) {
+ return RADAR_ERROR;
+ }
+
+ if (ISSET(*flags, RADAR_ITEM_FLAG)) {
+ /*
+ * If the new connected item is not appropriate back up
+ * to the old one.
+ */
+ if ((item->connected_item == RADAR_NO_ITEM) ||
+ (item->connected_item->class->has_anchors &&
+ (item->parent == item->connected_item->parent))) {
+ ITEM.UpdateItemDependency(item, old_connected);
+ }
+ else {
+ item->connected_item = old_connected;
+ }
+ }
+
+ if (ISSET(*flags, RADAR_IMAGE_FLAG)) {
+ Tk_Image image;
+
+ if (strcmp(icon->image_name, "") != 0) {
+ image = Tk_GetImage(wi->interp, wi->win, icon->image_name,
+ IconImageChange, (ClientData) icon);
+ if (image == NULL) {
+ /*
+ * The name will not be in sync with the image in
+ * this case.
+ */
+ return RADAR_ERROR;
+ }
+ }
+ else {
+ image = RadarUnspecifiedImage;
+ }
+ if (icon->image != RadarUnspecifiedImage) {
+ Tk_FreeImage(icon->image);
+ }
+ icon->image = image;
+ }
+
+ 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;
+ IconItem icon = (IconItem) item;
+ RadarDim width, height;
+ int w, h;
+
+ ResetBBox(&item->item_bounding_box);
+
+ /*
+ * If there is no image and no mask then nothing to show.
+ */
+ if (icon->image == RadarUnspecifiedImage &&
+ icon->mask == RadarUnspecifiedPattern) {
+ return;
+ }
+
+ if (icon->image != RadarUnspecifiedImage) {
+ Tk_SizeOfImage(icon->image, &w, &h);
+ }
+ else {
+ Tk_SizeOfBitmap(wi->dpy, icon->mask, &w,&h);
+ }
+ width = w;
+ height = h;
+
+ /*
+ * The connected item support anchors, this is checked by
+ * configure.
+ */
+ if (item->connected_item != RADAR_NO_ITEM) {
+ item->connected_item->class->GetAnchor(item->connected_item,
+ icon->connection_anchor,
+ &icon->pos_dev);
+ }
+ else {
+ RadarTransformPoint(wi->current_transfo, &icon->pos, &icon->pos_dev);
+ }
+
+ Anchor2Origin(&icon->pos_dev, width, height, icon->anchor,
+ &icon->pos_dev);
+
+ /*
+ * Compute the bounding box.
+ */
+ AddPointToBBox(&item->item_bounding_box, icon->pos_dev.x, icon->pos_dev.y);
+ AddPointToBBox(&item->item_bounding_box, icon->pos_dev.x+width,
+ icon->pos_dev.y+height);
+ item->item_bounding_box.orig.x -= 1;
+ item->item_bounding_box.orig.y -= 1;
+ item->item_bounding_box.corner.x += 1;
+ item->item_bounding_box.corner.y += 1;
+
+ /*
+ * Update connected items.
+ */
+ SET(item->flags, UPDATE_DEPENDENT_BIT);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * 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)
+{
+ /* IconItem icon = (IconItem) item;*/
+
+ return BBoxInBBox(&item->item_bounding_box, area);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Draw --
+ *
+ **********************************************************************************
+ */
+static void
+Draw(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ IconItem icon = (IconItem) item;
+ XGCValues values;
+ int gc_mask = 0;
+ ImageBits *im_bits;
+ Pixmap pmap, mask_pmap;
+
+ if (icon->image != RadarUnspecifiedImage) {
+ if (wi->current_clip) {
+ if (wi->current_clip->simple) {
+ Tk_RedrawImage(icon->image,
+ item->item_bounding_box.orig.x-icon->pos_dev.x,
+ item->item_bounding_box.orig.y-icon->pos_dev.y,
+ item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
+ item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
+ wi->draw_buffer,
+ item->item_bounding_box.orig.x,
+ item->item_bounding_box.orig.y);
+ }
+ else {
+ /*
+ * Non rectangular clipping. Two cases here: if the image
+ * has no contour mask, simply use the clipping set in the
+ * current gc, if not, we have to generate a bitmap mask
+ * using the image mask and the current clip and use this
+ * bitmap as the current clip.
+ */
+ im_bits = GetImageBits(wi->win, icon->image);
+ pmap = GetImagePixmap(wi->win, icon->image);
+ if (im_bits->mask == RadarUnspecifiedPattern) {
+ XCopyArea(wi->dpy, pmap, wi->draw_buffer, wi->gc,
+ item->item_bounding_box.orig.x-icon->pos_dev.x,
+ item->item_bounding_box.orig.y-icon->pos_dev.y,
+ item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
+ item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
+ item->item_bounding_box.orig.x,
+ item->item_bounding_box.orig.y);
+ }
+ else {
+ GC gc;
+ /*
+ * Build of the mask
+ */
+ mask_pmap = XCreatePixmap(wi->dpy, RadarWindowId(wi->win),
+ im_bits->width, im_bits->height, 1);
+ gc = XCreateGC(wi->dpy, mask_pmap, 0, NULL);
+ XFillRectangle(wi->dpy, mask_pmap, gc, 0, 0, im_bits->width, im_bits->height);
+ XSetRegion(wi->dpy, gc, wi->current_clip->region);
+ values.foreground = 1;
+ values.background = 0;
+ values.clip_x_origin = (int) -icon->pos_dev.x;
+ values.clip_y_origin = (int) -icon->pos_dev.y;
+ XChangeGC(wi->dpy, gc,
+ GCForeground|GCBackground|GCClipXOrigin|GCClipYOrigin, &values);
+ XPutImage(wi->dpy, mask_pmap, gc, im_bits->mask, 0, 0, 0, 0,
+ im_bits->width, im_bits->height);
+ XFreeGC(wi->dpy, gc);
+ /*
+ * Drawing of the icon using the mask.
+ */
+ XSetClipMask(wi->dpy, wi->gc, mask_pmap);
+ values.clip_x_origin = (int) icon->pos_dev.x;
+ values.clip_y_origin = (int) icon->pos_dev.y;
+ XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
+ XCopyArea(wi->dpy, pmap, wi->draw_buffer, wi->gc,
+ item->item_bounding_box.orig.x-icon->pos_dev.x,
+ item->item_bounding_box.orig.y-icon->pos_dev.y,
+ item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
+ item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
+ item->item_bounding_box.orig.x,
+ item->item_bounding_box.orig.y);
+ XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
+ values.clip_x_origin = 0;
+ values.clip_y_origin = 0;
+ XChangeGC(wi->dpy, wi->gc, GCClipXOrigin|GCClipYOrigin, &values);
+ XFreePixmap(wi->dpy, mask_pmap);
+ }
+ }
+ }
+ else { /* !current_clip */
+ Tk_RedrawImage(icon->image, 0, 0,
+ item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
+ item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
+ wi->draw_buffer,
+ item->item_bounding_box.orig.x,
+ item->item_bounding_box.orig.y);
+ }
+ }
+ else if (icon->mask != RadarUnspecifiedPattern) {
+ values.fill_style = FillStippled;
+ values.stipple = icon->mask;
+ values.ts_x_origin = icon->pos_dev.x;
+ values.ts_y_origin = icon->pos_dev.y;
+ values.foreground = RadarPixel(icon->color);
+ gc_mask |= GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCForeground;
+ XChangeGC(wi->dpy, wi->gc, gc_mask, &values);
+ XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc,
+ item->item_bounding_box.orig.x,
+ item->item_bounding_box.orig.y,
+ item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
+ item->item_bounding_box.corner.y-item->item_bounding_box.orig.y);
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * 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 --
+ *
+ **********************************************************************************
+ */
+static double
+Pick(Item item,
+ RadarPoint *p,
+ Item start_item,
+ int aperture,
+ Item *a_item,
+ int *part)
+{
+ IconItem icon = (IconItem) item;
+ WidgetInfo *wi = item->wi;
+ double dist;
+ int width, height;
+ double off_dist = MAX(1, wi->pick_aperture+1);
+
+ dist = RectangleToPointDist(&item->item_bounding_box, p);
+ /*
+ * If inside the bounding box, try to see if the point
+ * is actually on the image or not. If it lies in an
+ * area that is between pick_aperture+1 around the bbox
+ * and the actual shape, the distance will be reported
+ * as pick_aperture+1. Inside the actual shape it will be
+ * reported as 0. This is a kludge, there is currently
+ * no means to compute the real distance in the icon's
+ * vicinity.
+ */
+ if (dist <= 0.0) {
+ XImage *bitmap=NULL;
+ ImageBits *im_bits;
+ RadarPoint dp;
+
+ dist = 0.0;
+ dp.x = p->x - item->item_bounding_box.orig.x;
+ dp.y = p->y - item->item_bounding_box.orig.y;
+ if (icon->image != RadarUnspecifiedImage) {
+ Tk_SizeOfImage(icon->image, &width, &height);
+ if (dp.x >= width || dp.y >= height) {
+ dist = off_dist;
+ goto out_pick;
+ }
+ im_bits = GetImageBits(wi->win, icon->image);
+ bitmap = im_bits->mask;
+ }
+ else if (icon->mask != RadarUnspecifiedPattern) {
+ Tk_SizeOfBitmap(wi->dpy, icon->mask, &width, &height);
+ if (dp.x >= width || dp.y >= height) {
+ dist = off_dist;
+ goto out_pick;
+ }
+ bitmap = GetBitmapMask(wi->dpy, icon->mask);
+ }
+ if (bitmap != RadarUnspecifiedPattern) {
+ /*printf("dpx=%g, dpy=%g, width=%d, height=%d, pixel=%ld\n", dp.x, dp.y,
+ width, height, XGetPixel(bitmap, (int) dp.x, (int) dp.y));*/
+ if (! XGetPixel(bitmap, (int) dp.x, (int) dp.y)) {
+ dist = off_dist;
+ }
+ }
+ }
+ else if (dist < off_dist) {
+ dist = off_dist;
+ }
+
+out_pick:
+ /*printf("dist = %g\n", dist);*/
+ return dist;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * PostScript --
+ *
+ **********************************************************************************
+ */
+static void
+PostScript(Item item,
+ PostScriptInfo ps_info)
+{
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetAnchor --
+ *
+ **********************************************************************************
+ */
+static void
+GetAnchor(Item item,
+ RadarAnchor anchor,
+ RadarPoint *p)
+{
+ IconItem icon = (IconItem) item;
+
+ if ((icon->image != RadarUnspecifiedImage) ||
+ (icon->mask != RadarUnspecifiedPattern)) {
+ Origin2Anchor(&icon->pos_dev,
+ item->item_bounding_box.corner.x-item->item_bounding_box.orig.x,
+ item->item_bounding_box.corner.y-item->item_bounding_box.orig.y,
+ anchor, p);
+ }
+ else {
+ p->x = p->y = 0.0;
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetClipVertices --
+ * Get the clipping shape.
+ *
+ **********************************************************************************
+ */
+static RadarBool
+GetClipVertices(Item item,
+ RadarPoint **points,
+ int *num_points)
+{
+ RadarListAssertSize(item->wi->work_pts, 2);
+ *points = (RadarPoint *) RadarListArray(item->wi->work_pts);
+ *num_points = 2;
+ (*points)[0] = item->item_bounding_box.orig;
+ (*points)[1] = item->item_bounding_box.corner;
+
+ return True;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Coords --
+ * Return or edit the item origin. This doesn't take care of
+ * the possible attachment. The change will be effective at the
+ * end of the attachment.
+ *
+ **********************************************************************************
+ */
+static int
+Coords(Item item,
+ int index,
+ int cmd,
+ RadarPoint **pts,
+ int *num_pts)
+{
+ IconItem icon = (IconItem) item;
+
+ if ((cmd == COORDS_ADD) || (cmd == COORDS_ADD_LAST) || (cmd == COORDS_REMOVE)) {
+ Tcl_AppendResult(item->wi->interp,
+ " icons 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 icons", NULL);
+ return RADAR_ERROR;
+ }
+ icon->pos = (*pts)[0];
+ ITEM.Invalidate(item, RADAR_COORDS_FLAG);
+ }
+ else if ((cmd == COORDS_READ) || (cmd == COORDS_READ_ALL)) {
+ *num_pts = 1;
+ *pts = &icon->pos;
+ }
+ return RADAR_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Exported functions struct --
+ *
+ **********************************************************************************
+ */
+static ItemClassStruct ICON_ITEM_CLASS = {
+ sizeof(IconItemStruct),
+ False,
+ False,
+ True,
+ "icon",
+ icon_attrs,
+ Init,
+ Clone,
+ Destroy,
+ Configure,
+ Query,
+ NULL,
+ GetAnchor,
+ GetClipVertices,
+ Coords,
+ ComputeCoordinates,
+ ToArea,
+ Draw,
+ IsSensitive,
+ Pick,
+ PostScript
+};
+
+RadarItemClassId RadarIcon = (RadarItemClassId) &ICON_ITEM_CLASS;