home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1994 June / NEBULA_SE.ISO / SourceCode / Palettes / TTools / TToolsPalette / Ranker.subproj / Ranker.m < prev    next >
Encoding:
Text File  |  1993-11-10  |  4.1 KB  |  181 lines

  1. /* Ranker.m
  2.  * Written By:  Thomas Burkholder
  3.  *
  4.  * You may freely copy, distribute, and reuse the code in this example.
  5.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  6.  * fitness for any particular use.
  7.  */
  8.  
  9. #import "Ranker.h"
  10.  
  11. #define BOUND(__a,__low,__high) MIN(MAX((__a),(__low)),(__high))
  12.  
  13. @implementation Ranker
  14.  
  15. static BOOL dragging;
  16. static int rowDragged;
  17. static NXPoint currentMouse;
  18.  
  19. - initFrame:(const NXRect *)frameRect
  20. {
  21.     [super initFrame:frameRect];
  22.     dragging = NO;
  23.     rankMode = YES;
  24.     [self setMode:NX_TRACKMODE];
  25.     return self;
  26. }
  27.  
  28. - setRankMode:(BOOL)yn
  29. {
  30.     rankMode = yn;
  31.     return self;
  32. }
  33.  
  34. - (BOOL)rankMode
  35. {
  36.     return rankMode;
  37. }
  38.  
  39. - exchangeRow:(int)source with:(int)dest
  40. {
  41.     int i;
  42.     id a,b;
  43.  
  44.     for(i=0;(i<numCols);i++) {
  45.         a = [self cellAt:source :i];
  46.         b = [self cellAt:dest :i];
  47.         [self putCell:a at:dest :i];
  48.         [self putCell:b at:source :i];
  49.     }
  50.     return self;
  51. }
  52.  
  53. - mouseDown:(NXEvent *)theEvent
  54. {
  55.     NXRect r, bds;
  56.     int col, rowDropped;
  57.     float diff, offset;
  58.     NXEvent *ev;
  59.  
  60.     if (!rankMode || (!(theEvent->flags & NX_CONTROLMASK)))
  61.         return [super mouseDown:theEvent];
  62.  
  63.     [window getMouseLocation:¤tMouse];
  64.     [self convertPoint:¤tMouse fromView:nil];
  65.  
  66.     [self getRow:&rowDragged andCol:&col forPoint:¤tMouse];
  67.     if (rowDragged == -1) return [super mouseDown:theEvent];
  68.  
  69.     [window addToEventMask:NX_MOUSEDRAGGEDMASK];
  70.     [self getCellFrame:&r at:rowDragged :col];
  71.     offset = currentMouse.y - r.origin.y;
  72.     currentMouse.y -= offset;
  73.  
  74.     [window makeFirstResponder:window];
  75.     dragging = YES;
  76.     for(ev = theEvent;(ev->type!=NX_LMOUSEUP);) {
  77.         if (([self getVisibleRect:&r])&&
  78.                     ([[superview superview] isKindOf:[ScrollView class]])) {
  79.             diff = (currentMouse.y+cellSize.height) -
  80.                                                 (r.size.height+r.origin.y);
  81.             if  (diff > 0) {
  82.                 [superview getBounds:&bds];
  83.                 bds.origin.y += diff;
  84.                 [superview rawScroll:&(bds.origin)];
  85.                 [[superview superview] reflectScroll:superview];
  86.             } else {
  87.                 diff = (r.origin.y-currentMouse.y);
  88.                 if  (diff > 0) {
  89.                     [superview getBounds:&bds];
  90.                     bds.origin.y -= diff;
  91.                     [superview rawScroll:&(bds.origin)];
  92.                     [[superview superview] reflectScroll:superview];
  93.                 }
  94.             }
  95.         }
  96.  
  97.         [self displayFromOpaqueAncestor:&r :1 :YES];
  98.  
  99.         ev = [NXApp getNextEvent:NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
  100.         [window getMouseLocation:¤tMouse];
  101.         [self convertPoint:¤tMouse fromView:nil];
  102.         currentMouse.y -= offset;
  103.         currentMouse.y = BOUND(currentMouse.y, bounds.origin.y,
  104.                         (bounds.origin.y+bounds.size.height-cellSize.height));
  105.     }
  106.     dragging = NO;
  107.     [window removeFromEventMask:NX_MOUSEDRAGGEDMASK];
  108.  
  109.     diff = currentMouse.y;
  110.     currentMouse.y += (cellSize.height/2);
  111.     if (![self getRow:&rowDropped andCol:&col forPoint:¤tMouse]) {
  112.         currentMouse.y += (cellSize.height/4);
  113.         if (![self getRow:&rowDropped andCol:&col forPoint:¤tMouse]) {
  114.             NXLogError("Ranker:  Couldn't drop row.\n");
  115.             return [self display];
  116.         }
  117.     }
  118.  
  119.     [window disableFlushWindow];
  120.     if ((rowDropped==(numRows-1))&&(diff+cellSize.height>= bounds.size.height))
  121.         rowDropped++;
  122.     [self insertRowAt:rowDropped];
  123.     if (rowDropped < rowDragged)
  124.         rowDragged++;
  125.     if (selectedRow >= rowDropped)
  126.         selectedRow++;
  127.     if (selectedRow == rowDragged)
  128.         selectedRow = rowDropped;
  129.     [self exchangeRow:rowDragged with:rowDropped];
  130.     [self removeRowAt:rowDragged andFree:YES];
  131.     [self display];
  132.     [window reenableFlushWindow];
  133.     [window flushWindow];
  134.     return self;
  135. }
  136.  
  137. - drawSelf:(const NXRect *)rects :(int)rectCount
  138. {
  139.     NXRect r;
  140.     int i;
  141.  
  142.     if (!dragging)
  143.         return [super drawSelf:rects :rectCount];
  144.  
  145.     // draw ordinary matrix
  146.     [super drawSelf:rects :rectCount];
  147.  
  148.     PSgsave();
  149.     // draw well
  150.     PSsetgray([window backgroundGray]);
  151.     for(i=0;(i<numCols);i++) {
  152.         [self getCellFrame:&r at:rowDragged :i];
  153.         NXRectFill(&r);
  154.     }
  155.     PSgrestore();
  156.  
  157.     // draw dragging row
  158.     for(i=0;(i<numCols);i++) {
  159.         [self getCellFrame:&r at:rowDragged :i];
  160.         r.origin.y = currentMouse.y;
  161.         [[self cellAt:rowDragged :i] drawSelf:&r inView:self];
  162.     }
  163.     return self;
  164. }
  165.  
  166. - read:(NXTypedStream *)stream
  167. {
  168.     [super read:stream];
  169.     NXReadTypes(stream,"i",&rankMode);
  170.     return self;
  171. }
  172.  
  173. - write:(NXTypedStream *)stream
  174. {
  175.     [super write:stream];
  176.     NXWriteTypes(stream,"i",&rankMode);
  177.     return self;
  178. }
  179.  
  180. @end
  181.