Ignore:
Timestamp:
Jun 13, 2012 8:06:54 PM (12 years ago)
Author:
gah
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/src/RpCanvHotspot.c

    r3039 r3040  
    9191                                         * where the item is drawn on the
    9292                                         * canvas. */
    93 
     93    double x1, y1, x2, y2;
    9494    /*
    9595     * Configuration settings that are updated by Tk_ConfigureWidget:
     
    136136    ItemSegment *firstPtr, *lastPtr;    /* List of hotspot segments. */
    137137    int width, height;                  /* Dimension of bounding box. */
    138     ItemSegment *activePtr;             /* Active segment. */
     138    const char *activeValue;            /* Active segment. */
    139139    short int maxImageWidth, maxImageHeight;
    140140    int numLines;
     
    152152    {TK_CONFIG_STRING, "-activeimage", "activeImage", (char*)NULL, (char*)NULL,
    153153        Tk_Offset(HotspotItem, activeImageName), TK_CONFIG_NULL_OK},
     154    {TK_CONFIG_STRING, "-activevalue", "activeValue", (char*)NULL, (char*)NULL,
     155        Tk_Offset(HotspotItem, activeValue), TK_CONFIG_NULL_OK},
    154156    {TK_CONFIG_ANCHOR, "-anchor", "anchor", (char*)NULL,
    155157        "center", Tk_Offset(HotspotItem, anchor),
     
    168170        "blue", Tk_Offset(HotspotItem, activeValueBorder), 0},
    169171    {TK_CONFIG_FONT, "-valuefont", (char*)NULL, (char*)NULL,
    170         "courier -12", Tk_Offset(HotspotItem, valueFont), 0},
     172        "helvetica -12 bold", Tk_Offset(HotspotItem, valueFont), 0},
    171173    {TK_CONFIG_COLOR, "-valueforeground", (char*)NULL, (char*)NULL,
    172174        "blue", Tk_Offset(HotspotItem, valueColor), 0},
     
    569571    segPtr->lineNum = itemPtr->numLines;
    570572    segPtr->type = SEGMENT_TYPE_VARIABLE;
    571     memcpy(segPtr->text, varName, length);
     573    strncpy(segPtr->text, varName, length);
    572574    segPtr->text[length] = '\0';
    573575    segPtr->length = length;
     
    592594
    593595static void
    594 AddHotspotSegment(HotspotItem *itemPtr)
     596AddHotspotSegment(HotspotItem *itemPtr, const char *varName, int length)
    595597{
    596598    ItemSegment *segPtr;
    597599
    598     segPtr = (ItemSegment *)Tcl_Alloc(sizeof(ItemSegment));
     600    segPtr = (ItemSegment *)Tcl_Alloc(sizeof(ItemSegment) + length + 1);
    599601    memset(segPtr, 0, sizeof(ItemSegment));
    600602    segPtr->itemPtr = itemPtr;
    601603    segPtr->lineNum = itemPtr->numLines;
    602604    segPtr->type = SEGMENT_TYPE_HOTSPOT;
    603     segPtr->text[0] = '\0';
    604     segPtr->length = 0;
     605    strncpy(segPtr->text, varName, length);
     606    segPtr->text[length] = '\0';
     607    segPtr->length = length;
    605608    segPtr->x = segPtr->y = 0;
    606609    segPtr->nextPtr = NULL;
     
    756759    itemPtr->width = maxWidth;
    757760    itemPtr->height = y;
     761    ComputeBbox(itemPtr);
    758762}
    759763
     
    784788                if (*q == '}') {
    785789                    AddVariableSegment(itemPtr, varName, q - varName);
    786                     AddHotspotSegment(itemPtr);
     790                    AddHotspotSegment(itemPtr, varName, q- varName);
    787791                    p = q;
    788792                    start = p + 1;
     
    846850    }
    847851
     852    memset((char *)itemPtr + sizeof(Tk_Item), 0, sizeof(HotspotItem) - sizeof(Tk_Item));
    848853    /*
    849854     * Carry out initialization that is needed in order to clean up after
    850855     * errors during the the remainder of this procedure.
    851856     */
    852     itemPtr->activeImage = NULL;
    853     itemPtr->activeImageName = NULL;
    854     itemPtr->activePtr = NULL;
    855857    itemPtr->anchor = TK_ANCHOR_CENTER;
    856     itemPtr->border = NULL;
    857     itemPtr->borderWidth = 0;
    858858    itemPtr->canvas = canvas;
    859859    itemPtr->display = Tk_Display(tkwin);
    860     itemPtr->firstPtr = NULL;
    861     itemPtr->font = NULL;
    862     itemPtr->height = 0;
    863     itemPtr->image = NULL;
    864     itemPtr->imageName  = NULL;
    865860    itemPtr->interp = interp;
    866     itemPtr->lastPtr = NULL;
    867     itemPtr->maxImageWidth = itemPtr->maxImageHeight = 0;
    868     itemPtr->normalGC = None;
    869     itemPtr->numLines = 0;
    870     itemPtr->outlineColor = NULL;
    871     itemPtr->outlineGC = None;
    872861    itemPtr->relief = TK_RELIEF_FLAT;
    873     itemPtr->valueColor = NULL;
    874     itemPtr->valueFont = NULL;
    875     itemPtr->valueGC = None;
    876     itemPtr->activeGC = None;
     862    itemPtr->tkwin = tkwin;
    877863    itemPtr->valueInterp = interp;
    878     itemPtr->text = NULL;
    879     itemPtr->textColor = NULL;
    880     itemPtr->tkwin = tkwin;
    881     itemPtr->width = 0;
    882     itemPtr->x = itemPtr->y = 0.0;
     864    itemPtr->border = NULL;
     865    itemPtr->activeValueBorder = NULL;
    883866
    884867    /* Process the arguments to fill in the item record. */
     
    11781161 */
    11791162static void
    1180 TranslateAnchor(HotspotItem *itemPtr, int *xPtr, int *yPtr)
    1181 {
    1182     int x, y;
     1163TranslateAnchor(HotspotItem *itemPtr, double *xPtr, double *yPtr)
     1164{
     1165    double x, y;
    11831166
    11841167    x = *xPtr, y = *yPtr;
     
    11871170        break;
    11881171    case TK_ANCHOR_W:           /* Left center */
    1189         y -= (itemPtr->height / 2);
     1172        y -= (itemPtr->height * 0.5);
    11901173        break;
    11911174    case TK_ANCHOR_SW:          /* Lower left corner */
     
    11931176        break;
    11941177    case TK_ANCHOR_N:           /* Top center */
    1195         x -= (itemPtr->width / 2);
     1178        x -= (itemPtr->width * 0.5);
    11961179        break;
    11971180    case TK_ANCHOR_CENTER:      /* Centered */
    1198         x -= (itemPtr->width / 2);
    1199         y -= (itemPtr->height / 2);
     1181        x -= (itemPtr->width * 0.5);
     1182        y -= (itemPtr->height * 0.5);
    12001183        break;
    12011184    case TK_ANCHOR_S:           /* Bottom center */
    1202         x -= (itemPtr->width / 2);
     1185        x -= (itemPtr->width * 0.5);
    12031186        y -= itemPtr->height;
    12041187        break;
     
    12081191    case TK_ANCHOR_E:           /* Right center */
    12091192        x -= itemPtr->width;
    1210         y -= (itemPtr->height / 2);
     1193        y -= (itemPtr->height * 0.5);
    12111194        break;
    12121195    case TK_ANCHOR_SE:          /* Lower right corner */
     
    12421225ComputeBbox(HotspotItem *itemPtr)
    12431226{
    1244     int x, y;
    1245 
    1246     x = ROUND(itemPtr->x);
    1247     y = ROUND(itemPtr->y);
    1248     TranslateAnchor(itemPtr,&x, &y);
    1249     itemPtr->base.x1 = x;
    1250     itemPtr->base.y1 = y;
    1251     itemPtr->base.x2 = x + itemPtr->width;
    1252     itemPtr->base.y2 = y + itemPtr->height;
     1227    double x, y;
     1228
     1229    x = itemPtr->x, y = itemPtr->y;
     1230    TranslateAnchor(itemPtr, &x, &y);
     1231    itemPtr->x1 = x;
     1232    itemPtr->x2 = x + itemPtr->width;
     1233    itemPtr->y1 = y;
     1234    itemPtr->y2 = y + itemPtr->height;
     1235    itemPtr->base.x1 = ROUND(itemPtr->x1);
     1236    itemPtr->base.y1 = ROUND(itemPtr->y1);
     1237    itemPtr->base.x2 = ROUND(itemPtr->x2);
     1238    itemPtr->base.y2 = ROUND(itemPtr->y2);
    12531239}
    12541240
     
    12641250
    12651251        tkImage = NULL;
    1266         if (itemPtr->activePtr == segPtr) {
     1252        if ((itemPtr->activeValue != NULL) &&
     1253            (strcmp(itemPtr->activeValue, segPtr->text) == 0)) {
    12671254            tkImage = itemPtr->activeImage;
    12681255        }
     
    13051292    HotspotItem *itemPtr = (HotspotItem *) canvItemPtr;
    13061293    ItemSegment *segPtr;
    1307     short int cx, cy;
     1294    short int drawX, drawY;
     1295    double tx, ty;
    13081296
    13091297    itemPtr->flags &= ~REDRAW_PENDING;
     
    13141302        ComputeGeometry(itemPtr);
    13151303    }
    1316     Tk_CanvasDrawableCoords(canvas, itemPtr->x, itemPtr->y, &cx, &cy);
    1317     x = cx, y = cy;
    1318     TranslateAnchor(itemPtr, &x, &y);
     1304    tx = itemPtr->x, ty = itemPtr->y;
     1305    TranslateAnchor(itemPtr, &tx, &ty);
     1306
     1307    /* Convert canvas coordinates to drawable coordinates. */
     1308    Tk_CanvasDrawableCoords(canvas, tx, ty, &drawX, &drawY);
     1309    x = drawX, y = drawY;
    13191310
    13201311    if (itemPtr->border != NULL) {
     
    14021393    HotspotItem *itemPtr = (HotspotItem *)canvItemPtr;
    14031394
    1404     /* Compare against bounding box... */
    1405     if ((rectPtr[0] > itemPtr->base.x2) || (rectPtr[1] > itemPtr->base.y2) ||
    1406         (rectPtr[2] < itemPtr->base.x1) || (rectPtr[3] < itemPtr->base.y1)) {
    1407         return -1;                      /* Completely outside. */
    1408     }
    1409     if ((rectPtr[0] >= itemPtr->base.x1) && (rectPtr[1] >= itemPtr->base.y1) &&
    1410         (rectPtr[2] <= itemPtr->base.x2) && (rectPtr[3] <= itemPtr->base.y2)) {
    1411         return 1;                       /* Completely inside. */
    1412     }
    1413     return 0;                           /* Must be overlapping */
     1395    if ((rectPtr[2] <= itemPtr->base.x1) ||
     1396        (rectPtr[0] >= itemPtr->base.x2) ||
     1397        (rectPtr[3] <= itemPtr->base.y1) ||
     1398        (rectPtr[1] >= itemPtr->base.y2)) {
     1399        return -1;
     1400    }
     1401    if ((rectPtr[0] <= itemPtr->base.x1) &&
     1402        (rectPtr[1] <= itemPtr->base.y1) &&
     1403        (rectPtr[2] >= itemPtr->base.x2) &&
     1404        (rectPtr[3] >= itemPtr->base.y2)) {
     1405        return 1;
     1406    }
     1407    return 0;
    14141408}
    14151409
     
    14371431    HotspotItem *itemPtr = (HotspotItem *)canvItemPtr;
    14381432
    1439     itemPtr->x += scaleX * (itemPtr->x - x);
    1440     itemPtr->y += scaleY * (itemPtr->y - y);
     1433    itemPtr->x = x + scaleX * (itemPtr->x - x);
     1434    itemPtr->y = y + scaleY * (itemPtr->y - y);
    14411435    ComputeBbox(itemPtr);
    14421436    return;
     
    16551649}
    16561650
     1651static const char *
     1652Identify(Tcl_Interp *interp, HotspotItem *itemPtr, double x, double y)
     1653{
     1654    double tx, ty;
     1655    short drawX, drawY;
     1656    ItemSegment *segPtr;
     1657    int xOffset, yOffset;
     1658
     1659    tx = itemPtr->x, ty = itemPtr->y;
     1660    TranslateAnchor(itemPtr, &tx, &ty);
     1661
     1662    /* Convert canvas coordinates to drawable coordinates. */
     1663    Tk_CanvasDrawableCoords(itemPtr->canvas, tx, ty, &drawX, &drawY);
     1664    xOffset = ROUND(tx), yOffset = ROUND(ty);
     1665   
     1666    for (segPtr = itemPtr->firstPtr; segPtr != NULL; segPtr = segPtr->nextPtr) {
     1667        int x1, x2, y1, y2;
     1668
     1669        if (segPtr->type == SEGMENT_TYPE_TEXT) {
     1670            continue;
     1671        }
     1672        x1 = xOffset + segPtr->x;
     1673        x2 = xOffset + segPtr->x + segPtr->width;
     1674        y1 = yOffset + segPtr->y;
     1675        y2 = yOffset + segPtr->y + segPtr->height;
     1676        fprintf(stderr, "x=%g y=%g x1=%d x2=%d y1=%d y2=%d xOff=%d yOff=%d ix=%g iy=%g tx=%g ty=%g\n",
     1677                x, y, x1, x2, y1, y2, xOffset, yOffset, itemPtr->x, itemPtr->y, tx, ty);
     1678        if ((x >= x1) && (x < x2) && (y >= y1) && (y < y2)) {
     1679            return segPtr->text;
     1680        }
     1681    }
     1682    return "";
     1683}
     1684
    16571685static int
    16581686HotspotCmd(ClientData clientData, Tcl_Interp *interp, int objc,
     
    16771705    } else if ((c == 'd') && (strncmp(string, "deactivate", length) == 0)) {
    16781706        /* hotspot deactivate .c 0 */
    1679         itemPtr->activePtr = NULL;
     1707        itemPtr->activeValue = NULL;
    16801708    } else if ((c == 'i') && (strncmp(string, "identify", length) == 0)) {
     1709        double x, y;
     1710        const char *token;
     1711        Tcl_Obj *objPtr;
     1712
    16811713        /* hotspot identify .c 0 x y */
    1682         /* Return name of variable identified by x,y coordinate. */
     1714        if ((Tcl_GetDoubleFromObj(interp, objv[4], &x) != TCL_OK) ||
     1715            (Tcl_GetDoubleFromObj(interp, objv[5], &y) != TCL_OK)) {
     1716            return TCL_ERROR;
     1717        }
     1718        token = Identify(interp, itemPtr, x, y);
     1719        objPtr = Tcl_NewStringObj(token, -1);
     1720        Tcl_SetObjResult(interp, objPtr);
    16831721    } else if ((c == 'v') && (strncmp(string, "variables", length) == 0)) {
     1722        Tcl_Obj *listObjPtr;
     1723        ItemSegment *segPtr;
     1724
    16841725        /* hotspot variables .c 0 */
    1685         /* Return list of variable names. */
     1726        listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
     1727        for (segPtr = itemPtr->firstPtr; segPtr != NULL;
     1728             segPtr = segPtr->nextPtr) {
     1729            if (segPtr->type == SEGMENT_TYPE_VARIABLE) {
     1730                Tcl_Obj *objPtr;
     1731
     1732                objPtr = Tcl_NewStringObj(segPtr->text, -1);
     1733                Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
     1734            }
     1735        }
     1736        Tcl_SetObjResult(interp, listObjPtr);
    16861737    } else {
    16871738        Tcl_AppendResult(interp, "unknown hotspot option \"", string,
     
    17091760{
    17101761    Tk_CreateItemType(&hotspotType);
     1762    Tcl_CreateObjCommand(interp, "Rappture::hotspot", HotspotCmd, NULL, NULL);
    17111763    return TCL_OK;
    17121764}
Note: See TracChangeset for help on using the changeset viewer.