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