home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / SourceCode / MiscKit1.2.6 / Palettes / MiscCalendarPalette / MiscCalendarView.subproj / MiscCalendarView.m < prev    next >
Encoding:
Text File  |  1994-05-12  |  25.2 KB  |  1,155 lines

  1. #import <objc/List.h>
  2. #import <appkit/Application.h>
  3. #import <apps/InterfaceBuilder.h>
  4. #import <appkit/Text.h>
  5. #import <appkit/TextField.h>
  6. #import <appkit/Font.h>
  7. #import <appkit/Matrix.h>
  8. #import <appkit/Box.h>
  9. #import <appkit/color.h>
  10. #import <appkit/drag.h>
  11.  
  12. #import "misckit/MiscCalendarViewConstants.h"
  13. #import "misckit/DateDelegateProtocol.h"
  14. #import "misckit/MiscCalendarView.h"
  15.  
  16. #import "DateSelectionCell.h"
  17. #import "MiscCalendarMatrix.h"
  18.  
  19. typedef struct {
  20.     int    xdelta;
  21.     int width;
  22.     const char *value;
  23. } calHeaders;
  24.  
  25.  
  26. static calHeaders headerSpecs[] = {
  27. {0, 17, "S"},
  28. {16, 19, "M"},
  29. {17, 17, "T"},
  30. {16, 20, "W"},
  31. {18, 17, "T"},
  32. {18, 17, "F"},
  33. {17, 17, "S"},
  34. {-1, -1, ""},
  35. };
  36.  
  37. @interface MiscCalendarView (TextDelegate)
  38.  
  39. - (BOOL)textWillChange:sender;
  40. - textDidChange:sender;
  41. - (BOOL)textWillEnd:sender;
  42. - textDidEnd:sender endChar:(unsigned short)whyEnd;
  43. - textDidGetKeys:sender isEmpty:(BOOL)flag;
  44.  
  45. @end
  46.  
  47. @interface MiscCalendarView (Dragging)
  48.  
  49. - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender;
  50. - draggingExited:(id <NXDraggingInfo>)sender;
  51. - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender;
  52. - (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender;
  53. - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender;
  54. - concludeDragOperation:(id <NXDraggingInfo>)sender;
  55.  
  56. @end
  57.  
  58. @interface MiscCalendarView (IBView)
  59.  
  60. - depositIBColor:(NXColor)aColor at:(NXPoint *)aPoint;
  61. - acceptsIBColorAt:(NXPoint *)aPoint;
  62.  
  63. @end
  64.  
  65. @interface MiscCalendarView (Private)
  66.  
  67. - _createTextFieldWithFrame:(NXRect *)textFrame 
  68.   stringValue:(const char *)aString;
  69. - _acceptColor:(NXColor)aColor at:(NXPoint *)aPoint;
  70.  
  71. @end
  72.  
  73. /* This helps us get rid of unwanted compiler warnings and serves */
  74. /* no useful purpose */
  75.  
  76. @protocol FAKEOUTCC
  77.  
  78. - getInspectorFor:object owner:owner;
  79. - cellColorMatrix;
  80.  
  81. @end
  82.  
  83.  
  84. @implementation MiscCalendarView
  85.  
  86. - finishUnarchiving
  87. {
  88.     /* This is called by IB In test interface mode. */
  89.     /* Register a timed-entry to be called right after */
  90.     /* this event-loop to do our final initialization. */
  91.  
  92.    /* only for IB */
  93.  
  94.     const char *pbTypes[] = {NXColorPboardType};
  95.  
  96.     [self registerForDraggedTypes:pbTypes count:1];
  97.     [[self window] registerForDraggedTypes:pbTypes count:1];
  98.  
  99.    if([NXApp conformsTo:@protocol(IB)])
  100.    {
  101.        [self perform:@selector(awakeFromNib)
  102.     with:nil afterDelay:0.01 cancelPrevious:NO];
  103.    }
  104.  
  105.    return self;
  106. }
  107.  
  108. - awakeFromNib
  109. {
  110.     const char *pbTypes[] = {NXColorPboardType};
  111.  
  112.     [self registerForDraggedTypes:pbTypes count:1];
  113.     [[self window] registerForDraggedTypes:pbTypes count:1];
  114.  
  115.     /* Setup standard calendar action method */
  116.  
  117.     [calendarMatrix setAction:@selector(updateDate:)];
  118.     [calendarMatrix setTarget:self];
  119.  
  120.     /* If there is a date delegate, set it */
  121.  
  122.     if (dateDelegate)
  123.       [calendarMatrix setDateDelegate:dateDelegate];
  124.     else
  125.       dateDelegate = [calendarMatrix dateDelegate];
  126.  
  127.     /* If there is an external month field, set its value to */
  128.     /* the month value */
  129.  
  130.     if (monthField && [monthField respondsTo:@selector(setStringValue:)])
  131.       [monthField setStringValue:[[calendarMatrix dateDelegate]
  132.                   monthStringValue]];
  133.  
  134.     /* If we are displaying the standard month header, set its value */
  135.     /* to the month */
  136.  
  137.     if (displayMonthHeader)
  138.       [monthSubview setStringValue:[[calendarMatrix dateDelegate]
  139.                     monthStringValue]];
  140.  
  141.     /* If there is an external year field, set its value to */
  142.     /* the year value */
  143.  
  144.     if (yearField && [yearField respondsTo:@selector(setIntValue:)])
  145.       [yearField setIntValue:[[calendarMatrix dateDelegate] year]];
  146.  
  147.     /* If we are displaying the standard year header, set its value */
  148.     /* to the year */
  149.  
  150.     if (displayYearHeader)
  151.       [yearSubview setIntValue:[[calendarMatrix dateDelegate]
  152.                 year]];
  153.  
  154.     if (displayMonthAndYearHeader)
  155.     {
  156.     [inlineMonthSubview setStringValue:[[calendarMatrix dateDelegate]
  157.                         monthStringValue]];
  158.  
  159.     [inlineYearSubview setIntValue:[[calendarMatrix dateDelegate]
  160.                     year]];
  161.     }
  162.  
  163.     /* If there is a date field, set its value to the curent date */
  164.  
  165.     if (dateField && [dateField respondsTo:@selector(setStringValue:)])
  166.       [dateField setStringValue:[[calendarMatrix dateDelegate]
  167.                  dateStringValue]];
  168.  
  169.     return self;
  170. }
  171.  
  172. - initFrame:(const NXRect *)frameRect
  173. {
  174.     NXRect     subViewFrame;
  175.     id        newSubview;
  176.     calHeaders    *headers;
  177.     const char *pbTypes[] = {NXColorPboardType};
  178.  
  179.     [super initFrame:frameRect];
  180.  
  181.     [self registerForDraggedTypes:pbTypes count:1];
  182.     [[self window] registerForDraggedTypes:pbTypes count:1];
  183.  
  184.     colorDragAndDrop = NO;
  185.  
  186.     /* The list of textfield cells that holds the day of the week */
  187.     /* headings */
  188.  
  189.     dowSubviewList = [[List alloc] init];
  190.  
  191.     displayDOWHeader = YES;
  192.     displayMonthHeader = NO;
  193.     displayYearHeader = NO;
  194.     displayMonthAndYearHeader = NO;
  195.  
  196.     headers = headerSpecs;
  197.  
  198.     /* static view information for day-of-the-week textfield headers */
  199.  
  200.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  201.           DEFAULT_MATRIX_WIDTH, DEFAULT_HEADER_HEIGHT);
  202.          
  203.     /* Create the day of the week headers (S, M, T, W...) */
  204.  
  205.     while(headers->xdelta > -1)
  206.     {
  207.       NX_X(&subViewFrame) += headers->xdelta;
  208.       NX_WIDTH(&subViewFrame) = headers->width;
  209.  
  210.       newSubview = [self _createTextFieldWithFrame:&subViewFrame
  211.             stringValue:headers->value];
  212.  
  213.       [dowSubviewList addObject:newSubview];
  214.  
  215.       [self addSubview:newSubview];
  216.  
  217.       headers++;
  218.     }
  219.  
  220.     /* Create the month and year textfield headers */
  221.  
  222.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  223.           DEFAULT_MATRIX_WIDTH, DEFAULT_HEADER_HEIGHT);
  224.  
  225.     monthSubview = [self _createTextFieldWithFrame:&subViewFrame
  226.             stringValue:"Month"];
  227.  
  228.     yearSubview = [self _createTextFieldWithFrame:&subViewFrame
  229.            stringValue:"Year"];
  230.  
  231.     [Font setUserFont:[Font newFont:"Helvetica" size:12 style:0
  232.                matrix:NX_FLIPPEDMATRIX]];
  233.  
  234.     [monthSubview setFont:[Font boldSystemFontOfSize:12
  235.               matrix:NX_FLIPPEDMATRIX]];
  236.  
  237.     [yearSubview setFont:[Font boldSystemFontOfSize:12
  238.               matrix:NX_FLIPPEDMATRIX]];
  239.  
  240.     /* Create the month and year textfield headers, where the month */
  241.     /* and year are on the same line */
  242.  
  243.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  244.           (int)(DEFAULT_MATRIX_WIDTH/2), DEFAULT_HEADER_HEIGHT);
  245.  
  246.     inlineMonthSubview = [self _createTextFieldWithFrame:&subViewFrame
  247.               stringValue:"Month"];
  248.  
  249.     [inlineMonthSubview setAlignment:NX_LEFTALIGNED];
  250.  
  251.     [inlineMonthSubview setFont:[Font boldSystemFontOfSize:12
  252.                  matrix:NX_FLIPPEDMATRIX]];
  253.  
  254.     NXSetRect(&subViewFrame, 
  255.           ((DEFAULT_MATRIX_WIDTH - (int)(DEFAULT_MATRIX_WIDTH/2) + 
  256.         DEFAULT_MATRIX_XPOS+1)), 
  257.           DEFAULT_HEADER_YPOS, (int)(DEFAULT_MATRIX_WIDTH/2),
  258.           DEFAULT_HEADER_HEIGHT);
  259.  
  260.     inlineYearSubview = [self _createTextFieldWithFrame:&subViewFrame
  261.              stringValue:"Year"];
  262.  
  263.     [inlineYearSubview setAlignment:NX_RIGHTALIGNED];
  264.  
  265.     [inlineYearSubview setFont:[Font boldSystemFontOfSize:12
  266.                 matrix:NX_FLIPPEDMATRIX]];
  267.  
  268.     /* Create the actual calendar matrix view with the given */
  269.     /* dimensions */
  270.  
  271.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS, DEFAULT_MATRIX_YPOS,
  272.           DEFAULT_MATRIX_WIDTH, DEFAULT_MATRIX_HEIGHT);
  273.  
  274.     calendarMatrix = [[MiscCalendarMatrix alloc] initFrame:&subViewFrame];
  275.  
  276.     [calendarMatrix setAutosizing:NX_MINYMARGINSIZABLE | 
  277.      NX_MAXYMARGINSIZABLE | NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
  278.  
  279.     [calendarMatrix setAutosizeCells:YES];
  280.  
  281.     [calendarMatrix setAction:@selector(updateDate:)];
  282.     [calendarMatrix setTarget:self];
  283.  
  284.     if (dateDelegate)
  285.       [calendarMatrix setDateDelegate:dateDelegate];
  286.     else
  287.       dateDelegate = [calendarMatrix dateDelegate];
  288.  
  289.     previousDayCell = [calendarMatrix selectedCell];
  290.  
  291.     /* Added the calendar matrix to our view */
  292.  
  293.     [self addSubview:calendarMatrix];
  294.  
  295.     if (monthField && [monthField respondsTo:@selector(setStringValue:)])
  296.       [monthField setStringValue:[[calendarMatrix dateDelegate]
  297.                   monthStringValue]];
  298.  
  299.     if (yearField && [yearField respondsTo:@selector(setIntValue:)])
  300.       [yearField setIntValue:[[calendarMatrix dateDelegate] year]];
  301.  
  302.     if (dateField && [dateField respondsTo:@selector(setStringValue:)])
  303.       [dateField setStringValue:[[calendarMatrix dateDelegate]
  304.                  dateStringValue]];
  305.  
  306.     NX_WIDTH(&defaultFrame) = frameRect->size.width;
  307.     NX_HEIGHT(&defaultFrame) = frameRect->size.height;
  308.  
  309.     return self;
  310. }
  311.  
  312. - getMinSize:(NXSize *)minSize maxSize:(NXSize *)maxSize from:(int)where
  313. {
  314.     /* The view is not sizable at this time */
  315.  
  316.     minSize->width = NX_WIDTH(&defaultFrame);
  317.     minSize->height = NX_HEIGHT(&defaultFrame);
  318.  
  319.     maxSize->width = NX_WIDTH(&defaultFrame);
  320.     maxSize->height = NX_HEIGHT(&defaultFrame);
  321.  
  322.     return self;
  323. }
  324.  
  325. - calendarMatrix
  326. {
  327.     return calendarMatrix;
  328. }
  329.  
  330. - preserveCellColors:(BOOL)yn
  331. {
  332.     [calendarMatrix overwriteCellColors:yn];
  333.  
  334.     return self;
  335. }
  336.  
  337. - (BOOL)cellColorsPreserved
  338. {
  339.     return [calendarMatrix cellColorsOverwritten];
  340. }
  341.  
  342. - setColorOf:(int)element to:(NXColor)aColor forCellAt:(int)xPos :(int)yPos
  343. {
  344.     switch (element)
  345.     {
  346.       case MISC_CV_CELLBACKGROUND:
  347.     [calendarMatrix setBackgroundColor:aColor forCellAt:xPos :yPos];
  348.     [calendarMatrix display];
  349.     break;
  350.  
  351.       case MISC_CV_CELLTEXT:
  352.     [calendarMatrix setTextColor:aColor forCellAt:xPos :yPos];
  353.     [calendarMatrix display];
  354.     break;
  355.  
  356.       case MISC_CV_CELLHIGHLIGHT:
  357.     [calendarMatrix setHighlightColor:aColor forCellAt:xPos :yPos];
  358.     [calendarMatrix display];
  359.     break;
  360.  
  361.       case MISC_CV_CELLTEXTHIGHLIGHT:
  362.     [calendarMatrix setHighlightTextColor:aColor forCellAt:xPos :yPos];
  363.     [calendarMatrix display];
  364.     break;
  365.  
  366.       default:
  367.     break;
  368.     }
  369.     
  370.     return self;
  371. }
  372.  
  373. - (NXColor)colorOf:(int)element forCellAt:(int)xPos :(int)yPos
  374. {
  375.     NXColor color;
  376.  
  377.     color = NX_COLORBLACK;
  378.  
  379.     switch (element)
  380.     {
  381.       case MISC_CV_CELLBACKGROUND:
  382.     color = [calendarMatrix backgroundColorForCellAt:xPos :yPos];
  383.     break;
  384.  
  385.       case MISC_CV_CELLTEXT:
  386.     color = [calendarMatrix textColorForCellAt:xPos :yPos];
  387.     break;
  388.  
  389.       case MISC_CV_CELLHIGHLIGHT:
  390.     color = [calendarMatrix highlightColorForCellAt:xPos :yPos];
  391.     break;
  392.  
  393.       case MISC_CV_CELLTEXTHIGHLIGHT:
  394.     color =[calendarMatrix highlightTextColorForCellAt:xPos :yPos];
  395.     break;
  396.  
  397.       default:
  398.     break;
  399.     }
  400.     
  401.     return color;
  402. }
  403.  
  404. - setColorOf:(int)element to:(NXColor)aColor
  405. {
  406.     switch (element)
  407.     {
  408.       case MISC_CV_CELLBACKGROUND:
  409.     [calendarMatrix setCellBackgroundColor:aColor];
  410.     [calendarMatrix display];
  411.     break;
  412.  
  413.       case MISC_CV_CELLTEXT:
  414.     [calendarMatrix setCellTextColor:aColor];
  415.     [calendarMatrix display];
  416.     break;
  417.  
  418.       case MISC_CV_CELLHIGHLIGHT:
  419.     [calendarMatrix setCellHighlightColor:aColor];
  420.     [calendarMatrix display];
  421.     break;
  422.  
  423.       case MISC_CV_CELLTEXTHIGHLIGHT:
  424.     [calendarMatrix setCellHighlightTextColor:aColor];
  425.     [calendarMatrix display];
  426.     break;
  427.  
  428.       case MISC_CV_MONTHHEADER:
  429.     [monthSubview setTextColor:aColor];
  430.     [monthSubview display];
  431.     break;
  432.  
  433.       case MISC_CV_YEARHEADER:
  434.     [yearSubview setTextColor:aColor];
  435.     [yearSubview display];
  436.     break;
  437.  
  438.       case MISC_CV_INLINEMONTHHEADER:
  439.     [inlineMonthSubview setTextColor:aColor];
  440.     [inlineMonthSubview display];
  441.     break;
  442.  
  443.       case MISC_CV_INLINEYEARHEADER:
  444.     [inlineYearSubview setTextColor:aColor];
  445.     [inlineYearSubview display];
  446.     break;
  447.  
  448.       default:
  449.     break;
  450.     }
  451.     
  452.     return self;
  453. }
  454.  
  455. - (NXColor)colorOf:(int)element
  456. {
  457.     NXColor color;
  458.  
  459.     switch (element)
  460.     {
  461.       case MISC_CV_CELLBACKGROUND:
  462.     color = [calendarMatrix cellBackgroundColor];
  463.     break;
  464.  
  465.       case MISC_CV_CELLTEXT:
  466.     color = [calendarMatrix cellTextColor];
  467.     break;
  468.  
  469.       case MISC_CV_CELLHIGHLIGHT:
  470.     color = [calendarMatrix cellHighlightColor];
  471.     break;
  472.  
  473.       case MISC_CV_CELLTEXTHIGHLIGHT:
  474.     color = [calendarMatrix cellHighlightTextColor];
  475.     break;
  476.  
  477.       case MISC_CV_MONTHHEADER:
  478.     color = [monthSubview textColor];
  479.     break;
  480.  
  481.       case MISC_CV_YEARHEADER:
  482.     color = [yearSubview textColor];
  483.     break;
  484.  
  485.       case MISC_CV_INLINEMONTHHEADER:
  486.     color = [inlineMonthSubview textColor];
  487.     break;
  488.  
  489.       case MISC_CV_INLINEYEARHEADER:
  490.     color = [inlineYearSubview textColor];
  491.     break;
  492.  
  493.       default:
  494.     color = NX_COLORBLACK;
  495.     break;
  496.     }
  497.     
  498.     return color;
  499. }
  500.  
  501. - cellAt:(int)xPos :(int)yPos lock:(BOOL)yn
  502. {
  503.     [[calendarMatrix cellAt:xPos :yPos] setEnabled:yn];
  504.  
  505.     return self;
  506. }
  507.  
  508. - forRow:(int)row lock:(BOOL)yn
  509. {
  510.     int i;
  511.  
  512.     for (i = 0; i < NUM_MATRIX_COLS; i++)
  513.       [self cellAt:row :i lock:yn];
  514.  
  515.     return self;
  516. }
  517.  
  518. - forColumn:(int)col lock:(BOOL)yn
  519. {
  520.     int i;
  521.  
  522.     for (i = 0; i < NUM_MATRIX_ROWS; i++)
  523.       [self cellAt:i :col lock:yn];
  524.  
  525.     return self;
  526. }
  527.  
  528. - setHighlightMode:(int)mode
  529. {
  530.     return [calendarMatrix setMode:mode];
  531. }
  532.  
  533. - (int)highlightMode
  534. {
  535.     return [calendarMatrix mode];
  536. }
  537.  
  538. - allowColorDragAndDrop:(BOOL)yn
  539. {
  540.     colorDragAndDrop = yn;
  541.  
  542.     return self;
  543. }
  544.  
  545. - (BOOL)canDragAndDropColor
  546. {
  547.     return colorDragAndDrop;
  548. }
  549.  
  550. - forHeader:(int)aHeader display:(BOOL)doDisplay
  551. {
  552.     int        yOffset,
  553.         i;
  554.     
  555.     NX_HEIGHT(&defaultFrame) += doDisplay ? DEFAULT_HEADER_HEIGHT : 
  556.       -DEFAULT_HEADER_HEIGHT;
  557.  
  558.     [self sizeBy:0 :(doDisplay ? DEFAULT_HEADER_HEIGHT : 
  559.              -DEFAULT_HEADER_HEIGHT)];
  560.     
  561.     yOffset = doDisplay ? DEFAULT_HEADER_HEIGHT :
  562.       -DEFAULT_HEADER_HEIGHT;
  563.       
  564.     switch (aHeader)
  565.     {
  566.       case MISC_CV_DOWHEADER:
  567.     displayDOWHeader = doDisplay;
  568.  
  569.     if (displayMonthAndYearHeader)
  570.     {
  571.         [inlineMonthSubview moveBy:0 :yOffset];
  572.         [inlineYearSubview moveBy:0 :yOffset];
  573.     }
  574.  
  575.     if (displayMonthHeader)
  576.       [monthSubview moveBy:0 :yOffset];
  577.  
  578.     if (displayYearHeader)
  579.       [yearSubview moveBy:0 :yOffset];
  580.     
  581.     if (displayDOWHeader)
  582.       for (i = 0; i < [dowSubviewList count]; i++)
  583.         [self addSubview:[dowSubviewList objectAt:i]];
  584.     else
  585.         for (i = 0; i < [dowSubviewList count]; i++)
  586.           [[dowSubviewList objectAt:i] removeFromSuperview];
  587.  
  588.     break;
  589.  
  590.       case MISC_CV_MONTHANDYEARHEADER:
  591.     displayMonthAndYearHeader = doDisplay;
  592.     
  593.     if (displayYearHeader)
  594.       [yearSubview moveBy:0 :yOffset];
  595.  
  596.     if (displayMonthHeader)
  597.       [monthSubview moveBy:0 :yOffset];
  598.  
  599.     if (displayDOWHeader)
  600.     {
  601.         [inlineMonthSubview moveBy:0 :yOffset];
  602.         [inlineYearSubview moveBy:0 :yOffset];
  603.     }
  604.  
  605.     if (displayMonthAndYearHeader)
  606.     {
  607.         [self addSubview:inlineMonthSubview];
  608.         [self addSubview:inlineYearSubview];
  609.     }
  610.     else
  611.     {
  612.         [inlineMonthSubview removeFromSuperview];
  613.         [inlineYearSubview removeFromSuperview];
  614.     }
  615.  
  616.     break;
  617.  
  618.       case MISC_CV_MONTHHEADER:
  619.     displayMonthHeader = doDisplay;
  620.  
  621.     if (displayYearHeader)
  622.       [yearSubview moveBy:0 :yOffset];
  623.  
  624.     if (displayDOWHeader)
  625.       [monthSubview moveBy:0 :yOffset];
  626.  
  627.     if (displayMonthAndYearHeader)
  628.       [monthSubview moveBy:0 :yOffset];
  629.  
  630.     if (displayMonthHeader)
  631.       [self addSubview:monthSubview];
  632.     else
  633.       [monthSubview removeFromSuperview];
  634.  
  635.     break;
  636.  
  637.       case MISC_CV_YEARHEADER:
  638.     displayYearHeader = doDisplay;
  639.  
  640.     if (displayDOWHeader)
  641.       [yearSubview moveBy:0 :yOffset];
  642.  
  643.     if (displayMonthAndYearHeader)
  644.       [yearSubview moveBy:0 :yOffset];
  645.  
  646.     if (displayMonthHeader)
  647.       [yearSubview moveBy:0 :yOffset];
  648.  
  649.     if (displayYearHeader)
  650.       [self addSubview:yearSubview];
  651.     else
  652.       [yearSubview removeFromSuperview];
  653.  
  654.     break;
  655.     
  656.       default:
  657.     NX_HEIGHT(&defaultFrame) += !doDisplay ? DEFAULT_HEADER_HEIGHT : 
  658.       -DEFAULT_HEADER_HEIGHT;
  659.  
  660.     [self sizeBy:0 :(!doDisplay ? DEFAULT_HEADER_HEIGHT : 
  661.              -DEFAULT_HEADER_HEIGHT)];
  662.     
  663.     break;
  664.     }
  665.  
  666.     return self;
  667. }
  668.  
  669. - (BOOL)isHeaderDisplayed:(int)aHeader;
  670. {
  671.     switch (aHeader)
  672.     {
  673.       case MISC_CV_DOWHEADER:
  674.     return displayDOWHeader;
  675.     break;
  676.     
  677.       case MISC_CV_MONTHHEADER:
  678.     return displayMonthHeader;
  679.     break;
  680.  
  681.       case MISC_CV_YEARHEADER:
  682.     return displayYearHeader;
  683.     break;
  684.  
  685.       case MISC_CV_MONTHANDYEARHEADER:
  686.     return displayMonthAndYearHeader;
  687.     break;
  688.  
  689.       default:
  690.     return NO;
  691.     }
  692. }
  693.  
  694. - setColorTo:(NXColor)aColor forDay:(MiscCVDays)aDay
  695. {
  696.     return [[[dowSubviewList objectAt:aDay] setTextColor:aColor] display];
  697. }
  698.  
  699. - (NXColor)colorForDay:(MiscCVDays)aDay
  700. {
  701.     return [[dowSubviewList objectAt:aDay] textColor];
  702. }
  703.  
  704. - incrementMonth:sender
  705. {
  706.     id date;
  707.  
  708.     date = [calendarMatrix dateDelegate];
  709.  
  710.     [date incrementMonth];
  711.  
  712.     [self updateDate:self];
  713.  
  714.     previousDayCell = [calendarMatrix selectedCell];
  715.  
  716.     return self;
  717. }
  718.  
  719. - decrementMonth:sender
  720. {
  721.     id date;
  722.  
  723.     date = [calendarMatrix dateDelegate];
  724.  
  725.     [date decrementMonth];
  726.  
  727.     [self updateDate:self];
  728.  
  729.     previousDayCell = [calendarMatrix selectedCell];
  730.  
  731.     return self;
  732. }
  733.  
  734. - incrementYear:sender
  735. {
  736.     id date;
  737.  
  738.     date = [calendarMatrix dateDelegate];
  739.  
  740.     [date incrementYear];
  741.  
  742.     [self updateDate:self];
  743.  
  744.     previousDayCell = [calendarMatrix selectedCell];
  745.  
  746.     return self;
  747. }
  748.  
  749. - decrementYear:sender
  750. {
  751.     id date;
  752.  
  753.     date = [calendarMatrix dateDelegate];
  754.  
  755.     [date decrementYear];
  756.  
  757.     [self updateDate:self];
  758.  
  759.     previousDayCell = [calendarMatrix selectedCell];
  760.  
  761.     return self;
  762. }
  763.  
  764. - updateDate:sender
  765. {
  766.     DateSelectionCell    *dayCell;
  767.     id            date;
  768.     int            day,
  769.             month,
  770.             year;
  771.  
  772.     if (!(dayCell = [calendarMatrix selectedCell]))
  773.     {
  774.     if (previousDayCell)
  775.       [calendarMatrix selectCell:previousDayCell];
  776.  
  777.     return nil;
  778.     }
  779.  
  780.     dayCell = [calendarMatrix selectedCell];
  781.  
  782.     previousDayCell = dayCell;
  783.  
  784.     date = [calendarMatrix dateDelegate];
  785.  
  786.     day = [dayCell intValue];
  787.     month = [date month];
  788.     year = [date year];
  789.  
  790.     [date setYear:year month:month day:day];
  791.  
  792.     [self displayDate:self];
  793.  
  794.     return self;
  795. }
  796.  
  797. - displayDate:sender
  798. {
  799.     if (monthField && [monthField respondsTo:@selector(setStringValue:)])
  800.       [monthField setStringValue:[[calendarMatrix dateDelegate]
  801.                   monthStringValue]];
  802.  
  803.     if (displayMonthHeader)
  804.       [monthSubview setStringValue:[[calendarMatrix dateDelegate]
  805.                     monthStringValue]];
  806.  
  807.     if (yearField && [yearField respondsTo:@selector(setIntValue:)])
  808.       [yearField setIntValue:[[calendarMatrix dateDelegate] year]];
  809.  
  810.     if (displayYearHeader)
  811.       [yearSubview setIntValue:[[calendarMatrix dateDelegate]
  812.                 year]];
  813.  
  814.     if (dateField && [dateField respondsTo:@selector(setStringValue:)])
  815.       [dateField setStringValue:[[calendarMatrix dateDelegate]
  816.                  dateStringValue]];
  817.  
  818.     if (displayMonthAndYearHeader)
  819.     {
  820.     [inlineMonthSubview setStringValue:[[calendarMatrix dateDelegate]
  821.                         monthStringValue]];
  822.  
  823.     [inlineYearSubview setIntValue:[[calendarMatrix dateDelegate]
  824.                     year]];
  825.     }
  826.  
  827.     [calendarMatrix displayDate:sender];
  828.  
  829.     return self;
  830. }
  831.  
  832. - setDateDelegate:(id <DateDelegate>)anObject
  833. {
  834.     dateDelegate = anObject;
  835.  
  836.     return self;
  837. }
  838.  
  839. - (id <DateDelegate>)dateDelegate
  840. {
  841.     return dateDelegate;
  842. }
  843.  
  844. - (const char *)getInspectorClassName
  845. {
  846.     return "MiscCalendarViewInspector";
  847. }
  848.  
  849. - (const char *)getEditorClassName
  850. {
  851.     return "MiscCalendarViewEditor";
  852. }
  853.  
  854. - read:(NXTypedStream *)aStream
  855. {
  856.     float    width,
  857.         height;
  858.  
  859.     [super read:aStream];
  860.  
  861.     NXReadTypes(aStream, "fficcccc@@@@@@@@@@@", &width, &height,
  862.         &titleDisplayMode, &displayDOWHeader, &displayMonthHeader, 
  863.         &displayYearHeader, &displayMonthAndYearHeader,
  864.         &colorDragAndDrop,
  865.         &calendarMatrix, &monthField, &previousDayCell, &monthSubview,
  866.         &dateDelegate, &yearField, &dateField, &dowSubviewList, 
  867.         &yearSubview, &inlineMonthSubview, &inlineYearSubview);
  868.  
  869.     NX_WIDTH(&defaultFrame) = width;
  870.     NX_HEIGHT(&defaultFrame) = height;
  871.  
  872.     return self;
  873. }
  874.  
  875. - write:(NXTypedStream *)aStream
  876. {
  877.     [super write:aStream];
  878.  
  879.     NXWriteTypes(aStream, "fficcccc@@@@@@@@@@@", &(NX_WIDTH(&defaultFrame)),
  880.          &(NX_HEIGHT(&defaultFrame)), &titleDisplayMode, 
  881.          &displayDOWHeader, &displayMonthHeader, &displayYearHeader,
  882.          &displayMonthAndYearHeader, &colorDragAndDrop, 
  883.          &calendarMatrix, &monthField,
  884.          &previousDayCell, &monthSubview, &dateDelegate, &yearField,
  885.          &dateField, &dowSubviewList, &yearSubview, 
  886.          &inlineMonthSubview, &inlineYearSubview);
  887.  
  888.     return self;
  889. }
  890.  
  891. @end
  892.  
  893. @implementation MiscCalendarView (TextDelegate)
  894.  
  895. - (BOOL)textWillChange:sender
  896. {
  897.     if (textDelegate && [textDelegate respondsTo:@selector(textWillChange:)])
  898.       return [textDelegate textWillChange:sender];
  899.     else
  900.       return NO;
  901. }
  902.  
  903. - textDidChange:sender
  904. {
  905.     if (textDelegate && [textDelegate respondsTo:@selector(textDidChange:)])
  906.       return [textDelegate textDidChange:sender];
  907.     else
  908.       return self;
  909. }
  910.  
  911. - (BOOL)textWillEnd:sender
  912. {
  913.     if (textDelegate && [textDelegate respondsTo:@selector(textWillEnd:)])
  914.       return [textDelegate textWillEnd:sender];
  915.     else
  916.       return NO;
  917. }
  918.  
  919. - textDidEnd:sender endChar:(unsigned short)whyEnd
  920. {
  921.     id retCode = self;
  922.  
  923.     if (textDelegate && [textDelegate 
  924.              respondsTo:@selector(textDidEnd:endChar:)])
  925.     {
  926.     retCode = [textDelegate textDidEnd:sender endChar:whyEnd];
  927.  
  928.     [self updateDate:self];
  929.     }
  930.  
  931.     return retCode;
  932. }
  933.  
  934. - textDidGetKeys:sender isEmpty:(BOOL)flag
  935. {
  936.     if (textDelegate && [textDelegate 
  937.              respondsTo:@selector(textDidGetKeys:isEmpty:)])
  938.       return [textDelegate textDidGetKeys:sender isEmpty:flag];
  939.     else
  940.       return self;
  941. }
  942.  
  943. @end
  944.  
  945. @implementation MiscCalendarView (Dragging)
  946.  
  947. - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
  948. {
  949.     NXRect    aRect;
  950.     NXPoint    mouseLocation;
  951.  
  952.     if (([sender draggingSourceOperationMask] & NX_DragOperationCopy) &&
  953.     colorDragAndDrop)
  954.     {
  955.     NXSetRect(&aRect, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  956.           DEFAULT_MATRIX_WIDTH, 0);
  957.  
  958.     if (displayDOWHeader)
  959.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  960.  
  961.     if (displayMonthAndYearHeader)
  962.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  963.  
  964.     if (displayMonthHeader)
  965.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  966.  
  967.     if (displayYearHeader)
  968.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  969.  
  970.     mouseLocation = [sender draggingLocation];
  971.  
  972.     [self convertPoint:&mouseLocation toView:self];
  973.  
  974.     if (NXMouseInRect(&mouseLocation, &aRect, NO))
  975.       return NX_DragOperationCopy;
  976.     }
  977.  
  978.     return NX_DragOperationNone;
  979. }
  980.  
  981. - draggingExited:(id <NXDraggingInfo>)sender
  982. {
  983.     return self;
  984. }
  985.  
  986. - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender
  987. {
  988.     return [self draggingEntered:sender];
  989. }
  990.  
  991. - (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender
  992. {
  993.     if ([self draggingEntered:sender] == NX_DragOperationCopy)
  994.       return YES;
  995.  
  996.     return NO;
  997. }
  998.  
  999. - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender
  1000. {
  1001.     NXColor    color;
  1002.     NXPoint    mouseLocation;
  1003.  
  1004.     color = NXReadColorFromPasteboard([sender draggingPasteboard]);
  1005.     
  1006.     mouseLocation = [sender draggingLocation];
  1007.     
  1008.     if ([self _acceptColor:color at:&mouseLocation])
  1009.       return YES;
  1010.  
  1011.     return NO;
  1012. }
  1013.  
  1014. - concludeDragOperation:(id <NXDraggingInfo>)sender
  1015. {
  1016.     return self;
  1017. }
  1018.  
  1019. @end
  1020.  
  1021. /* Satan made me do it! Okay, well, maybe not, but jeez NeXT, if you */
  1022. /* would just publish some of these APIs so us lowly end-user programmer */
  1023. /* could do all the neat things you get to do, ugly rule-breaking hacks */
  1024. /* like this would not happen. sigh.... Anyway, these two methods allow */
  1025. /* my view to accept drag-and-drop color in IB, just like textfield does. */
  1026. /* Thanks to the person who wrote ClassDump and Robert Nicholson for */
  1027. /* helping me find these... */
  1028.  
  1029. @implementation MiscCalendarView (IBView)
  1030.  
  1031. - depositIBColor:(NXColor)aColor at:(NXPoint *)aPoint
  1032. {
  1033.     NXPoint    mouseLocation;
  1034.     int        cellColorSelection;
  1035.  
  1036.     mouseLocation.x = aPoint->x;
  1037.     mouseLocation.y = aPoint->y;
  1038.  
  1039.     if (![self _acceptColor:aColor at:&mouseLocation])
  1040.     {
  1041.     cellColorSelection = [[[[NXApp getInspectorFor:self owner:self] 
  1042.                   cellColorMatrix] selectedCell] tag];
  1043.  
  1044.     [self setColorOf:cellColorSelection to:aColor];
  1045.     }
  1046.  
  1047.     return self;
  1048. }
  1049.  
  1050. - acceptsIBColorAt:(NXPoint *)aPoint;
  1051. {
  1052.     return self;
  1053. }
  1054.  
  1055. @end
  1056.  
  1057. @implementation MiscCalendarView (Private)
  1058.  
  1059. - _createTextFieldWithFrame:(NXRect *)textFrame 
  1060.   stringValue:(const char *)aString
  1061. {
  1062.     TextField    *textField;
  1063.  
  1064.     textField = [[TextField alloc] initFrame:textFrame];
  1065.     [textField setEditable:NO];
  1066.     [textField setBezeled:NO];
  1067.     [textField setBordered:NO];
  1068.     [textField setSelectable:NO];
  1069.     [textField setAlignment:NX_CENTERED];
  1070.     [textField setBackgroundGray:-1];
  1071.     
  1072.     [textField setAutosizing:NX_MINYMARGINSIZABLE | 
  1073.      NX_MAXYMARGINSIZABLE | NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
  1074.  
  1075.     [Font setUserFont:[Font newFont:"Helvetica" size:11 style:0
  1076.                matrix:NX_FLIPPEDMATRIX]];
  1077.  
  1078.     [textField setFont:[Font boldSystemFontOfSize:11
  1079.             matrix:NX_FLIPPEDMATRIX]];
  1080.  
  1081.     [textField setStringValue:aString];
  1082.  
  1083.     return textField;
  1084. }
  1085.  
  1086. - _acceptColor:(NXColor)aColor at:(NXPoint *)aPoint
  1087. {
  1088.     TextField    *textField;
  1089.     NXPoint    mouseLocation;
  1090.     NXRect    aRect;
  1091.     int     i;
  1092.  
  1093.     mouseLocation.x = aPoint->x;
  1094.     mouseLocation.y = aPoint->y;
  1095.  
  1096.     textField = nil;
  1097.  
  1098.     [self convertPoint:&mouseLocation fromView:[self superview]];
  1099.  
  1100.     if (displayDOWHeader)
  1101.       for (i = 0; i < [dowSubviewList count]; i++)
  1102.       {
  1103.       [[dowSubviewList objectAt:i] getFrame:&aRect];
  1104.  
  1105.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1106.       {
  1107.           textField = [dowSubviewList objectAt:i];
  1108.           i = [dowSubviewList count];
  1109.       }
  1110.       }
  1111.  
  1112.     if (!textField && displayMonthAndYearHeader)
  1113.     {
  1114.     [inlineMonthSubview getFrame:&aRect];
  1115.  
  1116.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1117.         textField = inlineMonthSubview;
  1118.     }
  1119.  
  1120.     if (!textField && displayMonthAndYearHeader)
  1121.     {
  1122.     [inlineYearSubview getFrame:&aRect];
  1123.  
  1124.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1125.         textField = inlineYearSubview;
  1126.     }
  1127.  
  1128.     if (!textField && displayMonthHeader)
  1129.     {
  1130.     [monthSubview getFrame:&aRect];
  1131.  
  1132.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1133.         textField = monthSubview;
  1134.     }
  1135.  
  1136.     if (!textField && displayYearHeader)
  1137.     {
  1138.     [yearSubview getFrame:&aRect];
  1139.  
  1140.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1141.         textField = yearSubview;
  1142.     }
  1143.  
  1144.     if (textField)
  1145.     {
  1146.     [textField setTextColor:aColor];
  1147.     return self;
  1148.     }
  1149.     
  1150.     return nil;
  1151. }
  1152.  
  1153. @end
  1154.  
  1155.