OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" | |
6 | |
7 #include "base/mac/scoped_nsobject.h" | |
8 #include "chrome/browser/ui/cocoa/nsview_additions.h" | |
9 | |
10 // The baseline shift for text in the NSTextView. | |
11 const float kTextBaselineShift = -1.0; | |
12 | |
13 @interface HyperlinkTextView(Private) | |
14 // Initialize the NSTextView properties for this subclass. | |
15 - (void)configureTextView; | |
16 | |
17 // Change the current IBeamCursor to an arrowCursor. | |
18 - (void)fixupCursor; | |
19 @end | |
20 | |
21 @implementation HyperlinkTextView | |
22 | |
23 @synthesize drawsBackgroundUsingSuperview = drawsBackgroundUsingSuperview_; | |
24 | |
25 - (id)initWithCoder:(NSCoder*)decoder { | |
26 if ((self = [super initWithCoder:decoder])) | |
27 [self configureTextView]; | |
28 return self; | |
29 } | |
30 | |
31 - (id)initWithFrame:(NSRect)frameRect { | |
32 if ((self = [super initWithFrame:frameRect])) | |
33 [self configureTextView]; | |
34 return self; | |
35 } | |
36 | |
37 - (BOOL)acceptsFirstResponder { | |
38 return !refusesFirstResponder_; | |
39 } | |
40 | |
41 - (void)drawViewBackgroundInRect:(NSRect)rect { | |
42 if (drawsBackgroundUsingSuperview_) | |
43 [self cr_drawUsingAncestor:[self superview] inRect:rect]; | |
44 else | |
45 [super drawViewBackgroundInRect:rect]; | |
46 } | |
47 | |
48 // Never draw the insertion point (otherwise, it shows up without any user | |
49 // action if full keyboard accessibility is enabled). | |
50 - (BOOL)shouldDrawInsertionPoint { | |
51 return NO; | |
52 } | |
53 | |
54 - (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange | |
55 granularity:(NSSelectionGranularity)granularity { | |
56 // Do not allow selections. | |
57 return NSMakeRange(0, 0); | |
58 } | |
59 | |
60 // Convince NSTextView to not show an I-Beam cursor when the cursor is over the | |
61 // text view but not over actual text. | |
62 // | |
63 // http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg10791.html | |
64 // "NSTextView sets the cursor over itself dynamically, based on considerations | |
65 // including the text under the cursor. It does so in -mouseEntered:, | |
66 // -mouseMoved:, and -cursorUpdate:, so those would be points to consider | |
67 // overriding." | |
68 - (void)mouseMoved:(NSEvent*)e { | |
69 [super mouseMoved:e]; | |
70 [self fixupCursor]; | |
71 } | |
72 | |
73 - (void)mouseEntered:(NSEvent*)e { | |
74 [super mouseEntered:e]; | |
75 [self fixupCursor]; | |
76 } | |
77 | |
78 - (void)cursorUpdate:(NSEvent*)e { | |
79 [super cursorUpdate:e]; | |
80 [self fixupCursor]; | |
81 } | |
82 | |
83 - (void)configureTextView { | |
84 [self setEditable:NO]; | |
85 [self setDrawsBackground:NO]; | |
86 [self setHorizontallyResizable:NO]; | |
87 [self setVerticallyResizable:NO]; | |
88 | |
89 // When text is rendered, linkTextAttributes override anything set via | |
90 // addAttributes for text that has NSLinkAttributeName. Set to nil to allow | |
91 // custom attributes to take precedence. | |
92 [self setLinkTextAttributes:nil]; | |
93 [self setDisplaysLinkToolTips:NO]; | |
94 | |
95 refusesFirstResponder_ = NO; | |
96 drawsBackgroundUsingSuperview_ = NO; | |
97 } | |
98 | |
99 - (void)fixupCursor { | |
100 if ([[NSCursor currentCursor] isEqual:[NSCursor IBeamCursor]]) | |
101 [[NSCursor arrowCursor] set]; | |
102 } | |
103 | |
104 - (void)setMessageAndLink:(NSString*)message | |
105 withLink:(NSString*)link | |
106 atOffset:(NSUInteger)linkOffset | |
107 font:(NSFont*)font | |
108 messageColor:(NSColor*)messageColor | |
109 linkColor:(NSColor*)linkColor { | |
110 NSMutableString* finalMessage = [NSMutableString stringWithString:message]; | |
111 [finalMessage insertString:link atIndex:linkOffset]; | |
112 [self setMessage:finalMessage withFont:font messageColor:messageColor]; | |
113 if ([link length] != 0) { | |
114 [self addLinkRange:NSMakeRange(linkOffset, [link length]) | |
115 withName:@"" | |
116 linkColor:linkColor]; | |
117 } | |
118 } | |
119 | |
120 - (void)setMessage:(NSString*)message | |
121 withFont:(NSFont*)font | |
122 messageColor:(NSColor*)messageColor { | |
123 // Create an attributes dictionary for the message and link. | |
124 NSDictionary* attributes = @{ | |
125 NSForegroundColorAttributeName : messageColor, | |
126 NSCursorAttributeName : [NSCursor arrowCursor], | |
127 NSFontAttributeName : font, | |
128 NSBaselineOffsetAttributeName : @(kTextBaselineShift) | |
129 }; | |
130 | |
131 // Create the attributed string for the message. | |
132 base::scoped_nsobject<NSAttributedString> attributedMessage( | |
133 [[NSMutableAttributedString alloc] initWithString:message | |
134 attributes:attributes]); | |
135 | |
136 // Update the text view with the new text. | |
137 [[self textStorage] setAttributedString:attributedMessage]; | |
138 } | |
139 | |
140 - (void)addLinkRange:(NSRange)range | |
141 withName:(id)name | |
142 linkColor:(NSColor*)linkColor { | |
143 NSDictionary* attributes = @{ | |
144 NSForegroundColorAttributeName : linkColor, | |
145 NSUnderlineStyleAttributeName : @(YES), | |
146 NSCursorAttributeName : [NSCursor pointingHandCursor], | |
147 NSLinkAttributeName : name, | |
148 NSUnderlineStyleAttributeName : @(NSSingleUnderlineStyle) | |
149 }; | |
150 | |
151 [[self textStorage] addAttributes:attributes range:range]; | |
152 } | |
153 | |
154 - (void)setRefusesFirstResponder:(BOOL)refusesFirstResponder { | |
155 refusesFirstResponder_ = refusesFirstResponder; | |
156 } | |
157 | |
158 @end | |
OLD | NEW |