This is MapView.m in view mode; [Download] [Up]
/* TreeView.m - Copyright 1992 Steve Ludtke All Rights Reserved */
/* This object displays each Root as a circle in the x-y plane with */
/* the current location displayed as a cross. */
#import "MapView.h"
#import <appkit/View.h>
#import <appkit/Window.h>
#import <appkit/Control.h>
#import <appkit/Application.h>
#import <strings.h>
#import <dpsclient/psops.h>
#import <math.h>
#import <libc.h>
#define SQR(x) ((x)*(x))
@implementation MapView
/* initialize */
- initFrame:(NXRect *)myrect
{
[super initFrame:myrect];
bgColor = NX_WHITE;
fgColor = NX_BLACK;
xsca = NX_WIDTH(&bounds) / 2.0; /* set scaling for display */
zsca = NX_HEIGHT(&bounds) / 2.0; /* changing the view coordinate system */
xof = NX_MIDX(&bounds); /* would be better */
zof = NX_MIDY(&bounds);
myx = myy = 0.0;
return self;
}
/* One step in time. Just refresh the display */
- step:(Branch *) myloc
{
[self refresh:myloc :80];
return self;
}
/* We want keyboard/mouse events */
- (BOOL)acceptsFirstResponder
{
return YES;
}
/* parse keyboard input */
- keyDown:(NXEvent *)event
{
char c;
c = event->data.key.charCode;
switch (c) {
break;
}
return (self);
}
- keyUp:(NXEvent *)event
{
char c;
c = event->data.key.charCode;
switch (c) {
}
return (self);
}
/* The "meat" of the MapView */
- drawSelf:(NXRect *)rects :(int)rectCount
{
Root *cur;
/* bounding box for DPSDoUserPath */
bbox[0] = bbox[1] = 50.0;
bbox[2] = bbox[3] = 51.0;
/* clear the view */
PSsetlinewidth(0.0);
PSsetgray(NX_BLACK);
NXRectFill(&bounds);
PSsetgray(fgColor = NX_WHITE);
cur = top;
pathc = 0;
while (cur != NULL) {
if (cur->drawme) { /* only draw if drawme is true */
/* draw the "map" display */
PSarc(cur->branch.x / 32768.0 * xsca, cur->branch.y / 32768.0 * zsca, 2.0, 0, 360.0);
PSstroke();
}
/* repeat for all Roots */
cur = cur->next;
}
/* in map mode we want a + where we are */
PSmoveto(myx / 32768.0 * xsca - 4.0, myy / 32768.0 * zsca);
PSlineto(myx / 32768.0 * xsca + 4.0, myy / 32768.0 * zsca);
PSmoveto(myx / 32768.0 * xsca, myy / 32768.0 * zsca + 4.0);
PSlineto(myx / 32768.0 * xsca, myy / 32768.0 * zsca - 4.0);
PSstroke();
/* if we've used a userpath, this will draw it. Currently unused */
if (pathc != 0)
DPSDoUserPath(path, pathc * 2, dps_float, com, pathc, bbox, dps_ustroke);
return self;
}
/* 2d routine to add lines to the view, for future expansion */
- addline:(float)x1 :(float)y1 :(float)x2 :(float)y2
{
static float lastx, lasty;
if (x1 != lastx || y1 != lasty) {
com[pathc] = dps_moveto;
path[pathc * 2] = x1;
path[pathc * 2 + 1] = y1;
pathc++;
if (x1 > bbox[2])
bbox[2] = x1;
if (y1 > bbox[3])
bbox[3] = y1;
if (x1 < bbox[0])
bbox[0] = x1;
if (y1 < bbox[1])
bbox[1] = y1;
}
com[pathc] = dps_lineto;
path[pathc * 2] = x2;
path[pathc * 2 + 1] = y2;
pathc++;
if (x2 > bbox[2])
bbox[2] = x2;
if (y2 > bbox[3])
bbox[3] = y2;
if (x2 < bbox[0])
bbox[0] = x2;
if (y2 < bbox[1])
bbox[1] = y2;
if (pathc >= 1500) {
DPSDoUserPath(path, pathc * 2, dps_float, com, pathc, bbox, dps_ustroke);
bbox[0] = bbox[1] = 50.0;
bbox[2] = bbox[3] = 51.0;
pathc = 0;
}
lastx = x2;
lasty = y2;
return (self);
}
/* handles movement between branches */
- refresh:(Branch *) myloc :(int)speed;
{
float xs, ys, f, xls;
static Branch *last = NULL;
float sp2;
if (myloc == NULL) {
myloc = &top->branch;
last = NULL;
}
if (last == NULL) {
last = myloc;
myx = myloc->x;
myy = myloc->y;
}
sp2 = 51.2;
if (speed <= 80)
sp2 = 97.0;
if (speed <= 60)
sp2 = 182.0;
if (speed <= 40)
sp2 = 273.0;
if (speed <= 20)
sp2 = 400.0;
if (speed == 0)
sp2 = 30000.0;
/* we moved !!! */
if (last != myloc) {
if (last->root != myloc->root) {
/* zoom over to the new tree */
xs = (myloc->x - last->x);
ys = (myloc->y - last->y);
xls = sqrt(SQR(xs) + SQR(ys)) / sp2;
if (xls > 200.0)
xls /= 4.0;
for (f = xls; f >= 0.0; f -= 1.0) {
myx = myloc->x - 2.0 - xs / xls * f;
myy = myloc->y - 2.0 - ys / xls * f;
[self display];
usleep(20000);
}
myx = myloc->x;
myy = myloc->y;
}
}
/* make sure we're looking at the right place */
[self display];
last = myloc;
return self;
}
/* Receive useful pointers */
- start:(Root *) Ptop :Pobject :(char *)path
{
top = Ptop;
object = Pobject;
return self;
}
/* no prefs yet ...*/
- preferences:sender
{
return self;
}
/* display help */
- (char *)help:window :browser
{
return ("MapView - Steve Ludtke May 1992\n\nSimple view that draws a circle for each site and a cross at the current location. Eventually I'll probably expand this one myself to support zooming, rotating, etc... For now it's a good, simple example.");
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.