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.