1// 2// ZoomUpperWindow.m 3// ZoomCocoa 4// 5// Created by Andrew Hunter on Thu Oct 09 2003. 6// Copyright (c) 2003 Andrew Hunter. All rights reserved. 7// 8 9#import "ZoomUpperWindow.h" 10 11 12@implementation ZoomUpperWindow 13 14- (id) initWithZoomView: (ZoomView*) view { 15 self = [super init]; 16 if (self) { 17 theView = view; 18 lines = [[NSMutableArray allocWithZone: [self zone]] init]; 19 20 backgroundColour = [[NSColor blueColor] retain]; 21 22 endLine = startLine = 0; 23 } 24 return self; 25} 26 27- (void) dealloc { 28 //[theView release]; 29 [lines release]; 30 [inputStyle release]; 31 [backgroundColour release]; 32 [super dealloc]; 33} 34 35// Clears the window 36- (void) clearWithStyle: (ZStyle*) style { 37 [lines release]; 38 lines = [[NSMutableArray allocWithZone: [self zone]] init]; 39 xpos = ypos = 0; 40 41 [backgroundColour release]; 42 backgroundColour = [[style reversed]?[theView foregroundColourForStyle: style]:[theView backgroundColourForStyle: style] 43 retain]; 44} 45 46// Sets the input focus to this window 47- (void) setFocus { 48 [theView setFocusedView: self]; 49} 50 51// Sending data to a window 52- (void) writeString: (NSString*) string 53 withStyle: (ZStyle*) style { 54 [style setFixed: YES]; 55 56 int x; 57 int len = [string length]; 58 for (x=0; x<len; x++) { 59 if ([string characterAtIndex: x] == '\n') { 60 [self writeString: [string substringToIndex: x] 61 withStyle: style]; 62 ypos++; xpos = 0; 63 [self writeString: [string substringFromIndex: x+1] 64 withStyle: style]; 65 return; 66 } 67 } 68 69 if (ypos >= [lines count]) { 70 int x; 71 for (x=[lines count]; x<=ypos; x++) { 72 [lines addObject: [[[NSMutableAttributedString alloc] init] autorelease]]; 73 } 74 } 75 76 NSMutableAttributedString* thisLine; 77 thisLine = [lines objectAtIndex: ypos]; 78 79 int strlen = [string length]; 80 81 // Make sure there is enough space on this line for the text 82 if ([thisLine length] <= xpos+strlen) { 83 NSFont* fixedFont = [theView fontWithStyle: ZFixedStyle]; 84 NSDictionary* clearStyle = [NSDictionary dictionaryWithObjectsAndKeys: 85 fixedFont, NSFontAttributeName, 86 nil]; 87 char* spaces = malloc((xpos+strlen)-[thisLine length]); 88 89 int x; 90 for (x=0; x<(xpos+strlen)-[thisLine length]; x++) { 91 spaces[x] = ' '; 92 } 93 94 NSAttributedString* spaceString = [[NSAttributedString alloc] 95 initWithString: [NSString stringWithCString: spaces 96 length: (xpos+strlen)-[thisLine length]] 97 attributes: clearStyle]; 98 99 [thisLine appendAttributedString: spaceString]; 100 101 [spaceString release]; 102 free(spaces); 103 } 104 105 // Replace the appropriate section of the line 106 NSAttributedString* thisString = [theView formatZString: string 107 withStyle: style]; 108 [thisLine replaceCharactersInRange: NSMakeRange(xpos, strlen) 109 withAttributedString: thisString]; 110 xpos += strlen; 111 112 [theView upperWindowNeedsRedrawing]; 113} 114 115// Size (-1 to indicate an unsplit window) 116- (void) startAtLine: (int) line { 117 startLine = line; 118} 119 120- (void) endAtLine: (int) line { 121 endLine = line; 122 123 [theView rearrangeUpperWindows]; 124} 125 126// Cursor positioning 127- (void) setCursorPositionX: (int) xp 128 Y: (int) yp { 129 xpos = xp; ypos = yp-startLine; 130 131 if (xpos < 0) xpos = 0; 132 if (ypos < 0) ypos = 0; 133} 134 135- (NSPoint) cursorPosition { 136 return NSMakePoint(xpos, ypos+startLine); 137} 138 139 140// Line erasure 141static NSString* blankLine(int length) { 142 char* cString = malloc(length); 143 int x; 144 145 for (x=0; x<length; x++) cString[x] = ' '; 146 147 NSString* res = [NSString stringWithCString: cString 148 length: length]; 149 150 return res; 151} 152 153- (void) eraseLineWithStyle: (ZStyle*) style { 154 if (ypos >= [lines count]) { 155 int x; 156 for (x=[lines count]; x<=ypos; x++) { 157 [lines addObject: [[[NSMutableAttributedString alloc] init] autorelease]]; 158 } 159 } 160 161 int xs, ys; 162 NSAttributedString* newString; 163 164 [theView dimensionX: &xs Y: &ys]; 165 166 newString = [theView formatZString: blankLine(xs+1) 167 withStyle: style]; 168 169 [[lines objectAtIndex: ypos] setAttributedString: newString]; 170} 171 172// Maintainance 173- (int) length { 174 return (endLine - startLine); 175} 176 177- (NSArray*) lines { 178 return lines; 179} 180 181- (NSColor*) backgroundColour { 182 return backgroundColour; 183} 184 185- (void) cutLines { 186 int length = [self length]; 187 if ([lines count] < length) return; 188 189 [lines removeObjectsInRange: NSMakeRange(length, 190 [lines count] - length)]; 191} 192 193- (void) reformatLines { 194 NSEnumerator* lineEnum = [lines objectEnumerator]; 195 NSMutableAttributedString* string; 196 197 while (string = [lineEnum nextObject]) { 198 NSRange attributedRange; 199 NSDictionary* attr; 200 int len = [string length]; 201 202 attributedRange.location = 0; 203 204 while (attributedRange.location < len) { 205 attr = [string attributesAtIndex: attributedRange.location 206 effectiveRange: &attributedRange]; 207 208 if (attributedRange.location == NSNotFound) break; 209 if (attributedRange.length == 0) break; 210 211 // Re-apply the style associated with this block of text 212 ZStyle* sty = [attr objectForKey: ZoomStyleAttributeName]; 213 214 if (sty) { 215 NSDictionary* newAttr = [theView attributesForStyle: sty]; 216 217 [string setAttributes: newAttr 218 range: attributedRange]; 219 } 220 221 attributedRange.location += attributedRange.length; 222 } 223 } 224} 225 226// = NSCoding = 227- (void) encodeWithCoder: (NSCoder*) encoder { 228 [encoder encodeValueOfObjCType: @encode(int) 229 at: &startLine]; 230 [encoder encodeValueOfObjCType: @encode(int) 231 at: &endLine]; 232 [encoder encodeValueOfObjCType: @encode(int) 233 at: &xpos]; 234 [encoder encodeValueOfObjCType: @encode(int) 235 at: &ypos]; 236 [encoder encodeObject: lines]; 237 [encoder encodeObject: backgroundColour]; 238} 239 240- (id)initWithCoder:(NSCoder *)decoder { 241 self = [super init]; 242 243 if (self) { 244 [decoder decodeValueOfObjCType: @encode(int) 245 at: &startLine]; 246 [decoder decodeValueOfObjCType: @encode(int) 247 at: &endLine]; 248 [decoder decodeValueOfObjCType: @encode(int) 249 at: &xpos]; 250 [decoder decodeValueOfObjCType: @encode(int) 251 at: &ypos]; 252 lines = [[decoder decodeObject] retain]; 253 backgroundColour = [[decoder decodeObject] retain]; 254 } 255 256 return self; 257} 258 259- (void) setZoomView: (ZoomView*) view { 260 theView = view; 261} 262 263// = Input styles = 264 265- (void) setInputStyle: (ZStyle*) newInputStyle { 266 if (inputStyle) [inputStyle release]; 267 inputStyle = [newInputStyle copy]; 268} 269 270- (ZStyle*) inputStyle { 271 return inputStyle; 272} 273 274@end 275