This is DemoDiagram.m in view mode; [Download] [Up]
#import "DemoDiagram.h" #import "DiagramCell.h" @implementation DemoDiagram - initFrame:(NXRect *)r { [super initFrame:r]; /* Compute view limits for later use. */ minX=bounds.origin.x; maxX=minX+bounds.size.width-1.0; minY=bounds.origin.y; maxY=minY+bounds.size.height-1.0; itemList=[[List alloc] initCount:10]; //List of graphic items in the diagram [self setClipping:NO]; //Faster, and we'll be careful return self; } - setBackground:(NXImage *)anImage { bgImage=anImage; return self; } /* Drawing the view consists simply of compositing the background, then compositing each of the graphic items. */ - drawSelf:(NXRect *)rect :(int)c { int i; [bgImage composite:NX_COPY toPoint:&bounds.origin]; for (i=0; i<[itemList count]; i++){ [[itemList objectAt:i] drawSelf]; } return self; } - addItem:item { [itemList addObject:item]; [self display]; return self; } /* When the mouse goes down, search the item list, from top to bottom, for the first object answering self to the mouseHit request. That becomes the moused object. */ - mouseDownAction:(NXPoint *)location { id item; int i; mousedObject=nil; for (i=[itemList count]-1; i>=0; i--){ item=[itemList objectAt:i]; if([item mouseHit:location]){ mousedObject=item; oldMouse=*location; //save first mouse location break; } } [self lockFocus]; //prepare to draw while dragging return self; } /* When dragging, ask each item to draw its intersection with the dirty rectangle. */ - mouseDraggedAction:(NXPoint *)newMouse { int i; NXPoint mouseLoc; //location of the mouse cursor; float dx,dy; //relative x and y changes; NXRect dirtyRect,newRect; if(!mousedObject)return self; // If no mousehit in mouseDown /* Save rectangle before moving as initial dirty rect */ [mousedObject getFrame:&dirtyRect]; /* This is the new location of the mouse */ mouseLoc=*newMouse; /* First, constrain mouse point to appear to be in the view */ if(mouseLoc.x > maxX)mouseLoc.x = maxX; if(mouseLoc.x < minX)mouseLoc.x = minX; if(mouseLoc.y > maxY)mouseLoc.y = maxY; if(mouseLoc.y < minY)mouseLoc.y = minY; /* Now, find effective change in x and y */ dx=mouseLoc.x-oldMouse.x; dy=mouseLoc.y-oldMouse.y; /* Save mouse location for next time around */ oldMouse=mouseLoc; /* Finally, ask item to move as far as it can within the bounds of the view. */ [mousedObject moveBy:dx :dy inViewRect:&bounds]; /* Find out where it ended up */ [mousedObject getFrame:&newRect]; /* Compute dirty rectangle that needs redrawing */ NXUnionRect(&newRect,&dirtyRect); //replaces second rect with union /* Now time to draw in the view */ /* Erase dirty rectangle in the view*/ [bgImage composite:NX_COPY fromRect:&dirtyRect toPoint:&dirtyRect.origin]; /* For each object, redraw the portion that intersects the dirty rect. */ for (i=0; i<[itemList count]; i++) [[itemList objectAt:i] drawInDirtyRect:&dirtyRect]; [window flushWindow]; return self; } - mouseUpAction:(NXPoint *)location { [self unlockFocus]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.