OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <cmath> | |
groby-ooo-7-16
2014/08/21 04:40:06
After password_generation_popup_view_cocoa.h, plea
dconnelly
2014/08/21 10:44:25
Done.
| |
6 | |
5 #import "chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h " | 7 #import "chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h " |
6 | 8 |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
8 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
9 #include "chrome/browser/ui/autofill/autofill_popup_controller.h" | 11 #include "chrome/browser/ui/autofill/autofill_popup_controller.h" |
10 #include "chrome/browser/ui/autofill/autofill_popup_view.h" | 12 #include "chrome/browser/ui/autofill/autofill_popup_view.h" |
11 #include "chrome/browser/ui/autofill/popup_constants.h" | 13 #include "chrome/browser/ui/autofill/popup_constants.h" |
12 #include "chrome/browser/ui/chrome_style.h" | 14 #include "chrome/browser/ui/chrome_style.h" |
13 #include "chrome/browser/ui/cocoa/autofill/password_generation_popup_view_bridge .h" | 15 #include "chrome/browser/ui/cocoa/autofill/password_generation_popup_view_bridge .h" |
14 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" | 16 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" |
15 #import "chrome/browser/ui/cocoa/l10n_util.h" | 17 #import "chrome/browser/ui/cocoa/l10n_util.h" |
16 #include "components/autofill/core/browser/popup_item_ids.h" | 18 #include "components/autofill/core/browser/popup_item_ids.h" |
19 #include "grit/theme_resources.h" | |
17 #include "skia/ext/skia_utils_mac.h" | 20 #include "skia/ext/skia_utils_mac.h" |
18 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
19 #include "ui/gfx/font_list.h" | 22 #include "ui/gfx/font_list.h" |
20 #include "ui/gfx/image/image.h" | 23 #include "ui/gfx/image/image.h" |
21 #include "ui/gfx/point.h" | 24 #include "ui/gfx/point.h" |
22 #include "ui/gfx/range/range.h" | 25 #include "ui/gfx/range/range.h" |
23 #include "ui/gfx/rect.h" | 26 #include "ui/gfx/rect.h" |
24 #include "ui/gfx/text_constants.h" | 27 #include "ui/gfx/text_constants.h" |
25 | 28 |
26 using autofill::AutofillPopupView; | 29 using autofill::AutofillPopupView; |
30 using autofill::PasswordGenerationPopupController; | |
27 using autofill::PasswordGenerationPopupView; | 31 using autofill::PasswordGenerationPopupView; |
28 using base::scoped_nsobject; | 32 using base::scoped_nsobject; |
29 | 33 |
30 namespace { | 34 namespace { |
31 | 35 |
36 // The width of the divider between the password and help sections, in pixels. | |
37 const CGFloat kDividerHeight = 1; | |
38 | |
39 // The amount of whitespace, in pixels, between lines of text in the password | |
40 // section. | |
41 const CGFloat kPasswordSectionVerticalSeparation = 5; | |
42 | |
32 NSColor* DividerColor() { | 43 NSColor* DividerColor() { |
33 return gfx::SkColorToCalibratedNSColor( | 44 return gfx::SkColorToCalibratedNSColor( |
34 PasswordGenerationPopupView::kDividerColor); | 45 PasswordGenerationPopupView::kDividerColor); |
35 } | 46 } |
36 | 47 |
37 NSColor* HelpTextBackgroundColor() { | 48 CGColorRef HelpTextBackgroundColor() { |
38 return gfx::SkColorToCalibratedNSColor( | 49 return gfx::CGColorCreateFromSkColor( |
39 PasswordGenerationPopupView::kExplanatoryTextBackgroundColor); | 50 PasswordGenerationPopupView::kExplanatoryTextBackgroundColor); |
40 } | 51 } |
41 | 52 |
42 NSColor* HelpTextColor() { | 53 NSColor* HelpTextColor() { |
43 return gfx::SkColorToCalibratedNSColor( | 54 return gfx::SkColorToCalibratedNSColor( |
44 PasswordGenerationPopupView::kExplanatoryTextColor); | 55 PasswordGenerationPopupView::kExplanatoryTextColor); |
45 } | 56 } |
46 | 57 |
47 NSColor* HelpLinkColor() { | 58 NSColor* HelpLinkColor() { |
48 return gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); | 59 return gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); |
49 } | 60 } |
50 | 61 |
51 } // namespace | 62 } // namespace |
52 | 63 |
53 @implementation PasswordGenerationPopupViewCocoa | 64 @implementation PasswordGenerationPopupViewCocoa |
54 | 65 |
55 #pragma mark Initialisers | 66 #pragma mark Initialisers |
56 | 67 |
57 - (id)initWithFrame:(NSRect)frame { | 68 - (id)initWithFrame:(NSRect)frame { |
58 NOTREACHED(); | 69 NOTREACHED(); |
59 return nil; | 70 return nil; |
60 } | 71 } |
61 | 72 |
62 - (id)initWithController: | 73 - (id)initWithController: |
63 (autofill::PasswordGenerationPopupController*)controller | 74 (autofill::PasswordGenerationPopupController*)controller |
64 frame:(NSRect)frame { | 75 frame:(NSRect)frame { |
65 if (self = [super initWithDelegate:controller frame:frame]) { | 76 if (self = [super initWithDelegate:controller frame:frame]) { |
66 controller_ = controller; | 77 controller_ = controller; |
67 | 78 |
68 passwordField_ = [self textFieldWithText:controller_->password() | 79 passwordSection_.reset([[NSView alloc] initWithFrame:NSZeroRect]); |
69 color:[self nameColor] | 80 [self addSubview:passwordSection_]; |
70 alignment:NSLeftTextAlignment]; | |
71 [self addSubview:passwordField_]; | |
72 | 81 |
73 passwordSubtextField_ = [self textFieldWithText:controller_->SuggestedText() | 82 passwordField_.reset( |
74 color:[self subtextColor] | 83 [[self textFieldWithText:controller_->password() |
75 alignment:NSRightTextAlignment]; | 84 attributes:[self passwordAttributes]] retain]); |
76 [self addSubview:passwordSubtextField_]; | 85 [passwordSection_ addSubview:passwordField_]; |
77 | 86 |
78 scoped_nsobject<HyperlinkTextView> helpTextView( | 87 passwordTitleField_.reset( |
79 [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); | 88 [[self textFieldWithText:controller_->SuggestedText() |
80 [helpTextView setMessage:base::SysUTF16ToNSString(controller_->HelpText()) | 89 attributes:[self passwordTitleAttributes]] retain]); |
81 withFont:[self textFont] | 90 [passwordSection_ addSubview:passwordTitleField_]; |
82 messageColor:HelpTextColor()]; | 91 |
83 [helpTextView addLinkRange:controller_->HelpTextLinkRange().ToNSRange() | 92 keyIcon_.reset([[NSImageView alloc] initWithFrame:NSZeroRect]); |
84 withName:@"" | 93 NSImage* keyImage = ResourceBundle::GetSharedInstance() |
85 linkColor:HelpLinkColor()]; | 94 .GetImageNamed(IDR_GENERATE_PASSWORD_KEY) |
86 [helpTextView setDelegate:self]; | 95 .ToNSImage(); |
87 [[helpTextView textContainer] setLineFragmentPadding:0.0f]; | 96 [keyIcon_ setImage:keyImage]; |
88 [helpTextView setVerticallyResizable:YES]; | 97 [passwordSection_ addSubview:keyIcon_]; |
89 [self addSubview:helpTextView]; | 98 |
90 helpTextView_ = helpTextView.get(); | 99 divider_.reset([[NSBox alloc] initWithFrame:NSZeroRect]); |
91 } | 100 [divider_ setBoxType:NSBoxCustom]; |
101 [divider_ setBorderType:NSLineBorder]; | |
102 [divider_ setBorderColor:DividerColor()]; | |
103 [self addSubview:divider_]; | |
104 | |
105 helpSection_.reset([[NSView alloc] init]); | |
groby-ooo-7-16
2014/08/21 04:40:06
You can actually skip |helpSection_|, since |helpT
dconnelly
2014/08/21 10:44:25
Done.
| |
106 [self addSubview:helpSection_]; | |
107 // Add a background. NSViews don't have root layers by default. | |
108 base::scoped_nsobject<CALayer> rootLayer([[CALayer alloc] init]); | |
109 [helpSection_ setLayer:rootLayer]; | |
110 [helpSection_ setWantsLayer:YES]; | |
111 [rootLayer setBackgroundColor:HelpTextBackgroundColor()]; | |
112 | |
113 helpTextView_.reset([[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); | |
114 [helpTextView_ setMessage:base::SysUTF16ToNSString(controller_->HelpText()) | |
115 withFont:[self textFont] | |
116 messageColor:HelpTextColor()]; | |
117 [helpTextView_ addLinkRange:controller_->HelpTextLinkRange().ToNSRange() | |
118 withName:@"" | |
119 linkColor:HelpLinkColor()]; | |
120 [helpTextView_ setDelegate:self]; | |
121 [helpTextView_ setVerticallyResizable:YES]; | |
groby-ooo-7-16
2014/08/21 04:40:06
Are you sure you need this? This is only required
dconnelly
2014/08/21 10:44:25
Done.
| |
122 // Remove the underlining. | |
123 NSTextStorage* text = [helpTextView_ textStorage]; | |
124 [text addAttribute:NSUnderlineStyleAttributeName | |
125 value:[NSNumber numberWithInt:NSUnderlineStyleNone] | |
groby-ooo-7-16
2014/08/21 04:40:06
Instead of numberWithInt, just use value:@(NSUnder
dconnelly
2014/08/21 10:44:25
Done.
| |
126 range:controller_->HelpTextLinkRange().ToNSRange()]; | |
127 [helpSection_ addSubview:helpTextView_]; | |
128 } | |
92 | 129 |
93 return self; | 130 return self; |
94 } | 131 } |
95 | 132 |
96 #pragma mark NSView implementation: | 133 #pragma mark NSView implementation: |
97 | 134 |
98 - (void)drawRect:(NSRect)dirtyRect { | 135 - (void)drawRect:(NSRect)dirtyRect { |
136 [super drawRect:dirtyRect]; | |
137 | |
99 // If the view is in the process of being destroyed, don't bother drawing. | 138 // If the view is in the process of being destroyed, don't bother drawing. |
100 if (!controller_) | 139 if (!controller_) |
101 return; | 140 return; |
102 | 141 |
103 [self drawBackgroundAndBorder]; | 142 [self drawBackgroundAndBorder]; |
104 | 143 |
105 if (controller_->password_selected()) { | 144 if (controller_->password_selected()) { |
106 // Draw a highlight under the suggested password. | 145 // Draw a highlight under the suggested password. |
107 NSRect highlightBounds = [self passwordBounds]; | 146 NSRect highlightBounds = [passwordSection_ frame]; |
108 [[self highlightColor] set]; | 147 [[self highlightColor] set]; |
109 [NSBezierPath fillRect:highlightBounds]; | 148 [NSBezierPath fillRect:highlightBounds]; |
groby-ooo-7-16
2014/08/21 04:40:06
Curious: Why NSBezierPath instead of NSRectFill?.
dconnelly
2014/08/21 10:44:25
No idea. This was inherited.
| |
110 } | 149 } |
111 | |
112 // Render the background of the help text. | |
113 [HelpTextBackgroundColor() set]; | |
114 [NSBezierPath fillRect:[self helpBounds]]; | |
115 | |
116 // Render the divider. | |
117 [DividerColor() set]; | |
118 [NSBezierPath fillRect:[self dividerBounds]]; | |
119 } | 150 } |
120 | 151 |
121 #pragma mark Public API: | 152 #pragma mark Public API: |
122 | 153 |
154 - (NSSize)preferredSize { | |
155 const NSSize passwordTitleSize = | |
156 [base::SysUTF16ToNSString(controller_->SuggestedText()) | |
157 sizeWithAttributes:@{ NSFontAttributeName : [self boldFont] }]; | |
158 const NSSize passwordSize = [base::SysUTF16ToNSString(controller_->password()) | |
159 sizeWithAttributes:@{ NSFontAttributeName : [self textFont] }]; | |
160 | |
161 CGFloat width = | |
162 autofill::kPopupBorderThickness + | |
163 controller_->kHorizontalPadding + | |
164 [[keyIcon_ image] size].width + | |
165 controller_->kHorizontalPadding + | |
166 std::max(passwordSize.width, passwordTitleSize.width) + | |
167 controller_->kHorizontalPadding + | |
168 autofill::kPopupBorderThickness; | |
169 | |
170 width = std::max(width, (CGFloat)controller_->GetMinimumWidth()); | |
171 | |
172 CGFloat height = | |
173 autofill::kPopupBorderThickness + | |
174 controller_->kHelpVerticalPadding + | |
175 [self helpSizeForPopupWidth:width].height + | |
176 controller_->kHelpVerticalPadding + | |
177 autofill::kPopupBorderThickness; | |
178 | |
179 if (controller_->display_password()) | |
180 height += controller_->kPopupPasswordSectionHeight; | |
181 | |
182 return NSMakeSize(width, height); | |
183 } | |
184 | |
185 - (void)updatePassword { | |
groby-ooo-7-16
2014/08/21 04:40:06
Since it's public API, should it be in the header?
dconnelly
2014/08/21 10:44:25
It's private. Thanks, moved.
| |
186 NSAttributedString* currentPassword = [passwordField_ attributedStringValue]; | |
groby-ooo-7-16
2014/08/21 04:40:06
Why not just create a new NSAttributedString and s
dconnelly
2014/08/21 10:44:26
Done.
| |
187 base::scoped_nsobject<NSMutableAttributedString> updatedPassword( | |
188 [[NSMutableAttributedString alloc] | |
189 initWithAttributedString:currentPassword]); | |
190 [updatedPassword | |
191 replaceCharactersInRange:NSMakeRange(0, [currentPassword length]) | |
192 withString:base::SysUTF16ToNSString( | |
193 controller_->password())]; | |
194 [passwordField_ setAttributedStringValue:updatedPassword]; | |
195 } | |
196 | |
123 - (void)updateBoundsAndRedrawPopup { | 197 - (void)updateBoundsAndRedrawPopup { |
groby-ooo-7-16
2014/08/21 04:40:06
I'm wondering - it seems the width of all UI eleme
dconnelly
2014/08/21 10:44:26
After thinking through this, it seems like that wo
groby-ooo-7-16
2014/08/21 20:05:36
Both approaches sound like overkill, and we can't
| |
124 [self positionView:passwordField_ inRect:[self passwordBounds]]; | 198 const CGFloat popupWidth = controller_->popup_bounds().width(); |
125 [self positionView:passwordSubtextField_ inRect:[self passwordBounds]]; | 199 const CGFloat contentWidth = |
126 [self positionView:helpTextView_ inRect:[self helpBounds]]; | 200 popupWidth - (2 * autofill::kPopupBorderThickness); |
201 const CGFloat contentHeight = controller_->popup_bounds().height() - | |
202 (2 * autofill::kPopupBorderThickness); | |
203 | |
204 if (controller_->display_password()) { | |
205 // The password can change while the bubble is shown: If the user has | |
groby-ooo-7-16
2014/08/21 04:40:06
-updateBoundsAndRedrawPopup is only called for the
dconnelly
2014/08/21 10:44:26
It's actually called as the mouse moves over the b
groby-ooo-7-16
2014/08/21 20:05:36
Ah. Foiled by cs.chromium.org having an incomplete
| |
206 // accepted the password and then selects the form again and starts deleting | |
207 // the password, the field will be initially invisible and then become | |
208 // visible. | |
209 [self updatePassword]; | |
210 | |
211 // Layout the password section, which includes the key icon, the title, and | |
212 // the suggested password. | |
213 [passwordSection_ | |
214 setFrame:NSMakeRect(autofill::kPopupBorderThickness, | |
215 autofill::kPopupBorderThickness, | |
216 contentWidth, | |
217 controller_->kPopupPasswordSectionHeight)]; | |
218 | |
219 // The key icon falls to the left of the title and password. | |
220 const NSSize imageSize = [[keyIcon_ image] size]; | |
221 const CGFloat keyX = controller_->kHorizontalPadding; | |
222 const CGFloat keyY = | |
223 std::ceil(controller_->kPopupPasswordSectionHeight / 2.0) - | |
groby-ooo-7-16
2014/08/21 04:40:06
One std::ceil for the total term is probably enoug
dconnelly
2014/08/21 10:44:26
It looked nicer this way :( Done.
| |
224 std::ceil(imageSize.height / 2.0); | |
225 [keyIcon_ setFrame:{ NSMakePoint(keyX, keyY), [[keyIcon_ image] size] }]; | |
groby-ooo-7-16
2014/08/21 04:40:06
-setFrameOrigin
dconnelly
2014/08/21 10:44:26
It doesn't work, actually -- this size stays 0,0.
groby-ooo-7-16
2014/08/21 20:05:36
a [keyIcon_ sizeToFit] at creation time would addr
| |
226 | |
227 // The title and password fall to the right of the key icon and are centered | |
228 // vertically as a group with some padding in between. | |
229 [passwordTitleField_ sizeToFit]; | |
230 [passwordField_ sizeToFit]; | |
231 const CGFloat groupHeight = NSHeight([passwordField_ frame]) + | |
232 kPasswordSectionVerticalSeparation + | |
233 NSHeight([passwordTitleField_ frame]); | |
234 const CGFloat groupX = | |
235 NSMaxX([keyIcon_ frame]) + controller_->kHorizontalPadding; | |
236 const CGFloat groupY = | |
237 std::ceil(controller_->kPopupPasswordSectionHeight / 2.0) - | |
groby-ooo-7-16
2014/08/21 04:40:06
One ceil, as above
dconnelly
2014/08/21 10:44:26
Done.
| |
238 std::ceil(groupHeight / 2.0); | |
239 [passwordField_ setFrameOrigin:NSMakePoint(groupX, groupY)]; | |
240 const CGFloat titleY = groupY + | |
241 NSHeight([passwordField_ frame]) + | |
242 kPasswordSectionVerticalSeparation; | |
243 [passwordTitleField_ setFrameOrigin:NSMakePoint(groupX, titleY)]; | |
244 | |
245 // Layout the divider, which falls immediately below the password section. | |
246 const CGFloat dividerX = autofill::kPopupBorderThickness; | |
247 const CGFloat dividerY = NSMaxY([passwordSection_ frame]); | |
248 NSRect dividerFrame = | |
249 NSMakeRect(dividerX, dividerY, contentWidth, kDividerHeight); | |
250 [divider_ setFrame:dividerFrame]; | |
251 } | |
252 | |
253 // Layout the help section beneath the divider (if applicable, otherwise | |
254 // beneach the border). | |
255 const CGFloat helpX = autofill::kPopupBorderThickness; | |
256 const CGFloat helpY = controller_->display_password() | |
257 ? NSMaxY([divider_ frame]) | |
258 : autofill::kPopupBorderThickness; | |
259 const CGFloat helpHeight = contentHeight - helpY; | |
260 [helpSection_ setFrame:NSMakeRect(helpX, helpY, contentWidth, helpHeight)]; | |
261 | |
262 // Layout the help text in the help section with appropriate padding. | |
263 NSRect helpTextFrame = { | |
264 NSMakePoint(controller_->kHorizontalPadding, | |
265 controller_->kHelpVerticalPadding), | |
266 [self helpSizeForPopupWidth:popupWidth] | |
267 }; | |
268 [helpTextView_ setFrame:helpTextFrame]; | |
127 | 269 |
128 [super updateBoundsAndRedrawPopup]; | 270 [super updateBoundsAndRedrawPopup]; |
129 } | 271 } |
130 | 272 |
273 - (BOOL)isPointInPasswordBounds:(NSPoint)point { | |
274 return NSPointInRect(point, [passwordSection_ frame]); | |
275 } | |
276 | |
131 - (void)controllerDestroyed { | 277 - (void)controllerDestroyed { |
132 controller_ = NULL; | 278 controller_ = NULL; |
133 [super delegateDestroyed]; | 279 [super delegateDestroyed]; |
134 } | 280 } |
135 | 281 |
136 #pragma mark NSTextViewDelegate implementation: | 282 #pragma mark NSTextViewDelegate implementation: |
137 | 283 |
138 - (BOOL)textView:(NSTextView*)textView | 284 - (BOOL)textView:(NSTextView*)textView |
139 clickedOnLink:(id)link | 285 clickedOnLink:(id)link |
140 atIndex:(NSUInteger)charIndex { | 286 atIndex:(NSUInteger)charIndex { |
141 controller_->OnSavedPasswordsLinkClicked(); | 287 controller_->OnSavedPasswordsLinkClicked(); |
142 return YES; | 288 return YES; |
143 } | 289 } |
144 | 290 |
145 #pragma mark Private helpers: | 291 #pragma mark Private helpers: |
146 | 292 |
147 - (NSTextField*)textFieldWithText:(const base::string16&)text | 293 - (NSDictionary*)passwordTitleAttributes { |
148 color:(NSColor*)color | |
149 alignment:(NSTextAlignment)alignment { | |
150 scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( | 294 scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( |
151 [[NSMutableParagraphStyle alloc] init]); | 295 [[NSMutableParagraphStyle alloc] init]); |
152 [paragraphStyle setAlignment:alignment]; | 296 [paragraphStyle setAlignment:NSLeftTextAlignment]; |
297 return @{ | |
298 NSFontAttributeName : [self boldFont], | |
299 NSForegroundColorAttributeName : [self nameColor], | |
300 NSParagraphStyleAttributeName : paragraphStyle.autorelease() | |
301 }; | |
302 } | |
153 | 303 |
154 NSDictionary* textAttributes = @{ | 304 - (NSDictionary*)passwordAttributes { |
305 scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( | |
306 [[NSMutableParagraphStyle alloc] init]); | |
307 [paragraphStyle setAlignment:NSLeftTextAlignment]; | |
308 return @{ | |
155 NSFontAttributeName : [self textFont], | 309 NSFontAttributeName : [self textFont], |
156 NSForegroundColorAttributeName : color, | 310 NSForegroundColorAttributeName : [self nameColor], |
157 NSParagraphStyleAttributeName : paragraphStyle | 311 NSParagraphStyleAttributeName : paragraphStyle.autorelease() |
158 }; | 312 }; |
313 } | |
159 | 314 |
315 - (NSTextField*)textFieldWithText:(const base::string16&)text | |
316 attributes:(NSDictionary*)attributes { | |
317 NSTextField* textField = | |
318 [[[NSTextField alloc] initWithFrame:NSZeroRect] autorelease]; | |
160 scoped_nsobject<NSAttributedString> attributedString( | 319 scoped_nsobject<NSAttributedString> attributedString( |
161 [[NSAttributedString alloc] | 320 [[NSAttributedString alloc] |
162 initWithString:base::SysUTF16ToNSString(text) | 321 initWithString:base::SysUTF16ToNSString(text) |
163 attributes:textAttributes]); | 322 attributes:attributes]); |
164 | 323 [textField setAttributedStringValue:attributedString.autorelease()]; |
165 NSTextField* textField = | |
166 [[[NSTextField alloc] initWithFrame:NSZeroRect] autorelease]; | |
167 [textField setAttributedStringValue:attributedString]; | |
168 [textField setEditable:NO]; | 324 [textField setEditable:NO]; |
169 [textField setSelectable:NO]; | 325 [textField setSelectable:NO]; |
170 [textField setDrawsBackground:NO]; | 326 [textField setDrawsBackground:NO]; |
171 [textField setBezeled:NO]; | 327 [textField setBezeled:NO]; |
172 return textField; | 328 return textField; |
173 } | 329 } |
174 | 330 |
175 - (void)positionView:(NSView*)view inRect:(NSRect)bounds { | 331 - (NSSize)helpSizeForPopupWidth:(CGFloat)width { |
176 NSRect frame = NSInsetRect(bounds, controller_->kHorizontalPadding, 0); | 332 const CGFloat helpWidth = width - |
177 [view setFrame:frame]; | 333 2 * controller_->kHorizontalPadding - |
178 | 334 2 * autofill::kPopupBorderThickness; |
179 // Center the text vertically within the bounds. | 335 const NSSize size = NSMakeSize(helpWidth, MAXFLOAT); |
180 NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); | 336 NSRect textFrame = [base::SysUTF16ToNSString(controller_->HelpText()) |
181 [view setFrameOrigin: | 337 boundingRectWithSize:size |
182 NSInsetRect(frame, 0, floor(-delta.height/2)).origin]; | 338 options:NSLineBreakByWordWrapping | |
339 NSStringDrawingUsesLineFragmentOrigin | |
340 attributes:@{ NSFontAttributeName : [self textFont] }]; | |
341 return textFrame.size; | |
183 } | 342 } |
184 | 343 |
185 - (NSRect)passwordBounds { | 344 - (NSFont*)boldFont { |
186 return NSZeroRect; | 345 return [NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]]; |
187 } | |
188 | |
189 - (NSRect)helpBounds { | |
190 return NSZeroRect; | |
191 } | |
192 | |
193 - (NSRect)dividerBounds { | |
194 return NSZeroRect; | |
195 } | 346 } |
196 | 347 |
197 - (NSFont*)textFont { | 348 - (NSFont*)textFont { |
198 return ResourceBundle::GetSharedInstance().GetFontList( | 349 return [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; |
199 ResourceBundle::SmallFont).GetPrimaryFont().GetNativeFont(); | |
200 } | 350 } |
201 | 351 |
202 @end | 352 @end |
OLD | NEW |