home *** CD-ROM | disk | FTP | other *** search
- /* Ranker.m
- * Written By: Thomas Burkholder
- *
- * You may freely copy, distribute, and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to its
- * fitness for any particular use.
- */
-
- #import "Ranker.h"
-
- #define BOUND(__a,__low,__high) MIN(MAX((__a),(__low)),(__high))
-
- @implementation Ranker
-
- static BOOL dragging;
- static int rowDragged;
- static NXPoint currentMouse;
-
- - initFrame:(const NXRect *)frameRect
- {
- [super initFrame:frameRect];
- dragging = NO;
- rankMode = YES;
- [self setMode:NX_TRACKMODE];
- return self;
- }
-
- - setRankMode:(BOOL)yn
- {
- rankMode = yn;
- return self;
- }
-
- - (BOOL)rankMode
- {
- return rankMode;
- }
-
- - exchangeRow:(int)source with:(int)dest
- {
- int i;
- id a,b;
-
- for(i=0;(i<numCols);i++) {
- a = [self cellAt:source :i];
- b = [self cellAt:dest :i];
- [self putCell:a at:dest :i];
- [self putCell:b at:source :i];
- }
- return self;
- }
-
- - mouseDown:(NXEvent *)theEvent
- {
- NXRect r, bds;
- int col, rowDropped;
- float diff, offset;
- NXEvent *ev;
-
- if (!rankMode || (!(theEvent->flags & NX_CONTROLMASK)))
- return [super mouseDown:theEvent];
-
- [window getMouseLocation:¤tMouse];
- [self convertPoint:¤tMouse fromView:nil];
-
- [self getRow:&rowDragged andCol:&col forPoint:¤tMouse];
- if (rowDragged == -1) return [super mouseDown:theEvent];
-
- [window addToEventMask:NX_MOUSEDRAGGEDMASK];
- [self getCellFrame:&r at:rowDragged :col];
- offset = currentMouse.y - r.origin.y;
- currentMouse.y -= offset;
-
- [window makeFirstResponder:window];
- dragging = YES;
- for(ev = theEvent;(ev->type!=NX_LMOUSEUP);) {
- if (([self getVisibleRect:&r])&&
- ([[superview superview] isKindOf:[ScrollView class]])) {
- diff = (currentMouse.y+cellSize.height) -
- (r.size.height+r.origin.y);
- if (diff > 0) {
- [superview getBounds:&bds];
- bds.origin.y += diff;
- [superview rawScroll:&(bds.origin)];
- [[superview superview] reflectScroll:superview];
- } else {
- diff = (r.origin.y-currentMouse.y);
- if (diff > 0) {
- [superview getBounds:&bds];
- bds.origin.y -= diff;
- [superview rawScroll:&(bds.origin)];
- [[superview superview] reflectScroll:superview];
- }
- }
- }
-
- [self displayFromOpaqueAncestor:&r :1 :YES];
-
- ev = [NXApp getNextEvent:NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
- [window getMouseLocation:¤tMouse];
- [self convertPoint:¤tMouse fromView:nil];
- currentMouse.y -= offset;
- currentMouse.y = BOUND(currentMouse.y, bounds.origin.y,
- (bounds.origin.y+bounds.size.height-cellSize.height));
- }
- dragging = NO;
- [window removeFromEventMask:NX_MOUSEDRAGGEDMASK];
-
- diff = currentMouse.y;
- currentMouse.y += (cellSize.height/2);
- if (![self getRow:&rowDropped andCol:&col forPoint:¤tMouse]) {
- currentMouse.y += (cellSize.height/4);
- if (![self getRow:&rowDropped andCol:&col forPoint:¤tMouse]) {
- NXLogError("Ranker: Couldn't drop row.\n");
- return [self display];
- }
- }
-
- [window disableFlushWindow];
- if ((rowDropped==(numRows-1))&&(diff+cellSize.height>= bounds.size.height))
- rowDropped++;
- [self insertRowAt:rowDropped];
- if (rowDropped < rowDragged)
- rowDragged++;
- if (selectedRow >= rowDropped)
- selectedRow++;
- if (selectedRow == rowDragged)
- selectedRow = rowDropped;
- [self exchangeRow:rowDragged with:rowDropped];
- [self removeRowAt:rowDragged andFree:YES];
- [self display];
- [window reenableFlushWindow];
- [window flushWindow];
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- NXRect r;
- int i;
-
- if (!dragging)
- return [super drawSelf:rects :rectCount];
-
- // draw ordinary matrix
- [super drawSelf:rects :rectCount];
-
- PSgsave();
- // draw well
- PSsetgray([window backgroundGray]);
- for(i=0;(i<numCols);i++) {
- [self getCellFrame:&r at:rowDragged :i];
- NXRectFill(&r);
- }
- PSgrestore();
-
- // draw dragging row
- for(i=0;(i<numCols);i++) {
- [self getCellFrame:&r at:rowDragged :i];
- r.origin.y = currentMouse.y;
- [[self cellAt:rowDragged :i] drawSelf:&r inView:self];
- }
- return self;
- }
-
- - read:(NXTypedStream *)stream
- {
- [super read:stream];
- NXReadTypes(stream,"i",&rankMode);
- return self;
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteTypes(stream,"i",&rankMode);
- return self;
- }
-
- @end
-