home *** CD-ROM | disk | FTP | other *** search
- /*
- ** ScrollingTextDisplay, class to implement scrolling resizable text
- ** from an input stream. Scrolling is both vertical and horizontal.
- */
-
- #import <appkit/Text.h>
- #import <appkit/Font.h>
- #import <appkit/Window.h>
- #import <appkit/ScrollView.h>
- #import <stdio.h>
- #import "ScrollDis.h"
-
- #define MAXWIDTH (1.0e38)
- #define MAXHEIGHT (1.0e38)
-
- char *readline (st, buf, size)
- NXStream *st;
- char buf[];
- int size;
- {
- char *pt;
- int c;
-
- pt = &buf[0];
- for (c = NXGetc (st); !NXAtEOS (st) && (c != '\n'); c = NXGetc (st)) {
- *pt++ = c;
- }
- if (NXAtEOS (st)) return NULL;
- else {
- *pt++ = c;
- *pt = 0;
- return buf;
- }
- }
-
- @implementation ScrollingTextDisplay
-
- + newFrame:(const NXRect *)frm title:(char *)title
- {
- NXRect scrollFrame;
-
- self = [super new];
- font = [Font newFont:"Courier" size:12.0];
- text = [Text new];
- [text setOpaque:YES];
- [text setEditable: NO];
- [text setSelectable: YES];
- [text setNoWrap];
- textFrame.origin.x = textFrame.origin.y = 0.0;
- textFrame.size.width = [font getWidthOf:"X"] * 80.0;
- textFrame.size.height = [text lineHeight] * 24.0;
- [text setFrame:&textFrame];
- scrollFrame.origin.x = frm->origin.x;
- scrollFrame.origin.y = frm->origin.y;
- [ScrollView getFrameSize:&(scrollFrame.size)
- forContentSize:&(textFrame.size)
- horizScroller:YES
- vertScroller:YES
- borderType:NX_LINE];
- [self setFrame:&scrollFrame];
- [self setFont:font];
- [self setDocView:text];
- [self setBorderType:NX_LINE];
- [self setVertScrollerRequired:YES];
- [self setHorizScrollerRequired:YES];
-
- win = [Window newContent:&scrollFrame
- style:NX_TITLEDSTYLE
- backing:NX_BUFFERED
- buttonMask:NX_ALLBUTTONS
- defer:YES];
-
- [win setTitle: title];
- [win setContentView:self];
- [win setBackgroundGray:NX_WHITE];
- [win setFreeWhenClosed:NO];
- [[text superview] setAutoresizeSubviews:YES];
-
- [[[[text notifyAncestorWhenFrameChanged:YES]
- setVertResizable:YES]
- setHorizResizable:YES]
- setDelegate:self];
-
- [text setAutosizing:NX_WIDTHSIZABLE];
-
- {
- NXSize size = {MAXWIDTH, MAXHEIGHT};
- [text setMaxSize:&size];
- [self getContentSize:&size];
- [text setMinSize:&size];
- }
- return (self);
- }
-
- - show
- {
- [win display];
- [win makeKeyAndOrderFront:self];
- return self;
- }
-
- - free
- {
- [font free];
- [text free];
- /* must remove window's content view (self) first, because
- freed window first frees its content view, thus
- recursing into oblivion, re-freeing freed objects. */
- [win setContentView:nil];
- [win free];
- [super free];
- return self;
- }
-
- /* readText reads in the contents of the file into the text view.
- ** Note that some work is required to readjust the size of the text
- ** view after the text is read in --- After the adjustment, the text view
- ** lets the scroll view know of the change, and the scroll view recalculates
- ** and redraws it's scroll bar.
- */
- - readText:(NXStream *)st burst:(int)burst
- {
- float w, h, maxwidth;
- int where, strlen(), chars, maxchars;
- char buf[512];
- id docview;
-
- docview = [contentView docView];
- [text setText:""];
- if (burst == YES) {
- [text readText:st];
- [text sizeToFit];
- [text display];
- return self;
- }
- maxchars = 0;
- while (readline (st, buf, 512)) {
- where = [text textLength];
- [text setSel:where :where];
- [text replaceSel:buf];
- if ((chars = strlen (buf)) > maxchars) {
- maxchars = chars;
- maxwidth = [font getWidthOf: buf];
- [text getMinWidth: &w
- minHeight: &h
- maxWidth: maxwidth
- maxHeight: MAXHEIGHT];
- [text sizeTo:maxwidth :h];
- }
- {
- NXRect rect1, rect2;
- float diff;
- [docview getFrame:&rect1];
- [contentView getFrame:&rect2];
- diff = rect1.size.height - rect2.size.height;
- if (diff > 0) {
- rect1.origin.y = -diff;
- [docview setFrame:&rect1];
- [self reflectScroll:contentView];
- }
- }
- [text display];
- }
- [win flushWindow];
- return (self);
- }
-
- // To get around Text strangeness. This code assures that on a resize of
- // the text is resized and redrawn correctly. Note that the below method
- // cannot be in a subclass of Text as renewRuns:text:frame:tag: invokes
- // sizeTo::.
-
- - sizeTo:(NXCoord)w :(NXCoord)h
- {
- NXRect frm;
- NXSelPt start, end;
-
- [super sizeTo:w:h];
- [text getSel:&start :&end];
- [text getFrame:&frm];
- [text renewRuns:NULL text:NULL frame:&frm tag:0];
- [text setSel:start.cp :end.cp];
- return self;
- }
-
- // setFont: sets the text font and also remembers what it has been set to.
- // It also has some workarounds to get around a few Text problems.
-
- - setFont:fontID
- {
- NXSelPt selBeg, selEnd;
- BOOL insertedText = NO;
-
- if (fontID) {
- [[self window] disableFlushWindow]; // prevent many flashes
- if ([text textLength] == 0) {
- insertedText = YES;
- [text setText:" "];
- }
- [text getSel:&selBeg :&selEnd]; // get selection
- [text setSel:0 :0]; // set the selection to nothing
- [text setFont:fontID];
- [text setSel:selBeg.cp :selEnd.cp]; // restore the original selection
- if (insertedText) [text setText:""];
- [[self window] reenableFlushWindow];// allow window to update
- [[self window] display];
- } else fprintf (stderr, "setFont: given no font pointer\n");
-
- return self;
- }
-
- @end
-