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.