1 | // |
---|
2 | // ICeCoffEEMenuOutlineView.m |
---|
3 | // ICeCoffEE |
---|
4 | // |
---|
5 | // Created by Nicholas Riley on 3/2/08. |
---|
6 | // Copyright 2008 Nicholas Riley. All rights reserved. |
---|
7 | // |
---|
8 | |
---|
9 | #import "ICeCoffEEMenuOutlineView.h" |
---|
10 | #import <Carbon/Carbon.h> |
---|
11 | |
---|
12 | // Tiger or later, indicates whether highlighted row should draw as active |
---|
13 | @interface NSWindow (IC_KeyboardFocus) |
---|
14 | - (BOOL)_isKeyWindowIgnoringFocus; |
---|
15 | @end |
---|
16 | |
---|
17 | BOOL ICCF_ViewHasKeyboardFocus(NSView *view) { |
---|
18 | NSWindow *window = [view window]; |
---|
19 | if ([window firstResponder] != view) |
---|
20 | return NO; |
---|
21 | |
---|
22 | if ([window respondsToSelector: @selector(_isKeyWindowIgnoringFocus)]) |
---|
23 | return [window _isKeyWindowIgnoringFocus]; |
---|
24 | |
---|
25 | // XXX is there a documented way to do this? |
---|
26 | // see <http://lists.apple.com/archives/cocoa-dev/2008/Mar/msg00036.html> |
---|
27 | |
---|
28 | // test cases: |
---|
29 | // - About System Preferences... |
---|
30 | // - focused character palette |
---|
31 | // - Help menu search (Shortcut) |
---|
32 | // - menu extras |
---|
33 | NSWindow *keyWindow = [NSApp keyWindow]; |
---|
34 | if (window != keyWindow && (keyWindow == nil || [keyWindow isKindOfClass: [NSPanel class]])) |
---|
35 | return NO; // exclude NSCarbonMenuWindow |
---|
36 | |
---|
37 | return YES; |
---|
38 | } |
---|
39 | |
---|
40 | @implementation ICeCoffEEMenuOutlineView |
---|
41 | |
---|
42 | // undocumented, Leopard-only, only way I can figure out to bypass inter-cell navigation |
---|
43 | - (BOOL)canFocusCell:(NSCell *)cell atTableColumn:(NSTableColumn *)tableColumn row:(int)row; |
---|
44 | { |
---|
45 | return NO; |
---|
46 | } |
---|
47 | |
---|
48 | - (BOOL)shouldUseActiveHighlight; |
---|
49 | { |
---|
50 | return NO; |
---|
51 | return [[self window] _isKeyWindowIgnoringFocus]; |
---|
52 | } |
---|
53 | |
---|
54 | - (void)highlightSelectionInClipRect:(NSRect)clipRect; |
---|
55 | { |
---|
56 | NSRange rows = [self rowsInRect: clipRect]; |
---|
57 | unsigned maxRow = NSMaxRange(rows); |
---|
58 | |
---|
59 | HIThemeMenuItemDrawInfo drawInfo = {0, kThemeMenuItemHierBackground | kThemeMenuItemPopUpBackground, kThemeMenuSelected}; |
---|
60 | if (!ICCF_ViewHasKeyboardFocus(self)) { |
---|
61 | [super highlightSelectionInClipRect: clipRect]; |
---|
62 | return; |
---|
63 | } |
---|
64 | |
---|
65 | for (unsigned row = rows.location ; row < maxRow ; ++row) { |
---|
66 | if (![self isRowSelected: row]) |
---|
67 | continue; |
---|
68 | |
---|
69 | NSRect rowRect = [self rectOfRow: row]; |
---|
70 | rowRect.size.height += 2; |
---|
71 | if (NSIntersectsRect(rowRect, clipRect)) { |
---|
72 | OSStatus err = HIThemeDrawMenuItem((HIRect *)&clipRect, |
---|
73 | (HIRect *)&rowRect, |
---|
74 | &drawInfo, |
---|
75 | (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort], |
---|
76 | kHIThemeOrientationInverted, |
---|
77 | (HIRect *)&rowRect); |
---|
78 | if (err != noErr) { |
---|
79 | [super highlightSelectionInClipRect: clipRect]; |
---|
80 | return; |
---|
81 | } |
---|
82 | } |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | @end |
---|