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