home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / AppKit / Draw / SyncScrollView.m < prev    next >
Encoding:
Text File  |  1992-07-22  |  1.3 GB  |  444 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. #import "draw.h"
  2.  
  3. @implementation SyncScrollView
  4. /*
  5.  * This subclass of ScrollView is extremely useful for programmers
  6.  * who want some View to scroll along with a main docView.  A good
  7.  * example is a spreadsheet that wants its column and row headings
  8.  * to scroll along with the cells in the spreadsheet itself.
  9.  * It is actually quite simple.  We simply override tile to place
  10.  * two ClipViews with our views (rulers in this case) in them into
  11.  * the view hierarchy, then override scrollClip:to: to update their
  12.  * drawing origins when the docView is scrolled.  We also override
  13.  * reflectScroll: since we don't want that to apply to our little
  14.  * ruler views, only to the main docView.
  15.  */
  16.  
  17. - setRulerClass:factoryId
  18. {
  19.     if ([factoryId conformsTo:@protocol(Ruler)]) rulerClass = factoryId;
  20.     return self;
  21. }
  22.  
  23. - setRulerWidths:(NXCoord)horizontal :(NXCoord)vertical
  24. {
  25.     horizontalRulerWidth = horizontal;
  26.     verticalRulerWidth = vertical;
  27.     return self;
  28. }
  29.  
  30. - (BOOL)bothRulersAreVisible
  31. {
  32.     return verticalRulerIsVisible && horizontalRulerIsVisible;
  33. }
  34.  
  35. - (BOOL)eitherRulerIsVisible
  36. {
  37.     return verticalRulerIsVisible || horizontalRulerIsVisible;
  38. }
  39.  
  40. - (BOOL)verticalRulerIsVisible
  41. {
  42.     return verticalRulerIsVisibleRV4
  43. - (BOOL)horizontalRulerIsVisible
  44. {
  45.     return horizontalRulerIsVisible;
  46. }
  47.  
  48. - setRulerOrigin:(RulerOrigin)origin
  49. {
  50.     RulerOrigin oldRulerOrigin = rulerOrigin;
  51.  
  52.     rulerOrigin = origin;
  53.     switch (origin) {
  54.     case LowerRight:
  55.         [[hClipRuler docView] setFlipped:YES];
  56.         break;
  57.     case UpperRight:
  58.         [[hClipRuler docView] setFlipped:YES];
  59.     case UpperLeft:
  60.         [[vClipRuler docView] setFlipped:YES];
  61.     case LowerLeft:
  62.         break;
  63.     default:
  64.         rulerOrigin = oldRulerOrigin;
  65.         break;
  66.     }
  67.  
  68.     return self;
  69. }
  70.  
  71. - makeRulers
  72. /*
  73.  * This makes the rulers.
  74.  * We do this lazily in case the user never asks for the rulers.
  75.  */
  76. {
  77.     View <Ruler> *ruler;
  78.     NXRect aRect, bRect;
  79.  
  80.     if (!rulerClass || (!horizontalRulerWidth && !verticalRulerWidth)) return nil;
  81.  
  82.     if (horizontalRulerWidth) {
  83.     [[contentView docView] getFrame:&aRect];
  84.     NXDivideRect(&aRect, &bRect, horizontalRulerWidth, NX_YMIN);
  85.     hClipRuler = [[ClipView allocFromZone:[self zone]] init];
  86.     ruler = [[rulerClass allocFromZone:[self zone]] initFrame:&bRect];
  87.     [hClipRuler setDocView:ruler];
  88.     }
  89.     if (verticalRulerWidth) {
  90.     [[contentView docView] getFrame:&aRect];
  91.     NXDivideRect(&aRect, &bRect, verticalRulerWidth, NX_XMIN);
  92.     vClipRuler = [[ClipView allocFromZone:[self zone]] init];
  93.     ruler = [[rulerClass allocFromZone:[self zone]] initFrame:&bRect];
  94.     [vClipRuler setDocView:ruler];
  95.     }
  96.     [self setRulerOrigin:rulerOrigin];
  97.     rulersMade = 1;
  98.  
  99.     return self;
  100. }
  101.  
  102. - updateRulers:(const NXRect *)rect
  103. {
  104.     if (!rect) {
  105.     if (verticalRulerIsVisible) {
  106.         [[vClipRuler docView] hidePosition];
  107.     }
  108.     if (horizontalRulerIsVisible) {
  109.         [[hClipRuler docView] hidePosition];
  110.     }
  111.     } else {
  112.     if (verticalRulerIsVisible) {
  113.         [[vClipRuler docView] showPosition:rect->origin.y :rect->origin.y + rect->size.height];
  114.     }
  115.     if (horizontalRulerIsVisible) {
  116.         [[hClipRuler docView] showPosition:rect->origin.x :rect->origin.x + rect->size.width];
  117.     }
  118.     }
  119.  
  120.     return self;
  121. }
  122.  
  123. - updateRuler
  124. {
  125.     NXRect aRect, bRect;
  126.  
  127.     if (horizontalRulerIsVisible) {
  128.     [[contentView docView] getFrame:&aRect];
  129.     NXDivideRect(&aRect, &bRect, horizontalRulerWidth, NX_YMIN);
  130.     bRect.size.width += verticalRulerWidth;
  131.     [[hClipRuler docView] setFrame:&bRect];
  132.     [hClipRuler display];
  133.     }
  134.     if (verticalRulerIsVisible) {
  135.     [[contentView docView] getFrame:&aRect];
  136.     NXDivideRect(&aRect, &bRect,RV5ticalRulerWidth, NX_XMIN);
  137.     [[vClipRuler docView] setFrame:&bRect];
  138.     [vClipRuler display];
  139.     }
  140.  
  141.     return self;
  142. }
  143.  
  144. - (BOOL)showRuler:(BOOL)showIt isHorizontal:(BOOL)isHorizontal
  145. /*
  146.  * Adds or removes a ruler from the view hierarchy.
  147.  * Returns whether or not it succeeded in doing so.
  148.  */
  149. {
  150.     ClipView *ruler;
  151.     BOOL isVisible;
  152.     NXRect cRect, rRect;
  153.  
  154.     isVisible = isHorizontal ? horizontalRulerIsVisible : verticalRulerIsVisible;
  155.     if ((showIt && isVisible) || (!showIt && !isVisible)) return NO;
  156.     if (showIt && !rulersMade && ![self makeRulers]) return NO;
  157.     ruler = isHorizontal ? hClipRuler : vClipRuler;
  158.  
  159.     if (!showIt && isVisible) {
  160.     [ruler removeFromSuperview];
  161.     if (isHorizontal) {
  162.         horizontalRulerIsVisible = NO;
  163.     } else {
  164.         verticalRulerIsVisible = NO;
  165.     }
  166.     } else if (showIt && !isVisible && ruler) {
  167.     [self addSubview:ruler];
  168.     [window disableDisplay];
  169.     [contentView getBounds:&cRect];
  170.     [hClipRuler getBounds:&rRect];
  171.     [hClipRuler setDrawOrigin:cRect.origin.x :rRect.origin.y];
  172.     [vClipRuler getBounds:&rRect];
  173.     [vClipRuler setDrawOrigin:rRect.origin.x :cRect.origin.y];
  174.     [window reenableDisplay];
  175.     if (isHorizontal) {
  176.         horizontalRulerIsVisible = YES;
  177.     } else {
  178.         verticalRulerIsVisible = YES;
  179.     }
  180.     }
  181.  
  182.     return YES;
  183. }
  184.  
  185. - adjustSizes
  186. {
  187.     id windelegate;
  188.     NXRect winFrame;
  189.  
  190.     windelegate = [window delegate];
  191.     if ([windelegate respondsTo:@selector(windowWillResize:toSize:)]) {
  192.     [window getFrame:&winFrame];
  193.     [windelegate windowWillResize:window toSize:&winFrame.size];
  194.     [window placeWindow:&winFrame];
  195.     }
  196.     [self resizeSubviews:(NXSize *)nil];
  197.  
  198.     return self;
  199. }
  200.  
  201. - showHorizontalRuler:(BOOL)flag
  202. {
  203.     if ([self showRuler:flag isHorizontal:YES]) [self adjustSizes];
  204.     return self;
  205. }
  206.  
  207. - showVerticalRuler:(BOOL)flag
  208. {
  209.     if ([self showRuler:flag isHorizontal:NO]) [self adjustSizes];
  210.     return self;
  211. }
  212.  
  213. - showHideRulers:sender
  214. /*
  215.  * If both rulers are visible, they are both hidden.
  216.  * Otherwise, both rulers are made visible.
  217.  */
  218. {
  219.     BOOL resize = NO;
  220.  
  221.     if (verticalRulerIsVisible && horizontalRulerIsVisible) {
  222.     resize = [self showRuler:NO isHorizontal:YES];
  223.     resize = [self showRuler:NO isHorizontal:NO] || resize;
  224.     } else {
  225.     if (!horizontalRulerIsVisible) resize = [self showRuler:YES isHorizontal:YES];
  226.     if (!verticalRulerIsVisible) resize = [self showRuler:YES isRV6zontal:NO] || resize;
  227.     }
  228.     if (resize) [self adjustSizes];
  229.  
  230.     return self;
  231. }
  232.  
  233. /* ScrollView-specific stuff */
  234.  
  235. - free
  236. {
  237.     if (!horizontalRulerIsVisible) [hClipRuler free];
  238.     if (!verticalRulerIsVisible) [vClipRuler free];
  239.     return [super free];    
  240. }
  241.  
  242. - reflectScroll:cView
  243. /*
  244.  * We only reflect scroll in the contentView, not the rulers.
  245.  */
  246. {
  247.     if (cView == hClipRuler || cView == vClipRuler) return self;
  248.     return [super reflectScroll:cView];
  249. }
  250.  
  251. - tile
  252. /*
  253.  * Here is where we lay out the subviews of the ScrollView.
  254.  * Note the use of NXDivideRect() to "slice off" a section of
  255.  * a rectangle.  This is useful since the two scrollers each
  256.  * result in slicing a section off the contentView of the
  257.  * ScrollView.
  258.  */
  259. {
  260.     NXRect aRect, bRect, cRect;
  261.  
  262.     [super tile];
  263.  
  264.     if (horizontalRulerIsVisible || verticalRulerIsVisible) {
  265.     [contentView getFrame:&aRect];
  266.     [[self docView] getFrame:&cRect];
  267.     if (horizontalRulerIsVisible && hClipRuler) {
  268.         NXDivideRect(&aRect, &bRect, horizontalRulerWidth, NX_YMIN);
  269.         [hClipRuler setFrame:&bRect];
  270.         [[hClipRuler docView] sizeTo:cRect.size.width+verticalRulerWidth :bRect.size.height];
  271.     }
  272.     if (verticalRulerIsVisible && vClipRuler) {
  273.         NXDivideRect(&aRect, &bRect, verticalRulerWidth, NX_XMIN);
  274.         [vClipRuler setFrame:&bRect];
  275.         [[vClipRuler docView] sizeTo:bRect.size.width :cRect.size.height];
  276.     }
  277.     [contentView setFrame:&aRect];
  278.     }
  279.  
  280.     return self;
  281. }
  282.  
  283. - scrollClip:(ClipView *)aClipView to:(const NXPoint *)aPoint
  284. /*
  285.  * This is sent to us instead of rawScroll:.
  286.  * We scroll the two rulers, then the clipView itself.
  287.  */
  288. {
  289.     id fr;
  290.     NXRect rRect;
  291.  
  292.     if (horizontalRulerIsVisible && hClipRuler) {
  293.     [hClipRuler getBounds:&rRect];
  294.     rRect.origin.x = aPoint->x;
  295.     [hClipRuler rawScroll:&(rRect.origin)];
  296.     }
  297.     if (verticalRulerIsVisible && vClipRuler) {
  298.     [vClipRuler getBounds:&rRect];
  299.     rRect.origin.y = aPoint->y;
  300.     [vClipRuler rawScroll:&(rRect.origin)];
  301.     }
  302.  
  303.     [aClipView rawScroll:aPoint];
  304.  
  305.     fr = [window firstResponder];
  306.     if ([fr respondsTo:@selector(isRulerVisible)] && [fr isRulerVisible]) [fr updateRuler]; // keeps Text ruler up-to-date
  307.  
  308.     return self;
  309. }
  310.  
  311. - descendantFrameChanged:sender
  312. /*
  313.  * Any time the docView is resized, this method is
  314.  * called to update the size of the rulers to be equal to
  315.  * the size of the docView.
  316.  */
  317. {
  318.   RV7Rect aRect, bRect, cRect;
  319.  
  320.     [super descendantFrameChanged:sender];
  321.     if (horizontalRulerIsVisible || verticalRulerIsVisible) {
  322.     [contentView getFrame:&aRect];
  323.     [[self docView] getFrame:&cRect];
  324.     if (horizontalRulerIsVisible && hClipRuler) {
  325.         NXDivideRect(&aRect, &bRect, horizontalRulerWidth, NX_YMIN);
  326.         [[hClipRuler docView] sizeTo:cRect.size.width+verticalRulerWidth :bRect.size.height];
  327.     }
  328.     if (verticalRulerIsVisible && vClipRuler) {
  329.         NXDivideRect(&aRect, &bRect, verticalRulerWidth, NX_XMIN);
  330.         [[vClipRuler docView] sizeTo:bRect.size.width :cRect.size.height];
  331.     }
  332.     }
  333.  
  334.     return self;
  335. }
  336.  
  337. @end
  338. */
  339. {
  340.     int version;
  341.  
  342.     version = NXTypedStreamClassVersion(stream, "TextGraphic");
  343.     [super read:stream];
  344.  
  345.     if (version < 1) {
  346.     Cell *cell;
  347.     int maxlen;
  348.     NXStream *s;
  349.     char *buffer;
  350.     NXReadTypes(stream, "@", &cell);
  351.     [drawText setText:[cell stringValue]];
  352.     font = [cell font];
  353.     [drawText setFont:[cell font]];
  354.     [drawText setTextColor:[self lineColor]];
  355.     s = NXOpenMemory(NULL, 0, NX_WRITRV8Y);
  356.     [drawText writeRichText:s];
  357.     NXGetMemoryBuffer(s, &buffer, &length, &maxlen);
  358.     NX_ZONEMALLOC([self zone], data, char, length);
  359.     bcopy(buffer, data, length);
  360.     NXCloseMemory(s, NX_FREEBUFFER);
  361.     } else {
  362.     NXReadTypes(stream, "i", &length);
  363.     NX_ZONEMALLOC([self zone], data, char, length);
  364.     NXReadArray(stream, "c", length, data);
  365.     }
  366.  
  367.     if (version > 2 && version < 5) {
  368.     int linkNumber;
  369.     NXReadTypes(stream, "i", &linkNumber);
  370.     } else if (version == 2) {
  371.     int linkNumber;
  372.     link = NXReadObject(stream);
  373.     linkNumber = [link linkNumber];
  374.     link = nil;
  375.     }
  376.  
  377.     if (version > 3 && version < 6) {
  378.     BOOL isFormEntry;
  379.     NXReadTypes(stream, "c", &isFormEntry);
  380.     gFlags.isFormEntry = isFormEntry ? YES : NO;
  381.     }
  382.  
  383.     return self;
  384. }
  385.  
  386. @end
  387. #import "draw.h"
  388.  
  389. @implementation Tiff
  390.  
  391. - replaceWithImage
  392. {
  393.     Image *retval = [[Image allocFromZone:[self zone]] initFromStream:newStream];
  394.     [retval setBounds:&bounds];
  395.     if (!gFlags.selected) [retval deselect];
  396.     if (gFlags.locked) [retval lock];
  397.     [self free];
  398.     return retval;    
  399. }
  400.  
  401. - read:(NXTypedStream *)stream
  402. {
  403.     int length;
  404.     char *data;
  405.     NXImageInfo info;
  406.  
  407.     [super read:stream];
  408.     NXReadTypes(stream, "iiiiii", &info.width, &info.height,
  409.     &info.bitsPerSample, &info.samplesPerPixel,
  410.     &info.planarConfig, &info.photoInterp);
  411.     length = info.height * (info.samplesPerPixel) * ((info.bitsPerSample * info.width + 7) / 8);
  412.     NX_ZONEMALLOC([self zone], data, char,RV9gth+1);
  413.     NXReadArray(stream, "c", length, data);
  414.     data[length] = '\0';
  415.     newStream = NXOpenMemory(NULL, 0, NX_READWRITE);
  416.     NXWriteTIFF(newStream, &info, data);
  417.     NXSeek(newStream, 0, NX_FROMSTART);
  418.     NX_FREE(data);
  419.  
  420.     return self;
  421. }
  422.  
  423. @end
  424. /* Generated by the NeXT Project Builder 
  425.    NOTE: Do NOT change this file -- Project Builder maintains it.
  426. */
  427.  
  428. #import <stdlib.h>
  429. #import <sys/param.h>
  430. #import <objc/NXBundle.h>
  431.  
  432. #import "DrawApp.h"
  433.  
  434. void main(int argc, char *argv[]) {
  435.     char    path[MAXPATHLEN+1];
  436.     
  437.     NXApp = [DrawApp new];
  438.     if ([[NXBundle mainBundle] getPath:path forResource:"Draw" ofType:"nib"])
  439.     if ([NXApp loadNibFile:path owner:NXApp withNames:NO fromZone:[NXApp zone]])
  440.         [NXApp run];
  441.     [NXApp free];
  442.     exit(0);
  443. }
  444. RV@