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.