home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
- /*
- Augmented by Slugg Jello,
- Mouthing Flowers
- 152 20th Ave. #1
- Seattle, WA. 98112
- slugg@mouthers.nwnexus.wa.com
- */
-
- #import "Rubberband.h"
- #import <appkit/Window.h>
- #import <appkit/View.h>
- #import <appkit/Application.h>
- #import <appkit/appkit.h>
- #include "Rubber.h" // psw stuff
- #include <math.h>
-
- #define DRAG_MASK (NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK)
- //#define DEBUG_OUTPUT
- #define RUBBERBAND_WINDOW_WIDTH 1
-
- @implementation Rubberband
-
- /***** PRIVATE METHODS *****/
-
- - (void)correctRect :(NXRect *)rect
- {
- /* make sure it makes sense to NX routines which don't like negative
- size values */
- if (rect->size.width < 0.0)
- {
- rect->origin.x += rect->size.width;
- rect->size.width = -rect->size.width;
- }
- if (rect->size.height < 0.0)
- {
- rect->origin.y += rect->size.height;
- rect->size.height = -rect->size.height;
- }
- }
-
- - setPosition
- /* Position and draw rubberband. Assumes currentRect is set and rubberband
- windows are initialized. Also assumes currentRect is 'corrected'. */
- {
- struct
- {
- NXRect top,left,bottom,right;
- } points;
-
- NXRect tRect,screenRect=currentRect;
-
- [[myView window] convertBaseToScreen :&screenRect.origin];
-
- /**** set size of each rubberband side ****/
-
- /* left */
- tRect = screenRect;
- tRect.size.width = RUBBERBAND_WINDOW_WIDTH;
- tRect.size.height = MAX(RUBBERBAND_WINDOW_WIDTH,screenRect.size.height);
- points.left = tRect;
-
- /* right */
- tRect.origin.x += screenRect.size.width - 1.0;
- points.right = tRect;
-
- /* bottom */
- tRect = screenRect;
- tRect.origin.x += 1.0;
- tRect.size.width = MAX(RUBBERBAND_WINDOW_WIDTH,screenRect.size.width-1.0);
- tRect.size.height = RUBBERBAND_WINDOW_WIDTH;
- points.bottom = tRect;
-
- /* top */
- tRect.origin.y += screenRect.size.height - 1.0;
- points.top = tRect;
-
- /* this'll erase old one and draw new one in new position */
- PSWPositionRect((float *)&points);
-
- return self;
- }
-
-
- /***** PUBLIC METHODS *****/
-
- - initWithView :aView
- {
- [self init];
- [self setView :aView];
- return self;
- }
-
- - init
- {
- [super init];
- myView = nil;
-
- [self setPivot :RB_CORNER];
- [self setInclusive :TRUE];
-
- return self;
- }
-
- - setView :aView
- /* returns previous myView, sets bounds to those of aView */
- {
- id oldView = myView;
- NXRect rect;
-
- if (aView == nil)
- {
- [self setBounds :NULL];
- return oldView;
- }
-
- myView = aView;
-
- #if defined(DEBUG_OUTPUT)
- fprintf(stderr,"view == %p\n",myView);
- #endif
-
- [myView getBounds :&rect];
- [self setBounds:&rect];
-
- return oldView;
- }
-
-
- - doStretch :(NXEvent *)event
- /* stretch the rubber band until user lets go of mouse */
- {
- int oldMask;
- NXEvent *nextEvent;
- NXPoint mouseLocation;
- NXPoint pivotPt;
- NXRect tRect;
-
- if (myView == nil)
- return self;
-
- #if defined(DEBUG_OUTPUT)
- fprintf(stderr,"we's a trackin\n");
- #endif
-
- currentRect.origin = event->location;
- currentRect.size.width = currentRect.size.height = 0.0;
-
- if (flags.useBounds)
- /* do nothing if first click isn't in bounds */
- if (![myView mouse :¤tRect.origin inRect:&boundsRect])
- return self;
-
-
- mouseLocation = event->location;
-
- /* we want to grab mouse dragged events */
- oldMask = [[myView window] addToEventMask:NX_MOUSEDRAGGEDMASK];
-
- if (flags.pivot == RB_CENTER)
- pivotPt = currentRect.origin;
-
- PSWInitRubberband();
-
- [self setPosition];
-
- PSWMakeVisible(TRUE);
-
- /* start our event loop, looking for mouse-dragged or mouse-up events */
- nextEvent = [NXApp getNextEvent:DRAG_MASK];
-
- tRect = currentRect;
-
- while (nextEvent->type != NX_MOUSEUP)
- {
- if (flags.pivot == RB_CORNER)
- {
- tRect.size.width += nextEvent->location.x - mouseLocation.x;
- tRect.size.height += nextEvent->location.y - mouseLocation.y;
- }
- else
- {
- tRect.size.width +=
- (nextEvent->location.x - mouseLocation.x) * 2;
- tRect.size.height +=
- (nextEvent->location.y - mouseLocation.y) * 2;
- tRect.origin.x = pivotPt.x - tRect.size.width / 2;
- tRect.origin.y = pivotPt.y - tRect.size.height / 2;
- }
-
- currentRect = tRect;
- [self correctRect :¤tRect];
-
- if (flags.useBounds)
- NXIntersectionRect(&boundsRect,¤tRect);
- NXIntegralRect(¤tRect);
-
- mouseLocation = nextEvent->location;
-
- [self setPosition];
-
- #if defined(DEBUG_OUTPUT)
- fprintf(stderr,
- "current rect: origin (%3.2lf,%3.2lf), size (%3.2lf,%3.2lf)\n",
- currentRect.origin.x,currentRect.origin.y,
- currentRect.size.width,currentRect.size.height);
- #endif
-
- nextEvent = [NXApp getNextEvent:DRAG_MASK];
- }
-
- /* reset the event mask */
- [[myView window] setEventMask:oldMask];
-
- #if defined(DEBUG_OUTPUT)
- fprintf(stderr,"we's a done trackin\n");
- #endif
-
- PSWMakeVisible(FALSE);
-
- return self;
- }
-
- - currentRect :(NXRect *)rect
- /* return currentRect in rect in View coords */
- {
- if (!rect)
- return self;
-
- *rect = currentRect;
-
- if (!flags.inclusive)
- {
- ++rect->origin.x;
- ++rect->origin.y;
- rect->size.width -= 2.0;
- rect->size.height -= 2.0;
- }
-
- /* convert from Window to View coords */
- [myView convertRect:rect fromView:nil];
-
- return self;
- }
-
- - bounds :(NXRect *)rect
- /* return boundsRect in rect in View coords */
- {
- if (!rect)
- return self;
-
- *rect = boundsRect;
-
- /* convert from Window to View coords */
- [myView convertRect:rect fromView:nil];
-
- return self;
- }
-
- - setBounds :(const NXRect *)rect
- /* set boundaries within which the rubberband may be dragged.
- rect is in myView coords. if rect is NULL, then no bounds. */
- {
- if (rect == NULL)
- {
- flags.useBounds = FALSE;
- return self;
- }
-
- flags.useBounds = TRUE;
- boundsRect = *rect;
-
- /* convert from View to Window coords */
- [myView convertRect:&boundsRect toView:nil];
-
- #if defined(DEBUG_OUTPUT)
- fprintf(stderr,"bounds: origin (%f %f) size (%f %f)\n",boundsRect.origin.x,
- boundsRect.origin.y,boundsRect.size.width,boundsRect.size.height);
- #endif
-
- return self;
- }
-
-
- - setCurrentRectToBounds;
- {
- flags.useBounds = TRUE;
- boundsRect = currentRect;
- return self;
- }
-
- - (int)setPivot :(int)pivot
- {
- int oldPivot = flags.pivot;
- flags.pivot = pivot;
- #if defined(DEBUG_OUTPUT)
- fprintf(stderr,"pivot == %s\n",
- flags.pivot == RB_CORNER ? "CORNER":"CENTER");
- #endif
-
- return oldPivot;
- }
-
- - (BOOL)setInclusive:(BOOL)onoff
- {
- BOOL bPrev = flags.inclusive;
- flags.inclusive = onoff;
- return bPrev;
- }
-
-
- @end
-