Initial sauer
[SauerbratenRemote.git] / src / xcode / ConsoleView.m
blobb04a7fb2e2f53a9ec1117a77b281c2ef63f544cd
1 #import "ConsoleView.h"\r
2 \r
3 #define MAX_LINES 200\r
4 #define LINE_WIDTH 500\r
5 #define LINE_HEIGHT 12\r
6 \r
7 /*\r
8  * This VScroller sends a scrollToEnd message to the console based on whether you hit page/line down or not\r
9  */\r
10 @interface VScroller : NSScroller {\r
11 }\r
12 @end\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
18         return part;\r
19 }\r
20 @end\r
23 @implementation ConsoleView\r
25 - (id)initWithFrame:(NSRect)frame {\r
26     self = [super initWithFrame:frame];\r
27     if (self) {\r
28                 array = [[[NSMutableArray alloc] init] retain];\r
29                 \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
33                         nil] retain];\r
34     }\r
35     return self;\r
36 }\r
38 - (void)awakeFromNib {\r
39         [self scrollToEnd:YES];\r
40         \r
41         NSScroller *vscroll = [[VScroller alloc] init];\r
42         [vscroll setControlSize:[[[self enclosingScrollView] verticalScroller] controlSize]];\r
43         [[self enclosingScrollView] setVerticalScroller:vscroll];\r
44 }\r
46 - (void)dealloc {\r
47         [attr release];\r
48         [array release];\r
49         [super dealloc];\r
50 }\r
52 - (BOOL)isFlipped { \r
53         return YES; \r
54 }\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
62         int i;  \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
66         }\r
67 }\r
69 - (void)scrollToEnd:(BOOL)enable {\r
70         endScroll = enable;\r
71 }\r
73 - (void)appendLine:(NSString*)line {\r
74         BOOL chop = [array count] > MAX_LINES;\r
75         if(chop) {\r
76                 [array removeObjectAtIndex:0]; // limit the number of lines\r
77         }\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
81                 \r
82         NSRect rect = NSMakeRect(0, (i-1)*LINE_HEIGHT, LINE_WIDTH, LINE_HEIGHT);\r
83         if(endScroll) {\r
84                 // Scroll to the line just added\r
85                 if([self scrollRectToVisible:rect]) return;\r
86         } else {\r
87                 // Lock the scrolling on the first visible line\r
88                 i = [self visibleRect].origin.y/LINE_HEIGHT;\r
89                 if(!chop) i++;\r
90                 if(i < 0) i = 0; \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
94         }\r
95         if(chop)\r
96                 [self setNeedsDisplay:YES];\r
97         else\r
98                 [self setNeedsDisplayInRect:rect];\r
99 }\r
101 - (void)appendText:(NSString*)text {\r
102         NSArray *lines = [text componentsSeparatedByString:@"\n"]; //@TODO assumes we get given lines rather than fragments...\r
103         int i;\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
108         }\r
111 - (BOOL)acceptsFirstResponder { \r
112         return YES; \r
115 - (IBAction)delete:(id)sender {\r
116         [array removeAllObjects];\r
117         [self setFrame:NSMakeRect(0,0,0,0)];\r
120 @end\r