home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / YellowBox / Kits / MiscTableScroll-138.1 / Palettes / MiscTableScroll / Framework / MiscTableViewCursor.M < prev    next >
Encoding:
Text File  |  1998-03-31  |  11.1 KB  |  374 lines

  1. //=============================================================================
  2. //
  3. //  Copyright (C) 1995,1996,1997,1998 by Paul S. McCarthy and Eric Sunshine.
  4. //        Written by Paul S. McCarthy and Eric Sunshine.
  5. //                All Rights Reserved.
  6. //
  7. //    This notice may not be removed from this source code.
  8. //
  9. //    This object is included in the MiscKit by permission from the authors
  10. //    and its use is governed by the MiscKit license, found in the file
  11. //    "License.rtf" in the MiscKit distribution.  Please refer to that file
  12. //    for a list of all applicable permissions and restrictions.
  13. //
  14. //=============================================================================
  15. //-----------------------------------------------------------------------------
  16. // MiscTableViewCursor.M
  17. //
  18. //    Keyboard cursor methods for MiscTableView.
  19. //
  20. // FIXME: The PostScript pattern used to draw the dotted "keyboard focus" 
  21. //    rectangle gets "out-of-phase" as this view scrolls.  Consequently it 
  22. //    does not tile correctly.  The Adobe Purple Book section 10.4.4 implies 
  23. //    that the pattern has to be recreated each time the view changes.  (I 
  24. //    forsee using -initGState for this.) As an alternative, consider using 
  25. //    NSDottedFrameRect() which is available under OPENSTEP 4.2, but not 4.1.
  26. //
  27. //-----------------------------------------------------------------------------
  28. //-----------------------------------------------------------------------------
  29. // $Id: MiscTableViewCursor.M,v 1.2 98/03/29 23:59:05 sunshine Exp $
  30. // $Log:    MiscTableViewCursor.M,v $
  31. // Revision 1.2  98/03/29  23:59:05  sunshine
  32. // v138.1: #import was missing "MiscTableScroll/" for public header.
  33. // 
  34. // Revision 1.1  97/11/23  07:41:54  sunshine
  35. // v130.1: Keyboard cursor methods.
  36. //-----------------------------------------------------------------------------
  37. #import <MiscTableScroll/MiscTableScroll.h>
  38. #import "MiscTableViewPrivate.h"
  39. #import "MiscTableBorder.h"
  40. #import "MiscMouseTracker.h"
  41.  
  42. extern "Objective-C" {
  43. #import <AppKit/NSFontManager.h>
  44. }
  45. extern "C" {
  46. #import "MiscTableViewPS.h"
  47. #import <math.h>    // floor()
  48. }
  49.  
  50. int const NUM_EDGES = 4;    // 4 edges to draw per focus rectangle
  51. int const NUM_COORDS = 4;    // 4 coords per rectangle (x,y,w,h)
  52. int const MAX_COORDS = NUM_EDGES * NUM_COORDS;    // 16 coords per 4 rects
  53.  
  54. //-----------------------------------------------------------------------------
  55. // init_pswrap
  56. //-----------------------------------------------------------------------------
  57. static inline void init_pswrap()
  58.     {
  59.     static initialized = NO;
  60.     if (!initialized)
  61.     {
  62.     initialized = YES;
  63.     MISC_TV_initps();
  64.     }
  65.     }
  66.  
  67.  
  68. @implementation MiscTableView(Cursor)
  69. //=============================================================================
  70. // CURSOR DRAWING
  71. //=============================================================================
  72. - (BOOL)isCursorEnabled    { return (inhibitCursor == 0); }
  73. - (void)disableCursor    { inhibitCursor++; }
  74. - (void)enableCursor    { inhibitCursor--; }
  75.  
  76.  
  77. //-----------------------------------------------------------------------------
  78. // - shouldDrawCursor
  79. //-----------------------------------------------------------------------------
  80. - (BOOL)shouldDrawCursor
  81.     {
  82.     NSWindow* w = [self window];
  83.     return ([self isCursorEnabled] && [self canDraw] && [w isKeyWindow] &&
  84.         [w firstResponder] == self);
  85.     }
  86.  
  87.  
  88. //-----------------------------------------------------------------------------
  89. // - getCursorSlot
  90. //-----------------------------------------------------------------------------
  91. - (MiscCoord_V)getCursorSlot
  92.     {
  93.     MiscTableBorder* const b = [self borderFor:trackerBorder];
  94.     MiscCoord_V vslot = b->getCursor();
  95.     int const lim = b->count();
  96.     if (lim > 0 && (vslot < 0 || vslot >= lim))
  97.     {
  98.     vslot = b->selectedSlot();
  99.     if (vslot < 0)
  100.         vslot = b->physicalToVisual([self firstVisibleSlot:trackerBorder]);
  101.     NSParameterAssert( 0 <= vslot );
  102.     NSParameterAssert( vslot < lim );
  103.     b->setCursor( vslot );
  104.     }
  105.     return vslot;
  106.     }
  107.  
  108.  
  109. //-----------------------------------------------------------------------------
  110. // - getCursorFrame:
  111. //-----------------------------------------------------------------------------
  112. - (NSRect)getCursorFrame:(NSRect)clip
  113.     {
  114.     NSRect ret = NSZeroRect;
  115.     if (rowBorder->count() > 0 && colBorder->count() > 0)
  116.     {
  117.     MiscTableBorder* const b = [self borderFor:trackerBorder];
  118.     MiscCoord_P const pslot = b->visualToPhysical( [self getCursorSlot] );
  119.     if (pslot >= 0)
  120.         {
  121.         NSRect r = [self getSlotInsideAt:pslot from:trackerBorder];
  122.         if (NSIntersectsRect( r, clip ))
  123.         ret = r;
  124.         }
  125.     }
  126.     return ret;
  127.     }
  128.  
  129.  
  130. //-----------------------------------------------------------------------------
  131. // - getCursorEdges:clipTo:
  132. //
  133. //    Compute rectangles for drawing which make up the edges of the "focus
  134. //    frame".  Each edge is composed of values from the focus frame,
  135. //    possibly including its: X, Y, MAXX, MAXY.
  136. //-----------------------------------------------------------------------------
  137. - (int)getCursorEdges:(NSRect*)edges clipTo:(NSRect)clip
  138.     {
  139.     struct TV_Lines { char xs, maxxs, xc, ys, maxys, yc, ws, wc, hs, hc; };
  140.     static TV_Lines const LINES[ NUM_EDGES ] =
  141.     {
  142.         { 1, 0,  0, 1, 0,  0, 1,  0, 0,  1 }, // top
  143.         { 1, 0,  0, 0, 1, -1, 1,  0, 0,  1 }, // bottom
  144.         { 1, 0,  0, 1, 0,  1, 0,  1, 1, -2 }, // left
  145.         { 0, 1, -1, 1, 0,  1, 0,  1, 1, -2 }, // right
  146.     };
  147.  
  148.     NSRect* edge = edges;
  149.     NSRect rCursor = [self getCursorFrame:clip];
  150.     if (!NSIsEmptyRect( rCursor ))
  151.     {
  152.     for (int i = 0; i < NUM_EDGES; i++)
  153.         {
  154.         TV_Lines const& l = LINES[i];
  155.         NSRect r = NSMakeRect(
  156.             l.xs * NSMinX(rCursor) + l.maxxs * NSMaxX(rCursor) + l.xc,
  157.             l.ys * NSMinY(rCursor) + l.maxys * NSMaxY(rCursor) + l.yc,
  158.             l.ws * NSWidth(rCursor) + l.wc,
  159.             l.hs * NSHeight(rCursor) + l.hc );
  160.         r = NSIntersectionRect( clip, r );
  161.         if (!NSIsEmptyRect(r))
  162.         *edge++ = r;
  163.         }
  164.     }
  165.     return (edge - edges);
  166.     }
  167.  
  168.  
  169. //-----------------------------------------------------------------------------
  170. // - getCursorCoords:clipTo:
  171. //-----------------------------------------------------------------------------
  172. - (int)getCursorCoords:(float*)coords clipTo:(NSRect)in_clip
  173.     {
  174.     int num_coords = 0;
  175.  
  176.     NSRect clip;
  177.     if (NSIsEmptyRect( in_clip ))
  178.     clip = [self visibleRect];
  179.     else
  180.     clip = in_clip;
  181.  
  182.     NSRect edges[ NUM_EDGES ];
  183.     int const num_edges = [self getCursorEdges:edges clipTo:clip];
  184.     if (num_edges > 0)
  185.     {
  186.     float* p = coords;
  187.     for (int i = 0; i < num_edges; i++)
  188.         {
  189.         NSRect const& edge = edges[i];
  190.         *p++ = NSMinX( edge );
  191.         *p++ = NSMinY( edge );
  192.         *p++ = NSWidth( edge );
  193.         *p++ = NSHeight( edge );
  194.         }
  195.     num_coords = num_edges * NUM_COORDS;
  196.     }
  197.     return num_coords;
  198.     }
  199.  
  200.  
  201. //-----------------------------------------------------------------------------
  202. // - drawCursorCoords:count:
  203. //-----------------------------------------------------------------------------
  204. - (void)drawCursorCoords:(float const*)coords count:(int)n
  205.     {
  206.     init_pswrap();
  207.     BOOL needsFocus = ([NSView focusView] != self);
  208.     if (needsFocus) [self lockFocus];
  209.     MISC_TV_dashedrects( coords, n );
  210.     if (needsFocus) [self unlockFocus];
  211.     }
  212.  
  213.  
  214. //-----------------------------------------------------------------------------
  215. // - drawCursorClipTo:
  216. //-----------------------------------------------------------------------------
  217. - (void)drawCursorClipTo:(NSRect)clip
  218.     {
  219.     if ([self isCursorEnabled])
  220.     {
  221.     float coords[ MAX_COORDS ];
  222.     int const num_coords = [self getCursorCoords:coords clipTo:clip];
  223.     if (num_coords > 0)
  224.         {
  225.         [self drawCursorCoords:coords count:num_coords];
  226.         cursorSlot = [self borderFor:trackerBorder]->getCursor();
  227.         }
  228.     }
  229.     }
  230.  
  231.  
  232. //-----------------------------------------------------------------------------
  233. // - drawCursor
  234. //-----------------------------------------------------------------------------
  235. - (void)drawCursor
  236.     {
  237.     [self drawCursorClipTo:NSZeroRect];
  238.     }
  239.  
  240.  
  241. //-----------------------------------------------------------------------------
  242. // - eraseCursor
  243. //-----------------------------------------------------------------------------
  244. - (void)eraseCursor
  245.     {
  246.     if ([self isCursorEnabled])
  247.     {
  248.     MiscTableBorder* const b = [self borderFor:trackerBorder];
  249.     if (cursorSlot >= 0 && cursorSlot < b->count())
  250.         {
  251.         [self disableCursor];
  252.  
  253.         MiscCoord_P s = b->visualToPhysical( cursorSlot );
  254.         if (trackerBorder == MISC_COL_BORDER)
  255.         [self drawColumn:s];
  256.         else
  257.         [self drawRow:s];
  258.  
  259.         [self enableCursor];
  260.         cursorSlot = -1;
  261.         }
  262.     }
  263.     }
  264.  
  265.  
  266. //-----------------------------------------------------------------------------
  267. // - becomeFirstResponder
  268. //-----------------------------------------------------------------------------
  269. - (BOOL)becomeFirstResponder
  270.     {
  271.     NSWindow* win = [self window];
  272.     if (win && [win isKeyWindow])
  273.     {
  274.     if ([self shouldDrawCursor])
  275.         {
  276.         [self drawCursor];
  277.         [win flushWindow];
  278.         }
  279.     [[NSFontManager sharedFontManager]
  280.         setSelectedFont:[[self scroll] font] isMultiple:NO];
  281.     }
  282.     return YES;
  283.     }
  284.  
  285.  
  286. //-----------------------------------------------------------------------------
  287. // - resignFirstResponder
  288. //-----------------------------------------------------------------------------
  289. - (BOOL)resignFirstResponder
  290.     {
  291.     [self eraseCursor];
  292.     [[self window] flushWindow];
  293.     return YES;
  294.     }
  295.  
  296.  
  297. //-----------------------------------------------------------------------------
  298. // - becomeKeyWindow
  299. //-----------------------------------------------------------------------------
  300. - (void)becomeKeyWindow
  301.     {
  302.     if ([self shouldDrawCursor])
  303.     {
  304.     [self drawCursor];
  305.     [[self window] flushWindow];
  306.     }
  307.     [[NSFontManager sharedFontManager]
  308.             setSelectedFont:[[self scroll] font] isMultiple:NO];
  309.     }
  310.  
  311.  
  312. //-----------------------------------------------------------------------------
  313. // - resignKeyWindow
  314. //-----------------------------------------------------------------------------
  315. - (void)resignKeyWindow
  316.     {
  317.     [self eraseCursor];
  318.     [[self window] flushWindow];
  319.     }
  320.  
  321.  
  322. //-----------------------------------------------------------------------------
  323. // - reflectCursor
  324. //-----------------------------------------------------------------------------
  325. - (void)reflectCursor
  326.     {
  327.     if ([self shouldDrawCursor])
  328.     {
  329.     NSWindow* w = [self window];
  330.     [w disableFlushWindow];
  331.     [self eraseCursor];
  332.     [self drawCursor];
  333.     [w enableFlushWindow];
  334.     [w flushWindow];
  335.     }
  336.     }
  337.  
  338.  
  339. //-----------------------------------------------------------------------------
  340. // - moveCursorBy:
  341. //-----------------------------------------------------------------------------
  342. - (void)moveCursorBy:(int)delta
  343.     {
  344.     MiscTableBorder* const b = [self borderFor:trackerBorder];
  345.     int const lim = b->count();
  346.     if (lim > 0)
  347.     {
  348.     MiscCoord_V slot = b->getCursor() + delta;
  349.     if (slot < 0)
  350.         slot = lim - 1;
  351.     else if (slot >= lim)
  352.         slot = 0;
  353.     b->setCursor( slot );
  354.  
  355.     NSWindow* const w = [self window];
  356.     [w disableFlushWindow];
  357.     [self reflectCursor];
  358.     [self border:trackerBorder scrollToVisible:b->visualToPhysical(slot)];
  359.     [w enableFlushWindow];
  360.     [w flushWindow];
  361.     }
  362.     }
  363.  
  364.  
  365. //-----------------------------------------------------------------------------
  366. // - keyboardSelect:
  367. //-----------------------------------------------------------------------------
  368. - (void)keyboardSelect:(NSEvent*)p 
  369.     {
  370.     [tracker mouseDown:p atPos:[self borderFor:trackerBorder]->getCursor()];
  371.     }
  372.  
  373. @end
  374.