1 #import "ConsoleView.h"
\r
3 #define MAX_LINES 200
\r
4 #define LINE_WIDTH 500
\r
5 #define LINE_HEIGHT 12
\r
8 * This VScroller sends a scrollToEnd message to the console based on whether you hit page/line down or not
\r
10 @interface VScroller : NSScroller {
\r
13 @implementation VScroller
\r
14 - (NSScrollerPart)hitPart {
\r
15 ConsoleView *view = (ConsoleView *)[(NSScrollView*)[self superview] documentView];
\r
16 NSScrollerPart part = [super hitPart];
\r
17 [view scrollToEnd:((part == NSScrollerIncrementPage) || (part == NSScrollerIncrementLine))];
\r
23 @implementation ConsoleView
\r
25 - (id)initWithFrame:(NSRect)frame {
\r
26 self = [super initWithFrame:frame];
\r
28 array = [[[NSMutableArray alloc] init] retain];
\r
30 attr = [[NSDictionary dictionaryWithObjectsAndKeys:
\r
31 [NSFont userFontOfSize:(LINE_HEIGHT-2)], NSFontAttributeName,
\r
32 [NSColor colorWithCalibratedRed:0.2 green:0.8 blue:0.2 alpha:1.0], NSForegroundColorAttributeName,
\r
38 - (void)awakeFromNib {
\r
39 [self scrollToEnd:YES];
\r
41 NSScroller *vscroll = [[VScroller alloc] init];
\r
42 [vscroll setControlSize:[[[self enclosingScrollView] verticalScroller] controlSize]];
\r
43 [[self enclosingScrollView] setVerticalScroller:vscroll];
\r
52 - (BOOL)isFlipped {
\r
56 - (void)drawRect:(NSRect)rect {
\r
57 //draw the visible lines only
\r
58 int startLine = rect.origin.y/LINE_HEIGHT;
\r
59 int endLine = 1 + (rect.origin.y+rect.size.height)/LINE_HEIGHT;
\r
60 if(startLine < 0) startLine = 0;
\r
61 if(endLine > [array count]) endLine = [array count];
\r
63 for(i = startLine; i < endLine; i++) {
\r
64 NSString *str = [array objectAtIndex:i];
\r
65 [str drawAtPoint:NSMakePoint(2, i * LINE_HEIGHT) withAttributes:attr];
\r
69 - (void)scrollToEnd:(BOOL)enable {
\r
73 - (void)appendLine:(NSString*)line {
\r
74 BOOL chop = [array count] > MAX_LINES;
\r
76 [array removeObjectAtIndex:0]; // limit the number of lines
\r
78 [array addObject:line];
\r
79 int i = [array count];
\r
80 [self setFrame:NSMakeRect(0, 0, LINE_WIDTH, i*LINE_HEIGHT)]; // increase the frame size
\r
82 NSRect rect = NSMakeRect(0, (i-1)*LINE_HEIGHT, LINE_WIDTH, LINE_HEIGHT);
\r
84 // Scroll to the line just added
\r
85 if([self scrollRectToVisible:rect]) return;
\r
87 // Lock the scrolling on the first visible line
\r
88 i = [self visibleRect].origin.y/LINE_HEIGHT;
\r
91 if(i > [array count]) i = [array count];
\r
92 NSRect vrect = NSMakeRect(0, (i-1)*LINE_HEIGHT, LINE_WIDTH, LINE_HEIGHT);
\r
93 if([self scrollRectToVisible:vrect]) return;
\r
96 [self setNeedsDisplay:YES];
\r
98 [self setNeedsDisplayInRect:rect];
\r
101 - (void)appendText:(NSString*)text {
\r
102 NSArray *lines = [text componentsSeparatedByString:@"\n"]; //@TODO assumes we get given lines rather than fragments...
\r
104 for(i = 0; i < [lines count]; i++) {
\r
105 NSString *line = [lines objectAtIndex:i];
\r
106 if([line length] == 0) continue; //skip empty
\r
107 [self appendLine:line];
\r
111 - (BOOL)acceptsFirstResponder {
\r
115 - (IBAction)delete:(id)sender {
\r
116 [array removeAllObjects];
\r
117 [self setFrame:NSMakeRect(0,0,0,0)];
\r