This is GraphicView.m in view mode; [Download] [Up]
/* GraphicView.m -- The meaty part of the front end. * * Written By: Bill Bumgarner (Friday Software & Consulting) * <wb1j+@andrew.cmu.edu> * 414 S.Craig, #119 * Pittsburgh, PA. 15213 * 412-268-5378 * * This class drives the bitmap object-- it handles events, does * initialization and provides the interface between the bitmap and * the user interface. */ #import "GraphicView.h" #import "TGIF.h" #import "NXBitmapGraphicRep.h" #import <appkit/Application.h> #import <appkit/Slider.h> #import <appkit/Window.h> #import <appkit/color.h> #import <appkit/graphics.h> #import <math.h> #import <libc.h> #import "CmdVertex.h" #import "CmdBgnpoly.h" #import "CmdEndpoly.h" #import "AbsPoly.h" // Pre-defined Color Depths (NX_EightBitGrayDepth is not supported yet): // NX_DefaultDepth // NX_TwoBitGrayDepth // NX_EightBitGrayDepth // NX_TwelveBitRGBDepth // NX_TwentyFourBitRGBDepth // NeXT Pre-defined Colors: // NX_COLORBLACK // NX_COLORWHITE // NX_COLORGRAY // NX_COLORLTGRAY // NX_COLORDKGRAY // NX_COLORRED // NX_COLORGREEN // NX_COLORBLUE // NX_COLORCYAN // NX_COLORYELLOW // NX_COLORMAGENTA // NX_COLORORANGE // NX_COLORPURPLE // NX_COLORBROWN // NX_COLORCLEAR @implementation GraphicView id tgif; BOOL polyDrawing=NO; BOOL lineDrawing=YES; id curPoly; - initFrame:(NXRect *) aRect { [super initFrame:aRect]; bitmap=[[NXBitmapGraphicRep alloc] initWithSize:&(aRect->size) // change this to one of the predefined depths if you want to work // in other than two bit gray mode. As long as you use the // plotPoint method (or write your own color-handling bit // manipulation stuff) // the NXBitmapGraphicRep class will deal w/the different color // models automatically. Two change the color model for an existing // program, simply change the constant below and recompile. // currently, changing the color model on the fly is not supported // (though it is not that difficult to do!). depth:NX_TwoBitGrayDepth andColor:NX_COLORDKGRAY]; [self setFlipped:NO]; return self; } - infoPanel:sender { if (infoPanel == nil) { infoPanel = [NXApp loadNibSection:"InfoPanel.nib" owner:self withNames:NO]; [infoPanel center]; } [infoPanel orderFront:sender]; return self; } // this method is called immediately after all IB objects are created and // initialized and immediately before applicaton receives a -run message. -appDidInit:sender { float gray; [bitmap setColor:NX_COLORLTGRAY]; NXConvertColorToGray([bitmap color], &gray); [foreWell setColor:[bitmap color]]; [foreWell setContinuous:YES]; [foreSlide setFloatValue:gray]; [backWell setColor:[bitmap backColor]]; [backWell setContinuous:YES]; NXConvertColorToGray([bitmap backColor], &gray); [backSlide setFloatValue:gray]; srandom(getpid()); // start in line-drawing mode polyDrawing=NO; lineDrawing=YES; tgif=[[TGIF alloc] initWithBitmap:bitmap andView:self]; return self; } - drawSelf:(const NXRect *)rects :(int)rectCount { [bitmap draw]; return self; } long randnum(min, max) long min, max; { return (max-min)*(random()/(pow(2,31)-1))+min; } - draw:sender { int i; // normally, the [self display] would be done after ALL drawing. It is // done this way only as a throughput test. [bitmap setColor:NX_COLORBLACK]; for(i=0;i<1000;i++) { [bitmap line:randnum(0,639) :randnum(0,479) :randnum(0,639) :randnum(0,479)]; } [self display]; return self; } - setFore:sender { NXColor c=NXConvertGrayToColor([sender floatValue]); if (!NXEqualColor(c, [bitmap color])){ [bitmap setColor:c]; [foreWell setColor:c]; [tgif cmdForeColor:c]; } return self; } - setBack:sender { NXColor c=NXConvertGrayToColor([sender floatValue]); if (!NXEqualColor(c, [bitmap backColor])){ [bitmap setBackColor:c]; [backWell setColor:c]; [tgif cmdBackColor:c]; [bitmap eraseFrame]; [self display]; } return self; } - startStopPolyDraw:sender { if(polyDrawing){ polyDrawing=NO; // initialize poly data struct } else { polyDrawing=YES; // draw the polygon } return self; } NXPoint start,end; - mouseDown:(NXEvent *)theEvent { start=theEvent->location; [self convertPoint:&start fromView:nil]; if(!polyDrawing) [tgif cmdMove:(int)start.x :(int)start.y]; return self; } - mouseUp:(NXEvent *)theEvent { end=theEvent->location; [self convertPoint:&end fromView:nil]; if(!polyDrawing){ [bitmap line:(int)start.x :(int)start.y :(int)end.x :(int)end.y]; [tgif cmdDraw:(int)end.x :(int)end.y]; [self display]; } else [curPoly addCommand:[[CmdVertex alloc] initCmd:end.x :end.y]]; return self; } -eraseImage:sender { // erase the bitmap to the current backColor [bitmap eraseFrame]; [tgif cmdNewFrame]; // redisplay bitmap [self display]; return self; } - foreWell:sender { float gray; NXColor c=[sender color]; if(!NXEqualColor(c, [bitmap color])){ [bitmap setColor:c]; NXConvertColorToGray(c, &gray); [foreSlide setFloatValue:gray]; [tgif cmdForeColor:c]; } return self; } - backWell:sender { float gray; NXColor c=[sender color]; if(!NXEqualColor(c, [bitmap backColor])){ [bitmap setBackColor:c]; NXConvertColorToGray(c, &gray); [backSlide setFloatValue:gray]; [bitmap eraseFrame]; [tgif cmdBackColor:c]; [self display]; } return self; } - saveCommands:sender { if(polyDrawing){ [curPoly addCommand:[[CmdEndpoly alloc] initCmd]]; [curPoly doCmd]; [self display]; polyDrawing=NO; } [tgif saveToFile]; return self; } - openCommands:sender { if(polyDrawing){ [curPoly addCommand:[[CmdEndpoly alloc] initCmd]]; polyDrawing=NO; } [tgif openFile]; return self; } - newCommands:sender { [tgif newFile]; return self; } #define BTN_CROSS 0 #define BTN_ARROW 1 #define BTN_CIRCLE 2 #define BTN_LINE 3 #define BTN_POLY 4 - toolHit:sender { int hitOn=[[sender selectedCell] tag]; if(polyDrawing){ // close polygon and do command [curPoly addCommand:[[CmdEndpoly alloc] initCmd]]; [curPoly doCmd]; [self display]; polyDrawing=NO; } switch (hitOn){ case BTN_CROSS: case BTN_ARROW: polyDrawing=NO; lineDrawing=NO; [toolStatus setStringValue:"Selection"]; break; case BTN_LINE: lineDrawing=YES; [toolStatus setStringValue:"Line Drawing"]; break; case BTN_POLY: polyDrawing=YES; [toolStatus setStringValue:"Poly Drawing"]; curPoly=[tgif cmdNewPoly]; [curPoly addCommand:[[CmdBgnpoly alloc] initCmd]]; break; case BTN_CIRCLE: fprintf(stderr, "Circle Drawing not yet implemented\n"); break; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.