This is IcaoMap.m in view mode; [Download] [Up]
#import "IcaoMap.h" #import "mapobjects.h" #import "MapController.h" #import <appkit/appkit.h> @implementation IcaoMap - awakeFromNib { NXPoint hotSpot; cursor = [[NXCursor alloc] initFromImage:[NXImage findImageNamed:"CrossHair"]]; hotSpot.x = 8.0; hotSpot.y = 8.0; [cursor setHotSpot:&hotSpot]; trackingRect = 0; [self setMyTrackingRect:YES]; return self; } - (BOOL)acceptsFirstResponder { return YES; } - infoPopUp { return infoPopUp; } - setMyTrackingRect:(BOOL)flag { NXRect visible; if (trackingRect) { [window discardTrackingRect:trackingRect]; trackingRect = 0; } if (flag) { if ([self getVisibleRect:&visible] && [window isVisible]) { if ([[window delegate] mapZone] != theZone) [[window delegate] copyDataToGlobal]; else [[window delegate] copyDataFromGlobal]; [self convertRect:&visible toView:NULL]; [window setTrackingRect:&visible inside:NO owner:self tag:1 left:NO right:NO]; trackingRect = 1; } } return self; } - resetCursorRects { NXRect visible; if ([self getVisibleRect:&visible]) [self addCursorRect:&visible cursor:cursor]; return self; } - mouseEntered:(NXEvent *)theEvent { inside = YES; [window makeFirstResponder:self]; [window addToEventMask:NX_MOUSEMOVEDMASK]; return self; } - mouseMoved:(NXEvent *)theEvent { if (inside) { NXPoint p; BOOL shift, control; LOCATION pointer; shift = (theEvent->flags & NX_SHIFTMASK) ? YES : NO; control = (theEvent->flags & NX_CONTROLMASK) ? YES : NO; p = theEvent->location; [self convertPoint:&p fromView:nil]; pointer = window2internal(p.x, p.y); [locationField setStringValue:internal2string(pointer)]; #ifndef timetest [timeField setStringValue:nearobject(p.x, p.y)]; #endif } return self; } - mouseExited:(NXEvent *)theEvent { [window removeFromEventMask:NX_MOUSEMOVEDMASK]; [locationField setStringValue:""]; [timeField setStringValue:""]; inside = NO; return self; } - runRubberband { #define LINEWIDTH 2 /* At this point rubberStart is already set */ NXEvent *theEvent; BOOL shouldLoop = YES; int oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK]; char text[80]; char *name; int xtmp, ytmp; int x1, y1, x2, y2; NXRect old, new; NXPoint p2; [self lockFocus]; internal2window(rubberStart, &x1, &y1); gp_setlinestyle(LINEWIDTH, SOLID); gp_setcolor(RED); NXSetRect(&old, x1 - LINEWIDTH, x2 - LINEWIDTH, LINEWIDTH * 2, LINEWIDTH * 2); new = old; PSsetinstance(YES); while (shouldLoop) { NXPing(); theEvent = [NXApp getNextEvent:(NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK)]; if (theEvent->type == NX_LMOUSEUP) { PShideinstance(NX_X(&old), NX_Y(&old), NX_WIDTH(&old), NX_HEIGHT(&old)); shouldLoop = NO; } else { p2 = theEvent->location; [self convertPoint:&p2 fromView:nil]; rubberEnd = window2internal(p2.x, p2.y); if (!(theEvent->flags & NX_SHIFTMASK)) //snap ? { /* This also sets the variable saveobj. aarg */ name = nearobject(p2.x, p2.y); if (saveobj) /* This somehow checks for Areas */ if (saveobj->type / 10 != O_CTR / 10) { rubberEnd = saveobj->location; internal2window(rubberEnd, &xtmp, &ytmp); p2.x = xtmp; p2.y = ytmp; [locationField setStringValue:name]; } else [locationField setStringValue:internal2string(rubberEnd)]; else [locationField setStringValue:internal2string(rubberEnd)]; } else [locationField setStringValue:internal2string(rubberEnd)]; sprintf(text, "dist: %3.3f %s track: %3.2f" , distance(rubberStart, rubberEnd) * UNIT_CHANGE(IPD_RUBBERUNIT) , UNIT_NAME(IPD_RUBBERUNIT) , truetrack(rubberStart, rubberEnd)); #ifndef timetest [timeField setStringValue:text]; #endif internal2window(rubberEnd, &x2, &y2); NXSetRect(&new, MIN(x1, x2) - LINEWIDTH, MIN(y1, y2) - LINEWIDTH ,ABS(x1 - x2) + LINEWIDTH * 2, ABS(y1 - y2) + LINEWIDTH * 2); if (!NXEqualRect(&old, &new)) { PShideinstance(NX_X(&old), NX_Y(&old), NX_WIDTH(&old) ,NX_HEIGHT(&old)); old = new; gp_drawline(x1, y1, x2, y2); } } } [window setEventMask:oldMask]; /* to hide the rubberband */ [self mouseMoved:theEvent]; PSsetinstance(NO); [self unlockFocus]; return self; #undef LINEWIDTH } - mouseDown:(NXEvent *)theEvent { switch (theEvent->data.mouse.click) { case 2: { NXPoint p; /* Get the new center of the map */ p = theEvent->location; [self convertPoint:&p fromView:NULL]; map_origin = window2internal(p.x, p.y); map_initcoord(); /* Update the Coordinate Info */ [self mouseMoved:theEvent]; [self display]; break; } case 1: { NXPoint p; char *name; p = theEvent->location; [self convertPoint:&p fromView:nil]; rubberStart = window2internal(p.x, p.y); if (!(theEvent->flags & NX_SHIFTMASK)) { /* This also sets the global variable saveobj! shudder! */ name = nearobject(p.x, p.y); if (saveobj) { /* This somehow checks for Areas */ if (saveobj->type / 10 != O_CTR / 10) { rubberStart = saveobj->location; } } } [self runRubberband]; break; } } return self; } - removeInfoPopUp { if (infoPopUp) { infoPopUp = [infoPopUp close]; } return self; } - rightMouseUp:(NXEvent *)theEvent { return[self removeInfoPopUp]; } - rightMouseDown:(NXEvent *)theEvent { char *(savelines[MV_MAX_LINES]); int savenumlines; int i; TextField *aTextField; NXPoint p = theEvent->location; NXRect aRect; char *string = malloc(MV_MAX_LINES * MV_MAX_LEN); [self convertPoint:&p fromView:NULL]; for (i = 0; i < MV_MAX_LINES; i++) savelines[i] = malloc(MV_MAX_LEN); objectdescription(savelines, &savenumlines, p.x, p.y, &i); if (savenumlines != 0) { strcpy(string, savelines[0]); for (i = 1; i < savenumlines; i++) { /* OM I think this is not a nice way to do it */ sprintf(string, "%s\n%s", string, savelines[i]); } /* initialize with *any* frame */ aTextField = [[TextField alloc] initFrame:&frame]; [aTextField setSelectable:YES]; [aTextField setBordered:!(theEvent->flags & NX_CONTROLMASK)]; [aTextField setBackgroundGray:NX_LTGRAY]; [aTextField setBackgroundColor:NX_COLORLTGRAY]; [aTextField setStringValue:string]; [aTextField sizeToFit]; [aTextField getFrame:&aRect]; infoPopUp = [[Window alloc] initContent:&aRect style:theEvent->flags & NX_CONTROLMASK ? NX_TITLEDSTYLE : NX_PLAINSTYLE backing:NX_RETAINED buttonMask:NX_CLOSEBUTTONMASK | NX_MINIATURIZEBUTTONMASK defer:YES]; [[infoPopUp setContentView:aTextField] free]; p = theEvent->location; [window convertBaseToScreen:&p]; p.x -= aRect.size.width / 2; p.y -= aRect.size.height + 10; [infoPopUp moveTo:p.x:p.y]; [infoPopUp setTitle:"Info"]; [infoPopUp orderFront:self]; if (theEvent->flags & NX_CONTROLMASK) infoPopUp = NULL; } for (i=0; i < MV_MAX_LINES; i++) free(savelines[i]); free(string); return self; } - drawSelf:(const NXRect *)rects :(int)rectCount { if ([[window delegate] mapZone] != theZone) [[window delegate] copyDataToGlobal]; else [[window delegate] copyDataFromGlobal]; #ifdef timetest [super drawSelf:rects :rectCount]; [timeField setIntValue:Elapsed]; return self; #else return [super drawSelf:rects :rectCount]; #endif } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.