Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ui / base / cocoa / controls / 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 "ui/base/cocoa/controls/hyperlink_text_view.h"
6
7 #include "base/mac/scoped_nsobject.h"
8 #include "ui/base/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