home *** CD-ROM | disk | FTP | other *** search
/ Nebula / nebula.bin / SourceCode / Classes / ScrollTxt / ScrollDis.m < prev   
Text File  |  1989-09-30  |  5KB  |  213 lines

  1. /*
  2. **  ScrollingTextDisplay, class to implement scrolling resizable text
  3. **  from an input stream. Scrolling is both vertical and horizontal.
  4. */
  5.  
  6. #import <appkit/Text.h>
  7. #import <appkit/Font.h>
  8. #import <appkit/Window.h>
  9. #import <appkit/ScrollView.h>
  10. #import <stdio.h>
  11. #import "ScrollDis.h"
  12.  
  13. #define MAXWIDTH  (1.0e38)
  14. #define MAXHEIGHT (1.0e38)
  15.  
  16. char *readline (st, buf, size)
  17. NXStream *st;
  18. char buf[];
  19. int size;
  20. {
  21.     char *pt;
  22.     int c;
  23.     
  24.     pt = &buf[0];
  25.     for (c = NXGetc (st); !NXAtEOS (st) && (c != '\n'); c = NXGetc (st)) {
  26.         *pt++ = c;
  27.         }
  28.     if (NXAtEOS (st)) return NULL;
  29.     else {
  30.         *pt++ = c;
  31.         *pt = 0;
  32.         return buf;
  33.         }
  34. }
  35.  
  36. @implementation ScrollingTextDisplay
  37.  
  38. + newFrame:(const NXRect *)frm title:(char *)title
  39. {
  40.   NXRect scrollFrame;
  41.  
  42.   self = [super new]; 
  43.   font = [Font newFont:"Courier" size:12.0];
  44.   text = [Text new];
  45.   [text setOpaque:YES];  
  46.   [text setEditable: NO];
  47.   [text setSelectable: YES];
  48.   [text setNoWrap];
  49.   textFrame.origin.x = textFrame.origin.y = 0.0;
  50.   textFrame.size.width = [font getWidthOf:"X"] * 80.0;
  51.   textFrame.size.height = [text lineHeight] * 24.0;
  52.   [text setFrame:&textFrame];
  53.   scrollFrame.origin.x = frm->origin.x;
  54.   scrollFrame.origin.y = frm->origin.y;
  55.   [ScrollView getFrameSize:&(scrollFrame.size)
  56.           forContentSize:&(textFrame.size)
  57.         horizScroller:YES
  58.         vertScroller:YES
  59.         borderType:NX_LINE];
  60.   [self setFrame:&scrollFrame];
  61.   [self setFont:font];
  62.   [self setDocView:text];
  63.   [self setBorderType:NX_LINE];  
  64.   [self setVertScrollerRequired:YES];
  65.   [self setHorizScrollerRequired:YES];
  66.  
  67.   win = [Window newContent:&scrollFrame
  68.             style:NX_TITLEDSTYLE
  69.         backing:NX_BUFFERED 
  70.                 buttonMask:NX_ALLBUTTONS
  71.         defer:YES];
  72.  
  73.   [win setTitle: title];
  74.   [win setContentView:self];
  75.   [win setBackgroundGray:NX_WHITE];
  76.   [win setFreeWhenClosed:NO];
  77.   [[text superview] setAutoresizeSubviews:YES];
  78.  
  79.   [[[[text notifyAncestorWhenFrameChanged:YES] 
  80.            setVertResizable:YES] 
  81.            setHorizResizable:YES]
  82.        setDelegate:self];
  83.  
  84.   [text setAutosizing:NX_WIDTHSIZABLE];
  85.  
  86.   {
  87.     NXSize size = {MAXWIDTH, MAXHEIGHT};
  88.     [text setMaxSize:&size];
  89.     [self getContentSize:&size];
  90.     [text setMinSize:&size];  
  91.   }
  92.   return (self);
  93. }  
  94.  
  95. - show
  96. {
  97.     [win display];
  98.     [win makeKeyAndOrderFront:self];
  99.     return self;
  100. }
  101.  
  102. - free
  103. {
  104.     [font free];
  105.     [text free];
  106.     /* must remove window's content view (self) first, because
  107.        freed window first frees its content view, thus
  108.        recursing into oblivion, re-freeing freed objects. */
  109.     [win setContentView:nil];
  110.     [win free];
  111.     [super free];
  112.     return self;
  113. }
  114.  
  115. /* readText reads in the contents of the file into the text view.
  116. ** Note that some work is required to readjust the size of the text
  117. ** view after the text is read in --- After the adjustment, the text view
  118. ** lets the scroll view know of the change, and the scroll view recalculates
  119. ** and redraws it's scroll bar.
  120. */
  121. - readText:(NXStream *)st burst:(int)burst 
  122. {
  123.   float w, h, maxwidth;
  124.   int where, strlen(), chars, maxchars;
  125.   char buf[512];
  126.   id docview;
  127.   
  128.   docview = [contentView docView];
  129.   [text setText:""];
  130.   if (burst == YES) {
  131.     [text readText:st];
  132.     [text sizeToFit];
  133.     [text display];
  134.     return self;
  135.     }
  136.   maxchars = 0;
  137.   while (readline (st, buf, 512)) {
  138.       where = [text textLength];
  139.     [text setSel:where :where];
  140.     [text replaceSel:buf];
  141.     if ((chars = strlen (buf)) > maxchars) {
  142.         maxchars = chars;
  143.         maxwidth = [font getWidthOf: buf];
  144.         [text    getMinWidth: &w
  145.             minHeight: &h
  146.             maxWidth: maxwidth
  147.             maxHeight: MAXHEIGHT];
  148.         [text sizeTo:maxwidth :h];
  149.         }
  150.     {
  151.         NXRect rect1, rect2;
  152.         float diff;
  153.         [docview getFrame:&rect1];
  154.         [contentView getFrame:&rect2];
  155.         diff = rect1.size.height - rect2.size.height;
  156.         if (diff > 0) {
  157.             rect1.origin.y = -diff;
  158.             [docview setFrame:&rect1];
  159.             [self reflectScroll:contentView];
  160.             }
  161.         }
  162.     [text display];
  163.       }
  164.   [win flushWindow];
  165.   return (self);
  166. }
  167.  
  168. // To get around Text strangeness. This code assures that on a resize of
  169. // the text is resized and redrawn correctly. Note that the below method
  170. // cannot be in a subclass of Text as renewRuns:text:frame:tag: invokes
  171. // sizeTo::.
  172.  
  173. - sizeTo:(NXCoord)w :(NXCoord)h 
  174. {
  175.   NXRect frm;
  176.   NXSelPt start, end;
  177.  
  178.   [super sizeTo:w:h];
  179.   [text getSel:&start :&end];
  180.   [text getFrame:&frm];      
  181.   [text renewRuns:NULL text:NULL frame:&frm tag:0];
  182.   [text setSel:start.cp :end.cp];
  183.   return self;
  184. }
  185.  
  186. // setFont: sets the text font and also remembers what it has been set to.
  187. // It also has some workarounds to get around a few Text problems.
  188.  
  189. - setFont:fontID
  190. {
  191.   NXSelPt selBeg, selEnd;
  192.   BOOL insertedText = NO;
  193.  
  194.   if (fontID) {
  195.     [[self window] disableFlushWindow]; // prevent many flashes
  196.     if ([text textLength] == 0) {
  197.       insertedText = YES;
  198.       [text setText:" "];
  199.     }
  200.     [text getSel:&selBeg :&selEnd];     // get selection
  201.     [text setSel:0 :0];          // set the selection to nothing
  202.     [text setFont:fontID];        
  203.     [text setSel:selBeg.cp :selEnd.cp]; // restore the original selection
  204.     if (insertedText) [text setText:""];
  205.     [[self window] reenableFlushWindow];// allow window to update
  206.     [[self window] display];        
  207.   } else fprintf (stderr, "setFont: given no font pointer\n");
  208.  
  209.   return self;
  210. }
  211.  
  212. @end
  213.