// // GlkTextGridView.m // CocoaGlk // // Created by Andrew Hunter on Sun Jun 15 2003. // Copyright (c) 2003 Andrew Hunter. All rights reserved. // #import "GlkTextGridView.h" @implementation GlkTextGridView - (id) initWithFrame: (NSRect) frame window: (GlkWindow*) win { self = [super initWithFrame:frame]; if (self) { glkWin = win; flashOn = NO; timer = nil; } return self; } - (void) dealloc { if (timer) { [timer invalidate]; [timer release]; timer = nil; } [super dealloc]; } - (void)drawRect:(NSRect)rect { int y; GlkSize winSize = [glkWin size]; NSPoint pos; char** grid = [glkWin textGrid]; NSEraseRect(rect); NSDictionary* attr = [glkWin attributesForStyle: style_Normal]; NSSize fntSz = [@"0" sizeWithAttributes: attr]; pos = NSMakePoint(0,0); for (y=0; y<winSize.height; y++) { if (1 || (pos.y >= rect.origin.y && pos.y <= rect.origin.y + fntSz.height)) { NSMutableAttributedString* lineToDraw; NSString* lineString = [NSString stringWithCString: grid[y] length: winSize.width]; lineToDraw = [[NSMutableAttributedString allocWithZone: [self zone]] initWithString: lineString attributes: attr]; if (flashOn && [glkWin cursorPoint].y == y) { NSMutableDictionary* newAttr = [attr mutableCopy]; flashPoint = [glkWin cursorPoint]; [newAttr setObject: [NSColor selectedTextBackgroundColor] forKey: NSBackgroundColorAttributeName]; [newAttr setObject: [NSColor blackColor] forKey: NSForegroundColorAttributeName]; [[lineToDraw mutableString] appendString: @" "]; [lineToDraw setAttributes: newAttr range: NSMakeRange(flashPoint.x, 1)]; } [lineToDraw drawAtPoint: pos]; [lineToDraw release]; } pos.y += fntSz.height; } } - (BOOL) acceptsFirstResponder { if ([glkWin requestedCharEvents]) { return YES; } else { return NO; } } - (BOOL) isFlipped { return YES; } - (void) needsFlashDisplay { NSDictionary* attr = [glkWin attributesForStyle: style_Normal]; NSSize fntSz = [@"0" sizeWithAttributes: attr]; NSRect r; r.origin = NSMakePoint(fntSz.width*flashPoint.x, [self bounds].size.height - fntSz.height*(flashPoint.y+1)); r.size = fntSz; [self setNeedsDisplayInRect: r]; } - (BOOL) becomeFirstResponder { flashOn = YES; [self needsFlashDisplay]; if (timer) { [timer invalidate]; [timer release]; timer = nil; } timer = [[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(flashTick) userInfo:nil repeats:YES] retain]; return YES; } - (BOOL) resignFirstResponder { if (timer) { [timer invalidate]; [timer release]; timer = nil; } flashOn = NO; [self needsFlashDisplay]; return YES; } - (void)keyDown:(NSEvent *)theEvent { if (![glkWin handleKeyDown: theEvent]) { [super keyDown: theEvent]; } } - (void)mouseDown:(NSEvent*) theEvent { if (![glkWin requestedMouseEvent]) { [super mouseDown: theEvent]; } else { NSRect bounds = [self bounds]; NSDictionary* attr = [glkWin attributesForStyle: style_Normal]; NSSize fntSz = [@"0" sizeWithAttributes: attr]; NSPoint clickPos = [self convertPoint: [theEvent locationInWindow] fromView: nil]; [[glkWin session] queueEvent: [GlkEvent eventWithType: evtype_MouseInput win: glkWin val1: clickPos.x / fntSz.width val2: (bounds.size.height - clickPos.y) / fntSz.height]]; [glkWin cancelMouseEvent]; } } - (void) flashTick { flashOn = !flashOn; [self needsFlashDisplay]; } @end |