This is DocView.m in view mode; [Download] [Up]
/* * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * (b) If this Sample Code is distributed as part of the Display PostScript * System Software Development Kit from Adobe Systems Incorporated, * then this copy is designated as Development Software and its use is * subject to the terms of the License Agreement attached to such Kit. * * (c) If this Sample Code is distributed independently, then the following * terms apply: * * (d) This file may be freely copied and redistributed as long as: * 1) Parts (a), (d), (e) and (f) continue to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * (e) PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED. * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY) * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. */ /* * DocView.m * * This class handles the scaling of the drawing view. It repositions * The drawing view within itself if the drawing view is smaller than the * size of the clip view. The size of the doc view is: * MAX(clip view frame, drawing view frame). * * Version: 2.0 * Author: Ken Fromm * History: * 03-07-91 Added this comment. */ #import "DocView.h" #import <appkit/NXCursor.h> #import <appkit/NXImage.h> #import <appkit/Matrix.h> #import <appkit/ScrollView.h> #import <dpsclient/wraps.h> #import <appkit/nextstd.h> @implementation DocView /* * Since there is only one subview its easier to keep track of it as an * instance variable rather than in the subview list. Returns any the * previous drawing view. */ - setDrawView:aView { id oldView; oldView = drawviewId; [oldView removeFromSuperview]; [self addSubview:aView]; drawviewId = aView; return oldView; } - drawView { return drawviewId; } - setZoomControl:anObject { zoomControl = anObject; return self; } - zoomControl { return zoomControl; } - setHitSetting:(float) value { hitsetting = value; return self; } /* * Scale the hit setting. Using an unscaled hit setting would be like * using a boxing glove on a 400% scale. */ - (float) hitSetting { return hitsetting * (1.0/scale); } - setScale:(float)value { scale = value; return self; } - (float) scale { return scale; } - setZooming:(BOOL)flag { zooming = flag; return self; } - (BOOL) isZooming { return zooming; } /* * This method is overridden from the View class. When the * user is zooming the cursor rect for the zoom cursor is set * the the frame of the drawing view. */ - resetCursorRects { NXPoint hotspot; NXRect cursorRect, visRect; if (zooming) { if (!zoomCursor) { hotspot.x = hotspot.y = 8.0; zoomCursor = [NXCursor newFromImage:[NXImage newFromSection:"zoom.tiff"]]; [zoomCursor setHotSpot:&hotspot]; } [self getVisibleRect:&visRect]; [drawviewId getFrame:&cursorRect]; NXIntersectionRect(&visRect, &cursorRect); [self addCursorRect:&cursorRect cursor:zoomCursor]; } return self; } /* * Messaged from the zoom matrix. Starts the zoom loop. At the next * mouse down in the drawing view, the scaleDrawView:toPoint: method * will be called. */ - zoom:sender { [self setZooming:YES]; [self setZoomControl:sender]; [self resetCursorRects]; [window makeKeyAndOrderFront:self]; return self; } /* * Sizes the drawing view from the old scale to the newscale. * The frame of the view is used instead of the bounds because * the bound will always be the same whereas the frame will * provide the size in default coordinates. */ - sizeDrawViewWithScale:(float) newscale { float scalefactor, sizewidth, sizeheight; NXRect viewFrame; [drawviewId getFrame:&viewFrame]; scalefactor = newscale/scale; sizewidth = viewFrame.size.width*scalefactor; sizeheight = viewFrame.size.height*scalefactor; [drawviewId sizeTo:rint(sizewidth) :rint(sizeheight)]; return self; } /* * Scales the drawing view from the old scale to the new scale. * The scale method is relative so we use the ratio * of the old scale to the new scale to obtain the scaling factor. */ - scaleDrawViewWithScale:(float) newscale { float scalefactor; scalefactor = newscale/scale; [drawviewId scale:scalefactor :scalefactor]; return self; } /* * Place the view passed in in the center of the doc view * if it is smaller than the size of the ClipView. Two passes are made * through the loop because adding or removing a horizontal or * vertical scrollbar will affect the size of the remaining dimension . */ - placeDrawView { float margin; NXSize contSize, newSize, insetSize, delta; NXRect viewFrame; margin = 4 * OFFSET * scale; [drawviewId getFrame:&viewFrame]; [[superview superview] getContentSize:&contSize]; newSize.width = MAX(viewFrame.size.width, contSize.width); newSize.height = MAX(viewFrame.size.height, contSize.height); delta.width = newSize.width - viewFrame.size.width; delta.height = newSize.height - viewFrame.size.height; if (delta.width != 0.0 || delta.height != 0.0) { if (delta.width < margin) newSize.width += margin - delta.width; if (delta.height < margin) newSize.height += margin - delta.height; } [self sizeTo:newSize.width :newSize.height]; insetSize.width = floor((newSize.width - viewFrame.size.width)/2); insetSize.height = floor((newSize.height - viewFrame.size.height)/2); [drawviewId moveTo:insetSize.width :insetSize.height]; if (insetSize.width != 0 || insetSize.height != 0) [drawviewId setClipping:YES]; else [drawviewId setClipping:NO]; return self; } /* * Scales the view to the tag of the selected matrix cell and then * scrolls to the point. The point is in window coordinates so * it must be converted to the drawing view coordinates in order * to position it in the same relative place in the view. */ - scaleDrawViewToPoint:(NXPoint *) p; { float newscale; NXPoint viewPt; [window invalidateCursorRectsForView:self]; newscale = [zoomControl selectedTag] * 0.01; if (drawviewId && newscale != scale) { viewPt = *p; [drawviewId convertPoint:&viewPt fromView:nil]; [window disableDisplay]; /* Size and then scale the drawing view. The frame of the */ /* drawing view must reflect the changed size. Scaling */ /* alone will not change the frame. */ [self sizeDrawViewWithScale:newscale]; [self scaleDrawViewWithScale:newscale]; [self setScale:newscale]; [self placeDrawView]; [self scrollDrawPoint:&viewPt toWindowPoint:p]; [window reenableDisplay]; [[window contentView] display]; } [self setZooming:NO]; return self; } /* * Use the point location relative to the window versus the point relative * to the drawing view (before the scale) to determine where to scroll * the drawing view. We want the same location in the drawing view to * appear where the mouse downed occurred. The window coordinates * are used and then adjusted by the position of the scrolling frame * because the presence or absence of scrollbars throws the use * of the doc views coordinates awry. */ - scrollDrawPoint:(const NXPoint *) aPt toWindowPoint:(const NXPoint *) windowPt { NXPoint viewPt, scrollPt; NXRect clipFrame, visRect; [superview getFrame:&clipFrame]; if (frame.size.width > clipFrame.size.width || frame.size.height > clipFrame.size.height) { viewPt = *aPt; [drawviewId convertPointToSuperview:&viewPt]; scrollPt = *windowPt; [self convertPoint:&scrollPt fromView:nil]; [self getVisibleRect:&visRect]; viewPt.x -= (scrollPt.x - visRect.origin.x); viewPt.y -= (scrollPt.y - visRect.origin.y); [self scrollPoint:&viewPt]; } return self; } /* * This drawSelf method draws a border around the drawing view as well as a * drop shadow. This is only done if it will be visible however. We tell if it is visible * if the rectangle passed in is not contained entirely within drawingView frame. */ - drawSelf:(NXRect *)r :(int) count { NXRect drawRect, dropRect, bRect, xRect, yRect; /* Calculate the rectangle of the draw view plus its drop shadow. */ [drawviewId getFrame:&drawRect]; dropRect = bRect = drawRect; NXOffsetRect(&bRect, -rint(LINEWIDTH/2 * scale), -rint(LINEWIDTH/2 * scale)); NXOffsetRect(&dropRect, rint(OFFSET * scale), rint(-OFFSET * scale)); NXUnionRect(&dropRect, &bRect); if (!NXContainsRect(&bRect, r)) { bRect = xRect = yRect = dropRect; NXIntersectionRect(&drawRect, &bRect); NXDivideRect(&xRect, &dropRect, bRect.size.width, 0); NXDivideRect(&yRect, &dropRect, bRect.size.height, 3); PSgsave(); PSsetgray(NX_BLACK); PSrectclip(r->origin.x, r->origin.y, r->size.width, r->size.height); PSrectfill(xRect.origin.x, xRect.origin.y, xRect.size.width, xRect.size.height); PSrectfill(yRect.origin.x, yRect.origin.y, yRect.size.width, yRect.size.height); PSsetlinewidth(LINEWIDTH * scale); PSrectstroke(drawRect.origin.x, drawRect.origin.y, drawRect.size.width, drawRect.size.height); PSgrestore(); } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.