| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" |
| |
| #include "base/memory/scoped_nsobject.h" |
| |
| // The baseline shift for text in the NSTextView. |
| const float kTextBaselineShift = -1.0; |
| |
| @interface HyperlinkTextView(Private) |
| // Initialize the NSTextView properties for this subclass. |
| - (void)configureTextView; |
| |
| // Change the current IBeamCursor to an arrowCursor. |
| - (void)fixupCursor; |
| @end |
| |
| @implementation HyperlinkTextView |
| |
| - (id)initWithCoder:(NSCoder*)decoder { |
| if ((self = [super initWithCoder:decoder])) |
| [self configureTextView]; |
| return self; |
| } |
| |
| - (id)initWithFrame:(NSRect)frameRect { |
| if ((self = [super initWithFrame:frameRect])) |
| [self configureTextView]; |
| return self; |
| } |
| |
| // Never draw the insertion point (otherwise, it shows up without any user |
| // action if full keyboard accessibility is enabled). |
| - (BOOL)shouldDrawInsertionPoint { |
| return NO; |
| } |
| |
| - (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange |
| granularity:(NSSelectionGranularity)granularity { |
| // Do not allow selections. |
| return NSMakeRange(0, 0); |
| } |
| |
| // Convince NSTextView to not show an I-Beam cursor when the cursor is over the |
| // text view but not over actual text. |
| // |
| // http://www.mail-archive.com/[email protected]/msg10791.html |
| // "NSTextView sets the cursor over itself dynamically, based on considerations |
| // including the text under the cursor. It does so in -mouseEntered:, |
| // -mouseMoved:, and -cursorUpdate:, so those would be points to consider |
| // overriding." |
| - (void)mouseMoved:(NSEvent*)e { |
| [super mouseMoved:e]; |
| [self fixupCursor]; |
| } |
| |
| - (void)mouseEntered:(NSEvent*)e { |
| [super mouseEntered:e]; |
| [self fixupCursor]; |
| } |
| |
| - (void)cursorUpdate:(NSEvent*)e { |
| [super cursorUpdate:e]; |
| [self fixupCursor]; |
| } |
| |
| - (void)configureTextView { |
| [self setEditable:NO]; |
| [self setDrawsBackground:NO]; |
| [self setHorizontallyResizable:NO]; |
| [self setVerticallyResizable:NO]; |
| } |
| |
| - (void)fixupCursor { |
| if ([[NSCursor currentCursor] isEqual:[NSCursor IBeamCursor]]) |
| [[NSCursor arrowCursor] set]; |
| } |
| |
| - (void)setMessageAndLink:(NSString*)message |
| withLink:(NSString*)link |
| atOffset:(NSUInteger)linkOffset |
| font:(NSFont*)font |
| messageColor:(NSColor*)messageColor |
| linkColor:(NSColor*)linkColor { |
| // Create an attributes dictionary for the message and link. |
| NSMutableDictionary* attributes = [NSMutableDictionary dictionary]; |
| [attributes setObject:messageColor |
| forKey:NSForegroundColorAttributeName]; |
| [attributes setObject:[NSCursor arrowCursor] |
| forKey:NSCursorAttributeName]; |
| [attributes setObject:font |
| forKey:NSFontAttributeName]; |
| [attributes setObject:[NSNumber numberWithFloat:kTextBaselineShift] |
| forKey:NSBaselineOffsetAttributeName]; |
| |
| // Create the attributed string for the message. |
| scoped_nsobject<NSMutableAttributedString> attributedMessage( |
| [[NSMutableAttributedString alloc] initWithString:message |
| attributes:attributes]); |
| |
| if ([link length] != 0) { |
| // Add additional attributes to style the link text appropriately as |
| // well as linkify it. |
| [attributes setObject:linkColor |
| forKey:NSForegroundColorAttributeName]; |
| [attributes setObject:[NSNumber numberWithBool:YES] |
| forKey:NSUnderlineStyleAttributeName]; |
| [attributes setObject:[NSCursor pointingHandCursor] |
| forKey:NSCursorAttributeName]; |
| [attributes setObject:[NSNumber numberWithInt:NSSingleUnderlineStyle] |
| forKey:NSUnderlineStyleAttributeName]; |
| [attributes setObject:[NSString string] // dummy value |
| forKey:NSLinkAttributeName]; |
| |
| // Insert the link into the message at the appropriate offset. |
| scoped_nsobject<NSAttributedString> attributedLink( |
| [[NSAttributedString alloc] initWithString:link |
| attributes:attributes]); |
| [attributedMessage.get() insertAttributedString:attributedLink.get() |
| atIndex:linkOffset]; |
| // Ensure the TextView doesn't override the link style. |
| [self setLinkTextAttributes:attributes]; |
| } |
| |
| // Update the text view with the new text. |
| [[self textStorage] setAttributedString:attributedMessage]; |
| } |
| |
| @end |