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

  1. //=============================================================================
  2. //
  3. //    Copyright (C) 1995-1997 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. // MiscTableCell.M
  17. //
  18. //    Default cell class used by MiscTableScroll to display text.
  19. //
  20. // NOTE *OPENSTEP-4.x*
  21. //    OPENSTEP 4.x converts NSImageCellType cells to NSTextCellType 
  22. //    cells upon receipt of -setFont: which is not the behavior that we want
  23. //    (nor expect since in previous NEXTSTEP versions -setFont: left the 
  24. //    cell alone if it was not NX_TEXTCELL).
  25. //
  26. // NOTE *SET-OWNER-VALUE*
  27. //    We must implement these methods so that MiscTableScroll will call 
  28. //    these methods instead of the explicit instance -setXxx methods.  
  29. //    However, we don't need to do any work.  We will ask the owner for 
  30. //    it's value whenever we need it.  
  31. //
  32. // FIXME: optional-allocation stuff does not address alignment requirements.
  33. // FIXME: automate most of the optional-allocation stuff.
  34. //
  35. //-----------------------------------------------------------------------------
  36. //-----------------------------------------------------------------------------
  37. // $Id: MiscTableCell.M,v 1.21 97/06/22 10:20:57 sunshine Exp $
  38. // $Log:    MiscTableCell.M,v $
  39. // Revision 1.21  97/06/22  10:20:57  sunshine
  40. // v127.1: Now scrollable by default; making setup for editable slots simpler.
  41. // Fixed bug: Was making allocation from wrong zone in -copyWithZone:. 
  42. // 
  43. // Revision 1.20  97/06/18  10:24:02  sunshine
  44. // v125.9: Color-related methods changed name: "highlight" --> "selected".
  45. // 
  46. // Revision 1.19  97/04/15  09:02:35  sunshine
  47. // v0.125.8: Added "MiscTableScroll/" prefix to #import to facilitate new
  48. // framework organization.
  49. //-----------------------------------------------------------------------------
  50. #import <MiscTableScroll/MiscTableCell.h>
  51. #import <MiscTableScroll/MiscTableScroll.h>
  52. #import "MiscTableView.h"
  53. #import "MiscTableScrollPrivate.h"
  54. extern "Objective-C" {
  55. #import <AppKit/NSApplication.h> // NSEventTrackingRunLoopMode
  56. #import <AppKit/NSFont.h>
  57. #import <AppKit/NSImage.h>
  58. #import <AppKit/NSPasteboard.h>
  59. }
  60. extern "C" {
  61. #import <math.h> // floor()
  62. #import    <string.h>
  63. }
  64.  
  65. #define    MISC_TC_VERSION_0    0    // Conditional tag.
  66. #define    MISC_TC_VERSION_1    1    // Tag became unconditional.
  67. #define    MISC_TC_VERSION_1000    1000    // First OpenStep version (4.0 PR2).
  68. #define    MISC_TC_VERSION        MISC_TC_VERSION_1000
  69.  
  70.  
  71. //=============================================================================
  72. // IMPLEMENTATION
  73. //=============================================================================
  74. @implementation MiscTableCell
  75.  
  76. //-----------------------------------------------------------------------------
  77. // + initialize
  78. //-----------------------------------------------------------------------------
  79. + (void)initialize
  80.     {
  81.     if (self == [MiscTableCell class])
  82.     {
  83.     [self setVersion:MISC_TC_VERSION];
  84.     }
  85.     }
  86.  
  87.  
  88. //-----------------------------------------------------------------------------
  89. // + defaultFont
  90. //-----------------------------------------------------------------------------
  91. + (NSFont*)defaultFont
  92.     {
  93.     return [NSFont userFontOfSize:12.0];
  94.     }
  95.  
  96.  
  97. //-----------------------------------------------------------------------------
  98. // initTextCell:
  99. //    NOTE *1*  -[Cell initTextCell:] invokes -setStringValue: which
  100. //    invokes -setFont:.  This means that this cell will get an explicit
  101. //    -setFont call before we finish initialization, and we need to 
  102. //    restore the useOwnerFont setting.
  103. //-----------------------------------------------------------------------------
  104. - (id)initTextCell:(NSString*)s
  105.     {
  106.     [super initTextCell:s];                // NOTE *1*
  107.     [self setBordered:NO];
  108.     [self setWraps:NO];
  109.     [self setAlignment:NSLeftTextAlignment];
  110.     [self setScrollable:YES];
  111.     [self setUseOwnerFont:YES];                // NOTE *1*
  112.     [self setOwnerFont:[[self class] defaultFont]];
  113.     return self;
  114.     }
  115.  
  116.  
  117. //-----------------------------------------------------------------------------
  118. // initImageCell:
  119. //-----------------------------------------------------------------------------
  120. - (id)initImageCell:(NSImage*)s
  121.     {
  122.     [super initImageCell:s];
  123.     [self setBordered:NO];
  124.     return self;
  125.     }
  126.  
  127.  
  128. //-----------------------------------------------------------------------------
  129. // isOpaque
  130. //-----------------------------------------------------------------------------
  131. - (BOOL)isOpaque
  132.     {
  133.     return !([self isSelected] ? [self useOwnerSelectedBackgroundColor] :
  134.                  [self useOwnerBackgroundColor]);
  135.     }
  136.  
  137.  
  138. //-----------------------------------------------------------------------------
  139. // setSelected:
  140. //-----------------------------------------------------------------------------
  141. - (void)setSelected:(BOOL)flag
  142.     {
  143.     if (flag)
  144.     tc1_flags |= MISC_TC1_IS_SELECTED;
  145.     else
  146.     tc1_flags &= ~MISC_TC1_IS_SELECTED;
  147.     }
  148.  
  149.  
  150. //-----------------------------------------------------------------------------
  151. // isSelected
  152. //-----------------------------------------------------------------------------
  153. - (BOOL)isSelected
  154.     {
  155.     return ((tc1_flags & MISC_TC1_IS_SELECTED) != 0);
  156.     }
  157.  
  158.  
  159. //-----------------------------------------------------------------------------
  160. // tag
  161. //-----------------------------------------------------------------------------
  162. - (int)tag
  163.     {
  164.     return tag;
  165.     }
  166.  
  167.  
  168. //-----------------------------------------------------------------------------
  169. // setTag:
  170. //-----------------------------------------------------------------------------
  171. - (void)setTag:(int)x
  172.     {
  173.     tag = x;
  174.     }
  175.  
  176.  
  177. //-----------------------------------------------------------------------------
  178. // owner
  179. //-----------------------------------------------------------------------------
  180. - (id)owner
  181.     {
  182.     return owner;
  183.     }
  184.  
  185.  
  186. //-----------------------------------------------------------------------------
  187. // setOwner:
  188. //-----------------------------------------------------------------------------
  189. - (void)setOwner:(id)obj
  190.     {
  191.     if (obj != owner)
  192.     {
  193.     owner = obj;
  194.     if (owner != 0)
  195.         {
  196.         if ([owner respondsToSelector:@selector(font)])
  197.         [self setOwnerFont:[owner font]];
  198.         }
  199.     } 
  200.     }
  201.  
  202.  
  203. //-----------------------------------------------------------------------------
  204. // font
  205. //-----------------------------------------------------------------------------
  206. - (NSFont*)font
  207.     {
  208.     return [super font];
  209.     }
  210.  
  211.  
  212. //-----------------------------------------------------------------------------
  213. // setFont:
  214. //-----------------------------------------------------------------------------
  215. - (void)setFont:(NSFont*)fontObj
  216.     {
  217.     if ([self type] == NSTextCellType)        // NOTE *OPENSTEP-4.x*
  218.     {
  219.     [self setUseOwnerFont:NO];
  220.     [super setFont:fontObj];
  221.     }
  222.     }
  223.  
  224.  
  225. //-----------------------------------------------------------------------------
  226. // tc1Data
  227. //-----------------------------------------------------------------------------
  228. - (void*)tc1Data
  229.     {
  230.     return tc1_data;
  231.     }
  232.  
  233.  
  234. //=============================================================================
  235. // TC1 MANIPULATION
  236. //=============================================================================
  237. //-----------------------------------------------------------------------------
  238. // tc1Flags
  239. //-----------------------------------------------------------------------------
  240. - (unsigned int)tc1Flags
  241.     {
  242.     return tc1_flags;
  243.     }
  244.  
  245.  
  246. //-----------------------------------------------------------------------------
  247. // tc1DataSize
  248. //-----------------------------------------------------------------------------
  249. - (unsigned int)tc1DataSize
  250.     {
  251.     unsigned int size = 0;
  252.     if (tc1_flags & MISC_TC1_SELF_TEXT_COLOR)
  253.     size += [self tc1TextColorLen];
  254.     if (tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR)
  255.     size += [self tc1BackgroundColorLen];
  256.     if (tc1_flags & MISC_TC1_SELF_TEXT_COLOR_H)
  257.     size += [self tc1SelectedTextColorLen];
  258.     if (tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR_H)
  259.     size += [self tc1SelectedBackgroundColorLen];
  260.     return size;
  261.     }
  262.  
  263.  
  264. //-----------------------------------------------------------------------------
  265. // tc1TextColorPos
  266. //-----------------------------------------------------------------------------
  267. - (unsigned int)tc1TextColorPos
  268.     {
  269.     return 0;
  270.     }
  271.  
  272.  
  273. //-----------------------------------------------------------------------------
  274. // tc1BackgroundColorPos
  275. //-----------------------------------------------------------------------------
  276. - (unsigned int)tc1BackgroundColorPos
  277.     {
  278.     unsigned int pos = [self tc1TextColorPos];
  279.     if (tc1_flags & MISC_TC1_SELF_TEXT_COLOR)
  280.     pos += [self tc1TextColorLen];
  281.     return pos;
  282.     }
  283.  
  284.  
  285. //-----------------------------------------------------------------------------
  286. // tc1SelectedTextColorPos
  287. //-----------------------------------------------------------------------------
  288. - (unsigned int)tc1SelectedTextColorPos
  289.     {
  290.     unsigned int pos = [self tc1BackgroundColorPos];
  291.     if (tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR)
  292.     pos += [self tc1BackgroundColorLen];
  293.     return pos;
  294.     }
  295.  
  296.  
  297. //-----------------------------------------------------------------------------
  298. // tc1SelectedBackgroundColorPos
  299. //-----------------------------------------------------------------------------
  300. - (unsigned int)tc1SelectedBackgroundColorPos
  301.     {
  302.     unsigned int pos = [self tc1SelectedTextColorPos];
  303.     if (tc1_flags & MISC_TC1_SELF_TEXT_COLOR_H)
  304.     pos += [self tc1SelectedTextColorLen];
  305.     return pos;
  306.     }
  307.  
  308.  
  309. //-----------------------------------------------------------------------------
  310. // tc1TextColorLen
  311. //-----------------------------------------------------------------------------
  312. - (unsigned int)tc1TextColorLen
  313.     {
  314.     return sizeof(NSColor*);
  315.     }
  316.  
  317.  
  318. //-----------------------------------------------------------------------------
  319. // tc1BackgroundColorLen
  320. //-----------------------------------------------------------------------------
  321. - (unsigned int)tc1BackgroundColorLen
  322.     {
  323.     return sizeof(NSColor*);
  324.     }
  325.  
  326.  
  327. //-----------------------------------------------------------------------------
  328. // tc1SelectedTextColorLen
  329. //-----------------------------------------------------------------------------
  330. - (unsigned int)tc1SelectedTextColorLen
  331.     {
  332.     return sizeof(NSColor*);
  333.     }
  334.  
  335.  
  336. //-----------------------------------------------------------------------------
  337. // tc1SelectedBackgroundColorLen
  338. //-----------------------------------------------------------------------------
  339. - (unsigned int)tc1SelectedBackgroundColorLen
  340.     {
  341.     return sizeof(NSColor*);
  342.     }
  343.  
  344.  
  345. //-----------------------------------------------------------------------------
  346. // tc1TextColorPtr
  347. //-----------------------------------------------------------------------------
  348. - (NSColor**)tc1TextColorPtr
  349.     {
  350.     return (NSColor**)((char*)tc1_data + [self tc1TextColorPos]);
  351.     }
  352.  
  353.  
  354. //-----------------------------------------------------------------------------
  355. // tc1BackgroundColorPtr
  356. //-----------------------------------------------------------------------------
  357. - (NSColor**)tc1BackgroundColorPtr
  358.     {
  359.     return (NSColor**)((char*)tc1_data + [self tc1BackgroundColorPos]);
  360.     }
  361.  
  362.  
  363. //-----------------------------------------------------------------------------
  364. // tc1SelectedTextColorPtr
  365. //-----------------------------------------------------------------------------
  366. - (NSColor**)tc1SelectedTextColorPtr
  367.     {
  368.     return (NSColor**)((char*)tc1_data + [self tc1SelectedTextColorPos]);
  369.     }
  370.  
  371.  
  372. //-----------------------------------------------------------------------------
  373. // tc1SelectedBackgroundColorPtr
  374. //-----------------------------------------------------------------------------
  375. - (NSColor**)tc1SelectedBackgroundColorPtr
  376.     {
  377.     return (NSColor**)((char*)tc1_data + [self tc1SelectedBackgroundColorPos]);
  378.     }
  379.  
  380.  
  381. //-----------------------------------------------------------------------------
  382. // tc1InsertData:len:pos:
  383. //-----------------------------------------------------------------------------
  384. - (void*)tc1InsertData:(void const*)data
  385.     pos:(unsigned int)pos
  386.     len:(unsigned int)len
  387.     {
  388.     if (len > 0)
  389.     {
  390.     unsigned int const old_size = [self tc1DataSize];
  391.     unsigned int const new_size = old_size + len;
  392.     if (old_size == 0)
  393.         tc1_data = NSZoneMalloc( [self zone], new_size );
  394.     else
  395.         {
  396.         tc1_data = NSZoneRealloc( [self zone], tc1_data, new_size );
  397.         if (pos < old_size)
  398.         memmove( (char*) tc1_data + pos + len,        // Destination
  399.             (char*) tc1_data + pos,            // Source
  400.             old_size - pos );            // # bytes.
  401.         }
  402.     if (data != 0)
  403.         memcpy( (char*) tc1_data + pos, data, len );
  404.     else
  405.         memset( (char*) tc1_data + pos, 0, len );
  406.     return (void*)((char*) tc1_data + pos );
  407.     }
  408.     return 0;
  409.     }
  410.  
  411.  
  412. //-----------------------------------------------------------------------------
  413. // tc1DeleteDataPos:len:
  414. //-----------------------------------------------------------------------------
  415. - (void)tc1DeleteDataPos:(unsigned int)pos len:(unsigned int)len
  416.     {
  417.     if (len > 0)
  418.     {
  419.     unsigned int const old_size = [self tc1DataSize];
  420.     unsigned int const new_size = old_size - len;
  421.     if (new_size == 0)
  422.         {
  423.         NSZoneFree( [self zone], tc1_data );
  424.         tc1_data = 0;
  425.         }
  426.     else
  427.         {
  428.         if (pos < new_size)
  429.         memmove( (char*) tc1_data + pos,        // Destination
  430.             (char*) tc1_data + pos + len,        // Source
  431.             new_size - pos );            // # bytes
  432.         tc1_data = NSZoneRealloc( [self zone], tc1_data, new_size );
  433.         }
  434.     }
  435.     }
  436.  
  437.  
  438. //=============================================================================
  439. // *OWNER* CONTROLS
  440. //=============================================================================
  441. //-----------------------------------------------------------------------------
  442. // useOwnerFont
  443. //-----------------------------------------------------------------------------
  444. - (BOOL)useOwnerFont
  445.     {
  446.     return ((tc1_flags & MISC_TC1_SELF_FONT) == 0);
  447.     }
  448.  
  449.  
  450. //-----------------------------------------------------------------------------
  451. // useOwnerTextColor
  452. //-----------------------------------------------------------------------------
  453. - (BOOL)useOwnerTextColor
  454.     {
  455.     return ((tc1_flags & MISC_TC1_SELF_TEXT_COLOR) == 0);
  456.     }
  457.  
  458.  
  459. //-----------------------------------------------------------------------------
  460. // useOwnerBackgroundColor
  461. //-----------------------------------------------------------------------------
  462. - (BOOL)useOwnerBackgroundColor
  463.     {
  464.     return ((tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR) == 0);
  465.     }
  466.  
  467.  
  468. //-----------------------------------------------------------------------------
  469. // useOwnerSelectedTextColor
  470. //-----------------------------------------------------------------------------
  471. - (BOOL)useOwnerSelectedTextColor
  472.     {
  473.     return ((tc1_flags & MISC_TC1_SELF_TEXT_COLOR_H) == 0);
  474.     }
  475.  
  476.  
  477. //-----------------------------------------------------------------------------
  478. // useOwnerSelectedBackgroundColor
  479. //-----------------------------------------------------------------------------
  480. - (BOOL)useOwnerSelectedBackgroundColor
  481.     {
  482.     return ((tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR_H) == 0);
  483.     }
  484.  
  485.  
  486. //-----------------------------------------------------------------------------
  487. // setUseOwnerFont:
  488. //-----------------------------------------------------------------------------
  489. - (void)setUseOwnerFont:(BOOL)flag
  490.     {
  491.     if ([self useOwnerFont] != flag)
  492.     {
  493.     if (flag)
  494.         {
  495.         tc1_flags &= ~(MISC_TC1_SELF_FONT);
  496.         if (owner != 0 && [owner respondsToSelector:@selector(font)])
  497.         [self setOwnerFont:[owner font]];
  498.         }
  499.     else // (!flag)
  500.         {
  501.         tc1_flags |= MISC_TC1_SELF_FONT;
  502.         }
  503.     } 
  504.     }
  505.  
  506.  
  507. //-----------------------------------------------------------------------------
  508. // setUseOwnerTextColor:
  509. //-----------------------------------------------------------------------------
  510. - (void)setUseOwnerTextColor:(BOOL)flag
  511.     {
  512.     if ([self useOwnerTextColor] != flag)
  513.     {
  514.     unsigned int const pos = [self tc1TextColorPos];
  515.     unsigned int const len = [self tc1TextColorLen];
  516.     if (flag)
  517.         {
  518.         [[self textColor] release];
  519.         [self tc1DeleteDataPos:pos len:len];
  520.         tc1_flags &= ~(MISC_TC1_SELF_TEXT_COLOR);
  521.         }
  522.     else // (!flag)
  523.         {
  524.         NSColor* color = [[[self class] defaultTextColor] retain];
  525.         [self tc1InsertData:&color pos:pos len:len];
  526.         tc1_flags |= MISC_TC1_SELF_TEXT_COLOR;
  527.         }
  528.     } 
  529.     }
  530.  
  531.  
  532. //-----------------------------------------------------------------------------
  533. // setUseOwnerBackgroundColor:
  534. //-----------------------------------------------------------------------------
  535. - (void)setUseOwnerBackgroundColor:(BOOL)flag
  536.     {
  537.     if ([self useOwnerBackgroundColor] != flag)
  538.     {
  539.     unsigned int const pos = [self tc1BackgroundColorPos];
  540.     unsigned int const len = [self tc1BackgroundColorLen];
  541.     if (flag)
  542.         {
  543.         [[self backgroundColor] release];
  544.         [self tc1DeleteDataPos:pos len:len];
  545.         tc1_flags &= ~(MISC_TC1_SELF_BACKGROUND_COLOR);
  546.         }
  547.     else // (!flag)
  548.         {
  549.         NSColor* color = [[[self class] defaultBackgroundColor] retain];
  550.         [self tc1InsertData:&color pos:pos len:len];
  551.         tc1_flags |= MISC_TC1_SELF_BACKGROUND_COLOR;
  552.         }
  553.     } 
  554.     }
  555.  
  556.  
  557. //-----------------------------------------------------------------------------
  558. // setUseOwnerSelectedTextColor:
  559. //-----------------------------------------------------------------------------
  560. - (void)setUseOwnerSelectedTextColor:(BOOL)flag
  561.     {
  562.     if ([self useOwnerSelectedTextColor] != flag)
  563.     {
  564.     unsigned int const pos = [self tc1SelectedTextColorPos];
  565.     unsigned int const len = [self tc1SelectedTextColorLen];
  566.     if (flag)
  567.         {
  568.         [[self selectedTextColor] release];
  569.         [self tc1DeleteDataPos:pos len:len];
  570.         tc1_flags &= ~(MISC_TC1_SELF_TEXT_COLOR_H);
  571.         }
  572.     else // (!flag)
  573.         {
  574.         NSColor* color = [[[self class] defaultSelectedTextColor] retain];
  575.         [self tc1InsertData:&color pos:pos len:len];
  576.         tc1_flags |= MISC_TC1_SELF_TEXT_COLOR_H;
  577.         }
  578.     } 
  579.     }
  580.  
  581.  
  582. //-----------------------------------------------------------------------------
  583. // setUseOwnerSelectedBackgroundColor:
  584. //-----------------------------------------------------------------------------
  585. - (void)setUseOwnerSelectedBackgroundColor:(BOOL)flag
  586.     {
  587.     if ([self useOwnerSelectedBackgroundColor] != flag)
  588.     {
  589.     unsigned int const pos = [self tc1SelectedBackgroundColorPos];
  590.     unsigned int const len = [self tc1SelectedBackgroundColorLen];
  591.     if (flag)
  592.         {
  593.         [[self selectedBackgroundColor] release];
  594.         [self tc1DeleteDataPos:pos len:len];
  595.         tc1_flags &= ~(MISC_TC1_SELF_BACKGROUND_COLOR_H);
  596.         }
  597.     else // (!flag)
  598.         {
  599.         NSColor* color =
  600.         [[[self class] defaultSelectedBackgroundColor] retain];
  601.         [self tc1InsertData:&color pos:pos len:len];
  602.         tc1_flags |= MISC_TC1_SELF_BACKGROUND_COLOR_H;
  603.         }
  604.     } 
  605.     }
  606.  
  607.  
  608. //-----------------------------------------------------------------------------
  609. // setOwnerFont:
  610. //-----------------------------------------------------------------------------
  611. - (void)setOwnerFont:(NSFont*)fontObj
  612.     {
  613.     if ([self type] == NSTextCellType)        // NOTE *OPENSTEP-4.x*
  614.     if ([self useOwnerFont])
  615.         [super setFont:fontObj]; 
  616.     }
  617.  
  618.  
  619. //-----------------------------------------------------------------------------
  620. // setOwner values...    NOTE *SET-OWNER-VALUE*
  621. //-----------------------------------------------------------------------------
  622. - (void)setOwnerTextColor:(NSColor*)pcolor {}
  623. - (void)setOwnerBackgroundColor:(NSColor*)pcolor {}
  624. - (void)setOwnerSelectedTextColor:(NSColor*)pcolor {}
  625. - (void)setOwnerSelectedBackgroundColor:(NSColor*)pcolor {}
  626.  
  627.  
  628. //=============================================================================
  629. // COLOR MANIPULATION
  630. //=============================================================================
  631. //-----------------------------------------------------------------------------
  632. // +defaultBackgroundColor
  633. //-----------------------------------------------------------------------------
  634. + (NSColor*)defaultBackgroundColor
  635.     {
  636.     return [NSColor lightGrayColor];
  637.     }
  638.  
  639.  
  640. //-----------------------------------------------------------------------------
  641. // backgroundColor
  642. //-----------------------------------------------------------------------------
  643. - (NSColor*)backgroundColor
  644.     {
  645.     if ([self useOwnerBackgroundColor])
  646.     {
  647.     if (owner != 0 &&
  648.         [owner respondsToSelector:@selector(backgroundColor)])
  649.         return [owner backgroundColor];
  650.     return [[self class] defaultBackgroundColor];
  651.     }
  652.     return *[self tc1BackgroundColorPtr];
  653.     }
  654.  
  655.  
  656. //-----------------------------------------------------------------------------
  657. // setBackgroundColor
  658. //-----------------------------------------------------------------------------
  659. - (void)setBackgroundColor:(NSColor*)c
  660.     {
  661.     NSColor** p;
  662.     [self setUseOwnerBackgroundColor:NO];
  663.     p = [self tc1BackgroundColorPtr];
  664.     [*p autorelease];
  665.     *p = [c retain];
  666.     }
  667.  
  668.  
  669. //-----------------------------------------------------------------------------
  670. // +defaultSelectedBackgroundColor
  671. //-----------------------------------------------------------------------------
  672. + (NSColor*)defaultSelectedBackgroundColor
  673.     {
  674.     return [NSColor whiteColor];
  675.     }
  676.  
  677.  
  678. //-----------------------------------------------------------------------------
  679. // selectedBackgroundColor
  680. //-----------------------------------------------------------------------------
  681. - (NSColor*)selectedBackgroundColor
  682.     {
  683.     if ([self useOwnerSelectedBackgroundColor])
  684.     {
  685.     if (owner &&
  686.         [owner respondsToSelector:@selector(selectedBackgroundColor)])
  687.         return [owner selectedBackgroundColor];
  688.     return [[self class] defaultSelectedBackgroundColor];
  689.     }
  690.     return *[self tc1SelectedBackgroundColorPtr];
  691.     }
  692.  
  693.  
  694. //-----------------------------------------------------------------------------
  695. // setSelectedBackgroundColor
  696. //-----------------------------------------------------------------------------
  697. - (void)setSelectedBackgroundColor:(NSColor*)c
  698.     {
  699.     NSColor** p;
  700.     [self setUseOwnerSelectedBackgroundColor:NO];
  701.     p = [self tc1SelectedBackgroundColorPtr];
  702.     [*p autorelease];
  703.     *p = [c retain]; 
  704.     }
  705.  
  706.  
  707. //-----------------------------------------------------------------------------
  708. // +defaultTextColor
  709. //-----------------------------------------------------------------------------
  710. + (NSColor*)defaultTextColor
  711.     {
  712.     return [NSColor blackColor];
  713.     }
  714.  
  715.  
  716. //-----------------------------------------------------------------------------
  717. // textColor
  718. //-----------------------------------------------------------------------------
  719. - (NSColor*)textColor
  720.     {
  721.     if ([self useOwnerTextColor])
  722.     {
  723.     if (owner != 0 && [owner respondsToSelector:@selector(textColor)])
  724.         return [owner textColor];
  725.     return [[self class] defaultTextColor];
  726.     }
  727.     return *[self tc1TextColorPtr];
  728.     }
  729.  
  730.  
  731. //-----------------------------------------------------------------------------
  732. // setTextColor
  733. //-----------------------------------------------------------------------------
  734. - (void)setTextColor:(NSColor*)c
  735.     {
  736.     NSColor** p;
  737.     [self setUseOwnerTextColor:NO];
  738.     p = [self tc1TextColorPtr];
  739.     [*p autorelease];
  740.     *p = [c retain];
  741.     }
  742.  
  743.  
  744. //-----------------------------------------------------------------------------
  745. // +defaultSelectedTextColor
  746. //-----------------------------------------------------------------------------
  747. + (NSColor*)defaultSelectedTextColor
  748.     {
  749.     return [NSColor blackColor];
  750.     }
  751.  
  752.  
  753. //-----------------------------------------------------------------------------
  754. // selectedTextColor
  755. //-----------------------------------------------------------------------------
  756. - (NSColor*)selectedTextColor
  757.     {
  758.     if ([self useOwnerSelectedTextColor])
  759.     {
  760.     if (owner != 0 &&
  761.         [owner respondsToSelector:@selector(selectedTextColor)])
  762.         return [owner selectedTextColor];
  763.     return [[self class] defaultSelectedTextColor];
  764.     }
  765.     return *[self tc1SelectedTextColorPtr];
  766.     }
  767.  
  768.  
  769. //-----------------------------------------------------------------------------
  770. // setSelectedTextColor
  771. //-----------------------------------------------------------------------------
  772. - (void)setSelectedTextColor:(NSColor*)c
  773.     {
  774.     NSColor** p;
  775.     [self setUseOwnerSelectedTextColor:NO];
  776.     p = [self tc1SelectedTextColorPtr];
  777.     [*p autorelease];
  778.     *p = [c retain]; 
  779.     }
  780.  
  781.  
  782. //=============================================================================
  783. // DRAWING
  784. //=============================================================================
  785. //-----------------------------------------------------------------------------
  786. // ownerDraw
  787. //-----------------------------------------------------------------------------
  788. - (BOOL)ownerDraw
  789.     {
  790.     return !(tc1_flags & MISC_TC1_SELF_DRAW);
  791.     }
  792.  
  793.  
  794. //-----------------------------------------------------------------------------
  795. // setOwnerDraw:
  796. //-----------------------------------------------------------------------------
  797. - (void)setOwnerDraw:(BOOL)flag
  798.     {
  799.     if (flag)
  800.     tc1_flags &= ~(MISC_TC1_SELF_DRAW);
  801.     else // (!flag)
  802.     tc1_flags |= MISC_TC1_SELF_DRAW;
  803.     }
  804.  
  805.  
  806. //-----------------------------------------------------------------------------
  807. // bgColor
  808. //-----------------------------------------------------------------------------
  809. - (NSColor*)bgColor
  810.     {
  811.     return [self isSelected] ?
  812.         [self selectedBackgroundColor] : [self backgroundColor];
  813.     }
  814.  
  815.  
  816. //-----------------------------------------------------------------------------
  817. // fgColor
  818. //-----------------------------------------------------------------------------
  819. - (NSColor*)fgColor
  820.     {
  821.     return [self isSelected] ? [self selectedTextColor] : [self textColor];
  822.     }
  823.  
  824.  
  825. //-----------------------------------------------------------------------------
  826. // setUpFieldEditorAttributes:
  827. //-----------------------------------------------------------------------------
  828. - (NSText*)setUpFieldEditorAttributes:(NSText*)textObject
  829.     {
  830.     [super setUpFieldEditorAttributes:textObject];
  831.     [textObject setTextColor:[self fgColor]];
  832.     [textObject setBackgroundColor:[self bgColor]];
  833.     return textObject;
  834.     }
  835.  
  836.  
  837. //-----------------------------------------------------------------------------
  838. // drawInteriorWithFrame:inView:
  839. //
  840. // NOTE *1*: Our superclass (NSCell) swaps white with gray when highlighted.
  841. //    Since we supply our own highlight colors, we need to subvert NSCell's
  842. //    normal behavior in order to prevent it from munging our colors.
  843. //-----------------------------------------------------------------------------
  844. - (void)drawInteriorWithFrame:(NSRect)rect inView:(NSView*)controlView
  845.     {
  846.     if ([self isOpaque])
  847.     {
  848.     [[self bgColor] set];
  849.     NSRectFill( rect );
  850.     }
  851.  
  852.     BOOL const wasHighlighted = [self isHighlighted];        // NOTE *1*
  853.     [self setCellAttribute:NSCellHighlighted to:0];
  854.  
  855.     [super drawInteriorWithFrame:rect inView:controlView];
  856.  
  857.     [self setCellAttribute:NSCellHighlighted to:wasHighlighted];// NOTE *1*
  858.     }
  859.  
  860.  
  861. //-----------------------------------------------------------------------------
  862. // drawWithFrame:inView:
  863. //-----------------------------------------------------------------------------
  864. - (void)drawWithFrame:(NSRect)rect inView:(NSView*)aView
  865.     {
  866.     [self drawInteriorWithFrame:rect inView:aView];
  867.     }
  868.  
  869.  
  870. //-----------------------------------------------------------------------------
  871. // highlight:withFrame:inView:
  872. //
  873. //    No need to do any actual drawing since this class does not display
  874. //    itself differently when highlighted.
  875. //-----------------------------------------------------------------------------
  876. - (void)highlight:(BOOL)flag withFrame:(NSRect)rect inView:(NSView *)aView
  877.     {
  878.     if (flag != [self isHighlighted])
  879.     [self setCellAttribute:NSCellHighlighted to:flag];
  880.     }
  881.  
  882.  
  883. //=============================================================================
  884. // REVIVE / RETIRE
  885. //=============================================================================
  886. //-----------------------------------------------------------------------------
  887. // tableScroll:reviveAtRow:column:
  888. //
  889. // NOTE *1*
  890. //    This is a performance-critical method.  Therefore, the owner font
  891. //    setting code has been completely in-lined here.  Furthermore, since
  892. //    the owner's font may have changed after the cell was retired, we
  893. //    latch the owner's current font unconditionally here.
  894. //-----------------------------------------------------------------------------
  895. - (id)tableScroll:(MiscTableScroll*)scroll
  896.     reviveAtRow:(int)row column:(int)col
  897.     {
  898.     unsigned int const MASK =
  899.         MISC_TC1_SELF_DRAW |
  900.         MISC_TC1_SELF_TEXT_COLOR |
  901.         MISC_TC1_SELF_BACKGROUND_COLOR |
  902.         MISC_TC1_SELF_TEXT_COLOR_H |
  903.         MISC_TC1_SELF_BACKGROUND_COLOR_H;
  904.  
  905.     owner = scroll;
  906.     tc1_flags &= ~(MISC_TC1_SELF_FONT);
  907.     [super setFont:[scroll font]];        // NOTE *1*
  908.  
  909.     if (tc1_flags & MASK)
  910.     {
  911.     if (tc1_flags & MISC_TC1_SELF_DRAW)
  912.         [self setOwnerDraw:YES];
  913.     if (tc1_flags & MISC_TC1_SELF_TEXT_COLOR)
  914.         [self setUseOwnerTextColor:YES];
  915.     if (tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR)
  916.         [self setUseOwnerBackgroundColor:YES];
  917.     if (tc1_flags & MISC_TC1_SELF_TEXT_COLOR_H)
  918.         [self setUseOwnerSelectedTextColor:YES];
  919.     if (tc1_flags & MISC_TC1_SELF_BACKGROUND_COLOR_H)
  920.         [self setUseOwnerSelectedBackgroundColor:YES];
  921.     }
  922.     return self;
  923.     }
  924.  
  925.  
  926. //-----------------------------------------------------------------------------
  927. // tableScroll:retireAtRow:column:
  928. //-----------------------------------------------------------------------------
  929. - (id)tableScroll:(MiscTableScroll*)scroll
  930.     retireAtRow:(int)row column:(int)col
  931.     {
  932.     if ([self type] == NSTextCellType)
  933.     [self setStringValue:@""];
  934.     return self;
  935.     }
  936.  
  937.  
  938. //=============================================================================
  939. // ALLOCATION / DEALLOCATION
  940. //=============================================================================
  941. //-----------------------------------------------------------------------------
  942. // tc1DestroyData
  943. //-----------------------------------------------------------------------------
  944. - (void)tc1DestroyData
  945.     {
  946.     if (![self useOwnerTextColor])
  947.     [[self textColor] release];
  948.     if (![self useOwnerBackgroundColor])
  949.     [[self backgroundColor] release];
  950.     if (![self useOwnerSelectedTextColor])
  951.     [[self selectedTextColor] release];
  952.     if (![self useOwnerSelectedBackgroundColor])
  953.     [[self selectedBackgroundColor] release];
  954.  
  955.     tc1_flags = 0;
  956.     }
  957.  
  958.  
  959. //-----------------------------------------------------------------------------
  960. // tc1FreeData
  961. //-----------------------------------------------------------------------------
  962. - (void)tc1FreeData
  963.     {
  964.     if (tc1_data != 0)
  965.     {
  966.     NSZoneFree( [self zone], tc1_data );
  967.     tc1_data = 0;
  968.     }
  969.     }
  970.  
  971.  
  972. //-----------------------------------------------------------------------------
  973. // dealloc
  974. //-----------------------------------------------------------------------------
  975. - (void)dealloc
  976.     {
  977.     [self tc1DestroyData];
  978.     [self tc1FreeData];
  979.     [super dealloc];
  980.     }
  981.  
  982.  
  983. //-----------------------------------------------------------------------------
  984. // copyWithZone:
  985. //-----------------------------------------------------------------------------
  986. - (id)copyWithZone:(NSZone*)zone
  987.     {
  988.     MiscTableCell* clone = [super copyWithZone:zone];
  989.     if (tc1_data != 0)
  990.     {
  991.     unsigned int const size = [self tc1DataSize];
  992.     void* p = NSZoneMalloc( zone, size );
  993.     memcpy( p, tc1_data, size );
  994.     clone->tc1_data = p;
  995.  
  996.     if (![clone useOwnerTextColor])
  997.         *[clone tc1TextColorPtr] = [[self textColor] retain];
  998.     if (![clone useOwnerBackgroundColor])
  999.         *[clone tc1BackgroundColorPtr] = [[self backgroundColor] retain];
  1000.     if (![clone useOwnerSelectedTextColor])
  1001.         *[clone tc1SelectedTextColorPtr] =
  1002.             [[self selectedTextColor] retain];
  1003.     if (![clone useOwnerSelectedBackgroundColor])
  1004.         *[clone tc1SelectedBackgroundColorPtr] =
  1005.             [[self selectedBackgroundColor] retain];
  1006.     }
  1007.     return clone;
  1008.     }
  1009.  
  1010.  
  1011. //=============================================================================
  1012. // ARCHIVING
  1013. //=============================================================================
  1014. //-----------------------------------------------------------------------------
  1015. // initWithCoder_v0:
  1016. //-----------------------------------------------------------------------------
  1017. - (void)initWithCoder_v0:(NSCoder*)aDecoder
  1018.     {
  1019.     unsigned int x;
  1020.  
  1021.     owner = [[aDecoder decodeObject] retain];
  1022.  
  1023.     [aDecoder decodeValueOfObjCType:@encode(unsigned int) at:&x];
  1024.     if (x & MISC_TC1_HAS_TAG)
  1025.     [aDecoder decodeValueOfObjCType:@encode(int) at:&tag];
  1026.     else
  1027.     tag = 0;
  1028.  
  1029.     if (x & MISC_TC1_SELF_TEXT_COLOR)
  1030.     [self setTextColor:[aDecoder decodeNXColor]];
  1031.     if (x & MISC_TC1_SELF_BACKGROUND_COLOR)
  1032.     [self setBackgroundColor:[aDecoder decodeNXColor]];
  1033.     if (x & MISC_TC1_SELF_TEXT_COLOR_H)
  1034.     [self setSelectedTextColor:[aDecoder decodeNXColor]];
  1035.     if (x & MISC_TC1_SELF_BACKGROUND_COLOR_H)
  1036.     [self setSelectedBackgroundColor:[aDecoder decodeNXColor]];
  1037.     }
  1038.  
  1039.  
  1040. //-----------------------------------------------------------------------------
  1041. // initWithCoder_v1:
  1042. //-----------------------------------------------------------------------------
  1043. - (void)initWithCoder_v1:(NSCoder*)aDecoder
  1044.     {
  1045.     unsigned int x;
  1046.  
  1047.     owner = [[aDecoder decodeObject] retain];
  1048.  
  1049.     [aDecoder decodeValueOfObjCType:@encode(int) at:&tag];
  1050.     [aDecoder decodeValueOfObjCType:@encode(unsigned int) at:&x];
  1051.  
  1052.     if (x & MISC_TC1_SELF_TEXT_COLOR)
  1053.     [self setTextColor:[aDecoder decodeNXColor]];
  1054.     if (x & MISC_TC1_SELF_BACKGROUND_COLOR)
  1055.     [self setBackgroundColor:[aDecoder decodeNXColor]];
  1056.     if (x & MISC_TC1_SELF_TEXT_COLOR_H)
  1057.     [self setSelectedTextColor:[aDecoder decodeNXColor]];
  1058.     if (x & MISC_TC1_SELF_BACKGROUND_COLOR_H)
  1059.     [self setSelectedBackgroundColor:[aDecoder decodeNXColor]];
  1060.     }
  1061.  
  1062.  
  1063. //-----------------------------------------------------------------------------
  1064. // initWithCoder_v1000:
  1065. //-----------------------------------------------------------------------------
  1066. - (void)initWithCoder_v1000:(NSCoder*)aDecoder
  1067.     {
  1068.     unsigned int x;
  1069.  
  1070.     owner = [[aDecoder decodeObject] retain];
  1071.  
  1072.     [aDecoder decodeValueOfObjCType:@encode(int) at:&tag];
  1073.     [aDecoder decodeValueOfObjCType:@encode(unsigned int) at:&x];
  1074.  
  1075.     if (x & MISC_TC1_SELF_TEXT_COLOR)
  1076.     [self setTextColor:[aDecoder decodeObject]];
  1077.     if (x & MISC_TC1_SELF_BACKGROUND_COLOR)
  1078.     [self setBackgroundColor:[aDecoder decodeObject]];
  1079.     if (x & MISC_TC1_SELF_TEXT_COLOR_H)
  1080.     [self setSelectedTextColor:[aDecoder decodeObject]];
  1081.     if (x & MISC_TC1_SELF_BACKGROUND_COLOR_H)
  1082.     [self setSelectedBackgroundColor:[aDecoder decodeObject]];
  1083.     }
  1084.  
  1085.  
  1086. //-----------------------------------------------------------------------------
  1087. // initWithCoder:
  1088. //-----------------------------------------------------------------------------
  1089. - (id)initWithCoder:(NSCoder*)aDecoder
  1090.     {
  1091.     [super initWithCoder:aDecoder];
  1092.  
  1093.     [self tc1DestroyData];
  1094.     [self tc1FreeData];
  1095.  
  1096.     unsigned int const ver =
  1097.         [aDecoder versionForClassName:[[MiscTableCell class] description]];
  1098.  
  1099.     switch (ver)
  1100.     {
  1101.     case MISC_TC_VERSION_0:    [self initWithCoder_v0:   aDecoder]; break;
  1102.     case MISC_TC_VERSION_1:    [self initWithCoder_v1:   aDecoder]; break;
  1103.     case MISC_TC_VERSION_1000: [self initWithCoder_v1000:aDecoder]; break;
  1104.     default:
  1105.         [NSException raise:NSGenericException
  1106.             format:@"Cannot read: unknown version %d", ver];
  1107.         break;
  1108.     }
  1109.  
  1110.     return self;
  1111.     }
  1112.  
  1113.  
  1114. //-----------------------------------------------------------------------------
  1115. // encodeWithCoder:
  1116. //-----------------------------------------------------------------------------
  1117. - (void)encodeWithCoder:(NSCoder*)aCoder
  1118.     {
  1119.     [super encodeWithCoder:aCoder];
  1120.     [aCoder encodeConditionalObject:owner];
  1121.     [aCoder encodeValueOfObjCType:@encode(int) at:&tag];
  1122.     [aCoder encodeValueOfObjCType:@encode(unsigned int) at:&tc1_flags];
  1123.     if (![self useOwnerTextColor])
  1124.     [aCoder encodeObject:[self textColor]];
  1125.     if (![self useOwnerBackgroundColor])
  1126.     [aCoder encodeObject:[self backgroundColor]];
  1127.     if (![self useOwnerSelectedTextColor])
  1128.     [aCoder encodeObject:[self selectedTextColor]];
  1129.     if (![self useOwnerSelectedBackgroundColor])
  1130.     [aCoder encodeObject:[self selectedBackgroundColor]];
  1131.     }
  1132.  
  1133. @end
  1134.