Chromium Code Reviews| 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 |