source: releases/Pester/1.1a5/Source/NJRTableView.m@ 198

Last change on this file since 198 was 53, checked in by Nicholas Riley, 22 years ago

Updated for Pester 1.1a5 (very limited release).

Pester 1.1a4 was never released.

File size: 7.3 KB
Line 
1//
2// NJRTableView.m
3// Pester
4//
5// Created by Nicholas Riley on Sun Nov 17 2002.
6// Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "NJRTableView.h"
10#import "NSTableView-NJRExtensions.h"
11#import "NSCharacterSet-NJRExtensions.h"
12
13/* only defined in 10.2, but we want to be able to compile without warnings on 10.1.x */
14@interface NSColor (JaguarExtras)
15+ (NSColor *)alternateSelectedControlColor;
16@end
17
18@implementation NJRTableView
19
20- (id)initWithCoder:(NSCoder *)aDecoder;
21{
22 if ( (self = [super initWithCoder: aDecoder]) != nil) {
23 toolTipRegionList = [[NSMutableDictionary alloc] initWithCapacity: 20];
24 }
25 return self;
26}
27
28- (void)dealloc;
29{
30 [toolTipRegionList release];
31 [super dealloc];
32}
33
34#pragma mark tool tips
35
36- (void)reloadData;
37{
38 [toolTipRegionList removeAllObjects];
39 [self removeAllToolTips];
40 [super reloadData];
41}
42
43- (void)noteNumberOfRowsChanged;
44{
45 [toolTipRegionList removeAllObjects];
46 [self removeAllToolTips];
47 [super noteNumberOfRowsChanged];
48}
49
50- (NSString *)_keyForColumn:(int)columnIndex row:(int)rowIndex;
51{
52 return [NSString stringWithFormat:@"%d,%d", rowIndex, columnIndex];
53}
54
55- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)data;
56{
57 // ask our data source for the tool tip
58 if ([[self dataSource] respondsToSelector: @selector(tableView:toolTipForTableColumn:row:)]) {
59 if ([self rowAtPoint: point] >= 0) return [[self dataSource] tableView: self toolTipForTableColumn: [[self tableColumns] objectAtIndex: [self columnAtPoint: point]] row: [self rowAtPoint: point]];
60 }
61 return nil;
62}
63
64- (NSRect)frameOfCellAtColumn:(int)columnIndex row:(int)rowIndex;
65{
66 // this cell is apparently displayed, so we need to add a region for it
67 NSNumber *toolTipTag;
68 NSRect result = [super frameOfCellAtColumn: columnIndex row: rowIndex];
69 // check if cell is already in the list
70 NSString *cellKey = [self _keyForColumn: columnIndex row: rowIndex];
71 // remove old region
72 if (toolTipTag = [toolTipRegionList objectForKey: cellKey])
73 [self removeToolTip: [toolTipTag intValue]];
74 // add new region
75 [toolTipRegionList setObject: [NSNumber numberWithInt: [self addToolTipRect: result owner: self userData: cellKey]] forKey: cellKey];
76 return [super frameOfCellAtColumn: columnIndex row: rowIndex];
77}
78
79#pragma mark type selection
80
81- (id)typeSelectDisplay;
82{
83 return typeSelectDisplay;
84}
85
86- (void)moveToEndOfDocument:(id)sender {
87 [self scrollRowToVisible: [self numberOfRows] - 1];
88}
89
90- (void)moveToBeginningOfDocument:(id)sender {
91 [self scrollRowToVisible: 0];
92}
93
94- (void)keyDown:(NSEvent *)theEvent;
95{
96 NSString *characters;
97 unichar firstCharacter;
98 characters = [theEvent characters];
99 firstCharacter = [characters characterAtIndex: 0];
100 switch (firstCharacter) {
101 case 0177: // delete key
102 case NSDeleteFunctionKey:
103 case NSDeleteCharFunctionKey:
104 if ([self selectedRow] >= 0 && [[self dataSource] respondsToSelector: @selector(removeSelectedRowsFromTableView:)]) {
105 [[self dataSource] removeSelectedRowsFromTableView: self];
106 }
107 return;
108 case NSHomeFunctionKey:
109 [self moveToBeginningOfDocument: nil];
110 return;
111 case NSEndFunctionKey:
112 [self moveToEndOfDocument: nil];
113 return;
114 }
115 if ([[NSCharacterSet typeSelectSet] characterIsMember: firstCharacter]) {
116 // invoking -[NSResponder interpretKeyEvents:] will cause insertText: to be invoked, and allows function keys to still work.
117 [self interpretKeyEvents: [NSArray arrayWithObject: theEvent]];
118 } else {
119 [super keyDown: theEvent];
120 }
121}
122
123- (void)insertText:(id)inString;
124{
125 if (![[self delegate] respondsToSelector:@selector(selectString:inTableView:)]) {
126 // For consistency with List Manager as documented, reset the typeahead buffer after twice the delay until key repeat (in ticks).
127 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
128 int keyRepeatTicks = [defaults integerForKey: @"InitialKeyRepeat"];
129 NSTimeInterval resetDelay;
130
131 if (keyRepeatTicks == 0) keyRepeatTicks = 35; // default may be missing; if so, set default
132
133 resetDelay = MIN(2.0 / 60.0 * keyRepeatTicks, 2.0);
134
135 if (typed == nil) typed = [[NSMutableString alloc] init];
136 [typed appendString: inString];
137
138 // Cancel any previously queued future invocations of _resetTypeSelect
139 [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(_resetTypeSelect) object: nil];
140
141 // queue an invocation of clearAccumulatingTypeahead for the near future.
142 [self performSelector: @selector(_resetTypeSelect) withObject: nil afterDelay: resetDelay];
143
144 // Use stringWithString to make an autoreleased copy, since we may clear out the original string below before it can be used.
145 [[self delegate] tableView: self selectRowMatchingString: [NSString stringWithString: typed]];
146
147 // Show the current typeahead string in the optional display field, like CodeWarrior does (well, not really, CW is much more elegant because it doesn't select anything until you stop typing)
148 [typeSelectDisplay setObjectValue: typed];
149 }
150}
151
152- (void)_resetTypeSelect;
153{
154 [typed setString: @""];
155 [typeSelectDisplay setObjectValue: nil];
156}
157
158- (void)resetTypeSelect;
159{
160 [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(_resetTypeSelect) object: nil];
161 [self _resetTypeSelect];
162}
163
164#pragma mark row coloring
165
166- (void)drawGridInClipRect:(NSRect)rect;
167{
168 NSRange columnRange = [self columnsInRect: rect];
169 int i;
170 // match iTunesÕ grid color
171 [[[NSColor gridColor] blendedColorWithFraction: 0.70 ofColor: [NSColor whiteColor]] set];
172 for (i = columnRange.location ; i < NSMaxRange(columnRange) ; i++) {
173 NSRect colRect = [self rectOfColumn:i];
174 int rightEdge = (int) 0.5 + colRect.origin.x + colRect.size.width;
175 [NSBezierPath strokeLineFromPoint: NSMakePoint(-0.5 + rightEdge, -0.5 + rect.origin.y)
176 toPoint: NSMakePoint(-0.5 + rightEdge, -0.5 + rect.origin.y + rect.size.height)];
177 }
178}
179
180- (void)highlightSelectionInClipRect:(NSRect)clipRect;
181{
182 NSColor *evenColor, *oddColor = [self backgroundColor];
183 float cellHeight = [self cellHeight];
184 NSRect visibleRect = [self visibleRect];
185 NSRect highlightRect;
186
187 if ([NSColor respondsToSelector: @selector(alternateSelectedControlColor)])
188 evenColor = [[NSColor alternateSelectedControlColor] highlightWithLevel:0.90];
189 else // match iTunesÕ row background color
190 evenColor = [NSColor colorWithCalibratedRed: 0.929 green: 0.953 blue: 0.996 alpha:1.0];
191
192 highlightRect.origin = NSMakePoint(NSMinX(visibleRect), (int)(NSMinY(clipRect) / cellHeight) * cellHeight);
193 highlightRect.size = NSMakeSize(NSWidth(visibleRect), cellHeight);
194
195 while (NSMinY(highlightRect) < NSMaxY(clipRect)) {
196 NSRect clippedHighlightRect = NSIntersectionRect(highlightRect, clipRect);
197 int row = (int)((NSMinY(highlightRect) + cellHeight / 2.0) / cellHeight);
198 NSColor *rowColor = (row % 2 == 0) ? evenColor : oddColor;
199 [rowColor set];
200 NSRectFill(clippedHighlightRect);
201 highlightRect.origin.y += cellHeight;
202 }
203
204 [super highlightSelectionInClipRect: clipRect];
205}
206
207@end
Note: See TracBrowser for help on using the repository browser.