This is TclTV.m in view mode; [Download] [Up]
// Scrolling text window for use with TclObj.
// Copyright 1991 Manticore, Inc. All Rights Reserved.
//
// This code is adapted from:
//
// TextView.m, implementation of scrolling text stuff for TextLab.
// Copyright 1989 NeXT, Inc. All Rights Reserved.
// Author: Bruce Blumberg
//
// You may freely copy, distribute and reuse the code in this example.
// Manticore and NeXT disclaim any warranty of any kind, expressed or
// implied, as to its fitness for any particular use.
#import <appkit/appkit.h>
#import "TclTV.h"
#import "TclObj.h"
// String filter for trapping user input of newline. All characters
// but newline are passed through to the text object. Newline causes
// variables in 'self' to be updated which causes further processing
// at a more felicitous time. Frankly I would have done the tcl command
// invocation from here except it seems that the text object is not in
// the right state to do vary much when this routine is called.
static char *
myTextFilter(id self, unsigned char *insertText,
int *insertLength, int position)
{
NXSelPt st, en;
if (*insertLength == 1 && *insertText == '\n') {
[self getSel:&st:&en];
[self setSel:st.cp:st.cp];
*insertLength = 0; /* don't insert return characters */
[[self delegate] cmdLoc:&st:&en]; /* signal delegate */
}
return ((char *)insertText);
}
@implementation TclTV:ScrollView
- initFrame:(const NXRect *)frameRect
{
NXRect rect = {0.0, 0.0, 0.0, 0.0};
/* initialize view */
[super initFrame:frameRect];
/* specify scrollbars */
[[self setVertScrollerRequired:YES] setHorizScrollerRequired:NO];
[self getContentSize:&(rect.size)];
theText = [self newText:&rect];
[self setDocView:theText];
[theText setSel:0 :0];
// The following two lines allow the resizing of the scrollview
// to be passed down to the docView (in this case, the text view
// itself).
[contentView setAutoresizeSubviews:YES];
[contentView setAutosizing:NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
// Create enclosing window and bring it upfront
[self makeEnclosingWindow:frameRect];
[[[window setTitle:"Tcl commands"] display] makeKeyAndOrderFront:self];
// create a tcl command buffer
cmdBuf = Tcl_CreateCmdBuf();
return self;
}
- makeEnclosingWindow:(const NXRect *)rect
{
id textWindow;
textWindow = [[Window alloc] initContent:rect
style:NX_TITLEDSTYLE
backing:NX_BUFFERED
buttonMask:NX_ALLBUTTONS
defer:NO];
[textWindow setContentView:self];
[textWindow setBackgroundGray:NX_WHITE];
[textWindow setFreeWhenClosed:YES];
return self;
}
- newText:(const NXRect *)frameRect
{
id text;
NXSize aSize = {1.0E38, 1.0E38};
text = [[Text alloc] initFrame:frameRect
text:NULL
alignment:NX_LEFTALIGNED];
[text setOpaque:YES];
[[[[[text notifyAncestorWhenFrameChanged:YES]
setVertResizable:YES]
setHorizResizable:NO]
setMonoFont:YES]
setDelegate:self];
[text setMinSize:&(frameRect->size)];
[text setMaxSize:&aSize];
[text setAutosizing:NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
[text setCharFilter:NXEditorFilter];
[text setTextFilter:myTextFilter];
[text setFont:[Font newFont:"Ohlfs" size:11.0]];
return text;
}
- setCmdHandler:sender
{
cmdHandler = sender;
return self;
}
- cmdLoc:(NXSelPt *)start :(NXSelPt *)end
{
doCmd = TRUE;
cmdStart = *start;
cmdEnd = *end;
return self;
}
- addText:(const char *)text
{
[theText replaceSel:text];
return self;
}
- textDidGetKeys:sender isEmpty:(BOOL)flag
{
static char *buf = NULL;
static buflen = 0;
int textlen;
NXSelPt st, en;
int cmdlen;
int cmdstart;
int lineno;
int nextlinepos;
char *tc;
if (doCmd) {
/* get the start and length of the command to send */
textlen = [theText textLength];
if (cmdStart.cp == cmdEnd.cp) {
lineno = [theText lineFromPosition:cmdEnd.c1st];
nextlinepos = [theText positionFromLine:lineno + 1];
cmdstart = cmdStart.c1st;
if (nextlinepos < 0) {
cmdlen = textlen - cmdstart;
} else {
cmdlen = nextlinepos - cmdstart;
}
} else {
cmdstart = cmdStart.cp;
cmdlen = cmdEnd.cp - cmdStart.cp;
}
/* make sure that 'buf' is long enough and copy cmd to buf */
if ((cmdlen + 1) > buflen) {
if (buflen == 0) {
buf = malloc(cmdlen + 128);
buflen = cmdlen + 128;
} else {
buf = realloc(buf, cmdlen + 1);
buflen = cmdlen + 1;
}
}
[theText getSubstring:buf start:cmdstart length:cmdlen];
buf[cmdlen++] = '\n';
buf[cmdlen] = '\0';
/* move the sel to end of text and make sure its on new line */
[theText setSel:textlen:textlen];
[theText getSel:&st:&en];
if (en.cp != en.c1st) {
[theText replaceSel:"\n"];
}
tc = Tcl_AssembleCmd(cmdBuf, buf);
if (tc) {
[cmdHandler doCmd:tc:self];
}
doCmd = FALSE;
}
return self;
}
- cursorVisible
{
[theText scrollSelToVisible];
return self;
}
- free
{
[cmdHandler viewLeaving:self];
Tcl_DeleteCmdBuf(cmdBuf);
return [super free];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.