File: programming/cocoa/MacScare-Source.zip/MacScare-Source/GlkTextGridView.m


//
//  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

This code uses the PclZip Zip File reading code, which is subject to the GNU LGPL. It also uses the GeSHi syntax highlighter, subject to the GPL. Ask if you want this for your own web site, it's free.