OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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_button_cell.h" | |
6 | |
7 @interface HyperlinkButtonCell () | |
8 - (void)customizeButtonCell; | |
9 @end | |
10 | |
11 @implementation HyperlinkButtonCell | |
12 | |
13 @dynamic textColor; | |
14 @synthesize underlineOnHover = underlineOnHover_; | |
15 @synthesize shouldUnderline = shouldUnderline_; | |
16 | |
17 + (NSColor*)defaultTextColor { | |
18 return [NSColor blueColor]; | |
19 } | |
20 | |
21 + (NSButton*)buttonWithString:(NSString*)string { | |
22 NSButton* button = [[[NSButton alloc] initWithFrame:NSZeroRect] autorelease]; | |
23 base::scoped_nsobject<HyperlinkButtonCell> cell( | |
24 [[HyperlinkButtonCell alloc] initTextCell:string]); | |
25 [cell setAlignment:NSLeftTextAlignment]; | |
26 [button setCell:cell.get()]; | |
27 [button setBezelStyle:NSRegularSquareBezelStyle]; | |
28 return button; | |
29 } | |
30 | |
31 // Designated initializer. | |
32 - (id)init { | |
33 if ((self = [super init])) { | |
34 [self customizeButtonCell]; | |
35 } | |
36 return self; | |
37 } | |
38 | |
39 // Initializer called when the cell is loaded from the NIB. | |
40 - (id)initWithCoder:(NSCoder*)aDecoder { | |
41 if ((self = [super initWithCoder:aDecoder])) { | |
42 [self customizeButtonCell]; | |
43 } | |
44 return self; | |
45 } | |
46 | |
47 // Initializer for code-based creation. | |
48 - (id)initTextCell:(NSString*)title { | |
49 if ((self = [super initTextCell:title])) { | |
50 [self customizeButtonCell]; | |
51 } | |
52 return self; | |
53 } | |
54 | |
55 // Because an NSButtonCell has multiple initializers, this method performs the | |
56 // common cell customization code. | |
57 - (void)customizeButtonCell { | |
58 [self setBordered:NO]; | |
59 [self setTextColor:[HyperlinkButtonCell defaultTextColor]]; | |
60 [self setShouldUnderline:YES]; | |
61 | |
62 CGFloat fontSize = [NSFont systemFontSizeForControlSize:[self controlSize]]; | |
63 NSFont* font = [NSFont controlContentFontOfSize:fontSize]; | |
64 [self setFont:font]; | |
65 | |
66 // Do not change button appearance when we are pushed. | |
67 [self setHighlightsBy:NSNoCellMask]; | |
68 | |
69 // We need to set this so that we can override |-mouseEntered:| and | |
70 // |-mouseExited:| to change the cursor style on hover states. | |
71 [self setShowsBorderOnlyWhileMouseInside:YES]; | |
72 } | |
73 | |
74 - (void)setControlSize:(NSControlSize)size { | |
75 [super setControlSize:size]; | |
76 [self customizeButtonCell]; // recompute |font|. | |
77 } | |
78 | |
79 // Creates the NSDictionary of attributes for the attributed string. | |
80 - (NSDictionary*)linkAttributes { | |
81 NSUInteger underlineMask = NSNoUnderlineStyle; | |
82 if (shouldUnderline_ && | |
83 (!underlineOnHover_ || (mouseIsInside_ && [self isEnabled]))) | |
84 underlineMask = NSUnderlinePatternSolid | NSUnderlineStyleSingle; | |
85 | |
86 base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( | |
87 [[NSParagraphStyle defaultParagraphStyle] mutableCopy]); | |
88 [paragraphStyle setAlignment:[self alignment]]; | |
89 [paragraphStyle setLineBreakMode:[self lineBreakMode]]; | |
90 | |
91 return [NSDictionary dictionaryWithObjectsAndKeys: | |
92 [self textColor], NSForegroundColorAttributeName, | |
93 [NSNumber numberWithInt:underlineMask], NSUnderlineStyleAttributeName, | |
94 [self font], NSFontAttributeName, | |
95 [NSCursor pointingHandCursor], NSCursorAttributeName, | |
96 paragraphStyle.get(), NSParagraphStyleAttributeName, | |
97 nil | |
98 ]; | |
99 } | |
100 | |
101 // Override the drawing for the cell so that the custom style attributes | |
102 // can always be applied and so that ellipses will appear when appropriate. | |
103 - (NSRect)drawTitle:(NSAttributedString*)title | |
104 withFrame:(NSRect)frame | |
105 inView:(NSView*)controlView { | |
106 NSDictionary* linkAttributes = [self linkAttributes]; | |
107 NSString* plainTitle = [title string]; | |
108 [plainTitle drawWithRect:frame | |
109 options:(NSStringDrawingUsesLineFragmentOrigin | | |
110 NSStringDrawingTruncatesLastVisibleLine) | |
111 attributes:linkAttributes]; | |
112 return frame; | |
113 } | |
114 | |
115 // Override the default behavior to draw the border. Instead, change the cursor. | |
116 - (void)mouseEntered:(NSEvent*)event { | |
117 mouseIsInside_ = YES; | |
118 if ([self isEnabled]) | |
119 [[NSCursor pointingHandCursor] push]; | |
120 else | |
121 [[NSCursor currentCursor] push]; | |
122 if (underlineOnHover_) | |
123 [[self controlView] setNeedsDisplay:YES]; | |
124 } | |
125 | |
126 - (void)mouseExited:(NSEvent*)event { | |
127 mouseIsInside_ = NO; | |
128 [NSCursor pop]; | |
129 if (underlineOnHover_) | |
130 [[self controlView] setNeedsDisplay:YES]; | |
131 } | |
132 | |
133 // Setters and getters. | |
134 - (NSColor*)textColor { | |
135 if ([self isEnabled]) | |
136 return textColor_.get(); | |
137 else | |
138 return [NSColor disabledControlTextColor]; | |
139 } | |
140 | |
141 - (void)setTextColor:(NSColor*)color { | |
142 textColor_.reset([color retain]); | |
143 } | |
144 | |
145 // Override so that |-sizeToFit| works better with this type of cell. | |
146 - (NSSize)cellSize { | |
147 NSSize size = [super cellSize]; | |
148 size.width += 2; | |
149 return size; | |
150 } | |
151 | |
152 @end | |
OLD | NEW |