Annotation of Examples/EnterpriseObjects/SHLExamples/Sorting/SlidingMatrix.m, revision 1.1.1.1

1.1       root        1: /*--------------------------------------------------------------------------
                      2:  *
                      3:  *     You may freely copy, distribute, and reuse the code in this example.
                      4:  *     SHL Systemhouse disclaims any warranty of any kind, expressed or  
                      5:  *     implied, as to its fitness for any particular use.
                      6:  *
                      7:  *
                      8:  *     SlidingMatrix
                      9:  *
                     10:  *     Inherits From:          Matrix
                     11:  *
                     12:  *     Conforms To:            None.
                     13:  *
                     14:  *     Declared In:            SlidingMatrix.h
                     15:  *
                     16:  *
                     17:  *------------------------------------------------------------------------*/
                     18: #import "SlidingMatrix.h"
                     19: 
                     20: 
                     21: static int                     rowDropped;
                     22: static int                     rowDragged;
                     23: static BOOL                    isDragging;
                     24: static NXPoint         currentMouse;
                     25: 
                     26: 
                     27: #define BOUND(__a,__low,__high) MIN(MAX((__a),(__low)),(__high))
                     28: 
                     29: 
                     30: 
                     31: 
                     32: @implementation SlidingMatrix
                     33: 
                     34: /*--------------------------------------------------------------------------
                     35:  *     Private Methods
                     36:  *------------------------------------------------------------------------*/
                     37: - _exchangeRowAt: (int) source with: (int) destination
                     38: {
                     39:        int     iterator;
                     40:        id      sourceCell, destinationCell;
                     41:        
                     42:        for (iterator = 0; iterator < numCols; iterator++)
                     43:                {
                     44:                sourceCell = [self cellAt: source : iterator];
                     45:                destinationCell = [self cellAt: destination : iterator];
                     46:                [self putCell: sourceCell  at: destination : iterator];
                     47:                [self putCell: destinationCell  at: source : iterator];
                     48:                }
                     49:                
                     50:        return self;
                     51: }
                     52: 
                     53: 
                     54: - _reflectScroll
                     55: {
                     56:        //  If in a ScrollView, reflect scroll if drag is beyond visibleRect...
                     57:        
                     58:        id                      scrollView = [superview superview];
                     59:        id                      clipView  = superview;
                     60:        NXRect          visibleRect, clipViewBoundsRect;
                     61:        NXCoord         delta;
                     62: 
                     63:        [self getVisibleRect: &visibleRect];
                     64:        delta = (currentMouse.y + cellSize.height) - (NX_HEIGHT (&visibleRect) + NX_Y 
                     65:                (&visibleRect));
                     66: 
                     67:        if (delta > 0.0)
                     68:                {
                     69:                [clipView getBounds: &clipViewBoundsRect];
                     70:                NX_Y (&clipViewBoundsRect) += delta;
                     71:                [clipView rawScroll: &clipViewBoundsRect.origin];
                     72:                [scrollView reflectScroll: clipView];
                     73:                }
                     74:        else
                     75:                {
                     76:                delta = NX_Y (&visibleRect) - currentMouse.y;
                     77:                if (delta > 0.0)
                     78:                        {
                     79:                        [clipView getBounds: &clipViewBoundsRect];
                     80:                        NX_Y (&clipViewBoundsRect) -= delta;
                     81:                        [clipView rawScroll: &clipViewBoundsRect.origin];
                     82:                        [scrollView reflectScroll: clipView];
                     83:                        }
                     84:                }
                     85: 
                     86:        return self;
                     87: }
                     88: 
                     89: 
                     90: - _reflectSlide
                     91: {
                     92:        //  Here's where we actually adjust the cells to reflect the slide.  Insert
                     93:        //  a new cell at the drop row (this moves any rows > than drop row by
                     94:        //  one).  Exchange the dragged cell with the newly inserted cell.  Remove
                     95:        //  the original dragged row. If user has dragged beyond last cell, add to
                     96:        //  end.
                     97:                
                     98:        int             rowDraggedOffset = 0;
                     99:        NXRect  rect;
                    100:        NXPoint mouseLocation;
                    101: 
                    102:        [window getMouseLocation: &mouseLocation];
                    103:        [self getBounds: &rect];
                    104:        [self convertRect: &rect  toView: nil];
                    105:        if (rowDropped == numRows -1  &&  mouseLocation.y < NX_Y (&rect))
                    106:                  rowDropped++;
                    107: 
                    108:        [window disableFlushWindow];
                    109: 
                    110:        [self insertRowAt: rowDropped];
                    111:        if (rowDropped < rowDragged)  {  rowDragged++;  rowDraggedOffset = 1;  }
                    112:        selectedRow = rowDropped;
                    113:        [self _exchangeRowAt: rowDragged  with: rowDropped];
                    114:        [self removeRowAt: rowDragged  andFree: YES];
                    115: 
                    116:        rowDragged -= rowDraggedOffset;
                    117: 
                    118:        [self display];
                    119:        [window reenableFlushWindow];
                    120:        [window flushWindow];
                    121:        return self;
                    122: }
                    123: 
                    124: 
                    125: - (BOOL) _notifyDelegateWillSlideFromRow: (int) sourceRow
                    126: {
                    127:        if (delegate  && [delegate respondsTo:
                    128:                        @selector (slidingMatrix:willSlideFromRow:)])
                    129:                return [delegate slidingMatrix: self  willSlideFromRow: sourceRow ];
                    130:                
                    131:        return YES;
                    132: }
                    133: 
                    134: 
                    135: - (BOOL) _notifyDelegateWillSlideToRow: (int) destinationRow
                    136: {
                    137:        if (delegate  &&  [delegate respondsTo:
                    138:                        @selector (slidingMatrix:willSlideToRow:)])
                    139:                return [delegate slidingMatrix: self  willSlideToRow: destinationRow];
                    140:                
                    141:        return YES;
                    142: }
                    143: 
                    144: 
                    145: - _notifyDelegateDidSlideFromRow: (int) sourceRow  toRow: (int) destinationRow
                    146: {
                    147:        if (delegate  &&  [delegate respondsTo:
                    148:                        @selector (slidingMatrix:didSlideFromRow:toRow:)])
                    149:                [delegate slidingMatrix:self didSlideFromRow:sourceRow 
                    150:                                toRow:destinationRow];
                    151:                
                    152:        return self;
                    153: }
                    154: 
                    155: 
                    156: /*--------------------------------------------------------------------------
                    157:  *     Initialization and Freeing
                    158:  *------------------------------------------------------------------------*/
                    159: - initFrame: (const NXRect*) frameRect
                    160: {
                    161:        id buttonCellPrototype = [[ButtonCell allocFromZone: [self zone]]
                    162:                        initTextCell:"empty"];
                    163:        [buttonCellPrototype setIconPosition:NX_ICONLEFT];
                    164:        [buttonCellPrototype setBordered:NO];
                    165:        [buttonCellPrototype setIcon:"empty"];
                    166:        [buttonCellPrototype setAlignment:NX_LEFTALIGNED];
                    167:        [buttonCellPrototype setType:NX_ONOFF];
                    168: 
                    169:        [super initFrame:(const NXRect *)frameRect mode:NX_RADIOMODE
                    170:                prototype:buttonCellPrototype numRows:0 numCols:0];
                    171: 
                    172:        return self;
                    173: }
                    174: 
                    175: 
                    176: /*--------------------------------------------------------------------------
                    177:  *     Accessing the deleagate
                    178:  *------------------------------------------------------------------------*/
                    179: - delegate
                    180: {
                    181:        return delegate;
                    182: }
                    183: 
                    184: 
                    185: - setDelegate: anObject
                    186: {
                    187:        delegate = anObject;
                    188:        return self;
                    189: }
                    190: 
                    191: 
                    192: /*--------------------------------------------------------------------------
                    193:  *     Event Handling
                    194:  *------------------------------------------------------------------------*/
                    195: - mouseDown: (NXEvent*) theEvent
                    196: {
                    197:        int                     column, originalEventMask;
                    198:        BOOL            scrollViewFlag;
                    199:        NXRect          cellFrame, visibleRect;
                    200:        NXCoord         offset;
                    201:        NXEvent*        nextEvent;
                    202: 
                    203:        //  Is user control-dragging...
                    204:        if ( ! (theEvent->flags & NX_CONTROLMASK))
                    205:                return [super mouseDown: theEvent];
                    206: 
                    207:        //  Is there a valid row under the mouse...
                    208:        currentMouse = theEvent->location;
                    209:        [self convertPoint: &currentMouse fromView: nil];
                    210:        [self getRow: &rowDragged  andCol: &column  forPoint: &currentMouse];
                    211:        if (rowDragged == -1)  return [super mouseDown: theEvent];
                    212:        if ([self _notifyDelegateWillSlideFromRow: rowDragged] == NO)
                    213:                return [super mouseDown: theEvent];
                    214:        [self selectCellAt: rowDragged : column];
                    215: 
                    216:        //  Calculate offset (difference between mouse hit y coord and
                    217:        //      cellFrame y coord).  
                    218:        [self getCellFrame: &cellFrame at: rowDragged : column];
                    219:        offset = currentMouse.y - NX_Y (&cellFrame);
                    220: 
                    221:        //  Adjust currentMouse.y to cell frame boundary.
                    222:        currentMouse.y -= offset;
                    223: 
                    224:        //  Prepare for event loop...
                    225:        [window makeFirstResponder: window];
                    226:        originalEventMask = [window addToEventMask: NX_MOUSEDRAGGEDMASK];
                    227:        scrollViewFlag = ([[superview superview] isKindOf:
                    228:                        [ScrollView class]] ? YES : NO);
                    229:        isDragging = YES;
                    230: 
                    231:        while (isDragging)
                    232:                {
                    233:                nextEvent = [NXApp getNextEvent:NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK];
                    234:                
                    235:                switch (nextEvent->type)
                    236:                        {
                    237:                        case NX_MOUSEDRAGGED:
                    238:                                isDragging = YES;
                    239:                                currentMouse = nextEvent->location;
                    240:                                [self convertPoint: &currentMouse  fromView: nil];
                    241:                                currentMouse.y -= offset;
                    242:                                currentMouse.y = BOUND (currentMouse.y, NX_Y (&bounds),
                    243:                                        (NX_Y (&bounds) + NX_HEIGHT (&bounds) - cellSize.height));
                    244:                                if  ([self getVisibleRect: &visibleRect]  &&  scrollViewFlag)
                    245:                                        [self _reflectScroll];
                    246:                                [self displayFromOpaqueAncestor: &visibleRect  :1  :YES];
                    247:                                break;
                    248: 
                    249:                        case NX_MOUSEUP:
                    250:                                isDragging = NO;
                    251:                                currentMouse.y += cellSize.height / 2.0;
                    252: 
                    253:                                if ( ! [self getRow:&rowDropped andCol:&column
                    254:                                                forPoint:&currentMouse])
                    255:                                        {
                    256:                                        currentMouse.y += cellSize.height  / 4.0;
                    257:                                        if ( ! [self getRow:&rowDropped andCol:&column
                    258:                                                forPoint:&currentMouse])
                    259:                                                break;
                    260:                                        }
                    261:        
                    262:                                if ([self _notifyDelegateWillSlideToRow: rowDropped])
                    263:                                        {
                    264:                                        [self _reflectSlide];
                    265:                                        [self selectCellAt: rowDropped : column];
                    266:                                        [self _notifyDelegateDidSlideFromRow:rowDragged 
                    267:                                                toRow:rowDropped];
                    268:                                        }
                    269:        
                    270:                                break;
                    271:                        }
                    272:                }  
                    273:        
                    274:        [self display];
                    275:        [window setEventMask: originalEventMask];
                    276:        return self;
                    277: }
                    278: 
                    279: 
                    280: /*--------------------------------------------------------------------------
                    281:  *     Drawing Methods
                    282:  *------------------------------------------------------------------------*/
                    283: - drawSelf: (const NXRect*)rects : (int) rectCount
                    284: {
                    285:        int             iterator;
                    286:        NXRect  rect;
                    287: 
                    288:        if (! isDragging)  return [super drawSelf: rects  : rectCount];
                    289: 
                    290:        [super drawSelf: rects  : rectCount];
                    291: 
                    292:        PSgsave ();
                    293:        PSsetgray ([window backgroundGray]);
                    294:        for (iterator = 0;  iterator < numCols; iterator++) 
                    295:                {
                    296:                [self getCellFrame: &rect  at: rowDragged : iterator];
                    297:                NXRectFill (&rect);
                    298:                }
                    299:        PSgrestore();
                    300: 
                    301: 
                    302:        for (iterator = 0;  iterator < numCols; iterator++) 
                    303:                {
                    304:                [self getCellFrame: &rect  at: rowDragged  : iterator];
                    305:                NX_Y (&rect) = currentMouse.y;
                    306:                [[self cellAt: rowDragged : iterator]  drawSelf: &rect  inView: self];
                    307:                }
                    308:                
                    309:        return self;
                    310: }
                    311: 
                    312: 
                    313: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.