Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Unified Diff: chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm

Issue 487193003: Update Mac password generation autofill popup to match latest mocks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
diff --git a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
index a8a85fdc74e95a18c14aa2f3dad1cb9f3c4f0ab9..bf4e390b4708328ce9a6b41287793adcb3d1ca0f 100644
--- a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
@@ -14,6 +14,7 @@
#import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
#import "chrome/browser/ui/cocoa/l10n_util.h"
#include "components/autofill/core/browser/popup_item_ids.h"
+#include "grit/theme_resources.h"
#include "skia/ext/skia_utils_mac.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font_list.h"
@@ -24,11 +25,19 @@
#include "ui/gfx/text_constants.h"
using autofill::AutofillPopupView;
+using autofill::PasswordGenerationPopupController;
using autofill::PasswordGenerationPopupView;
using base::scoped_nsobject;
namespace {
+const CGFloat kDividerWidth = 1;
+const CGFloat kPasswordSectionVerticalSeparation = 5;
Ilya Sherman 2014/08/19 22:32:17 nit: Please document these, including units.
dconnelly 2014/08/20 17:07:06 Done.
+
+CGFloat MidY(NSRect frame) {
+ return (NSMaxY(frame) + NSMinY(frame)) / 2.0;
Ilya Sherman 2014/08/19 22:32:17 Any particular reason not to just use NSMidY?
dconnelly 2014/08/20 17:07:06 Amusingly, I googled for it and only found crap, b
+}
+
NSColor* DividerColor() {
return gfx::SkColorToCalibratedNSColor(
PasswordGenerationPopupView::kDividerColor);
@@ -67,13 +76,19 @@ NSColor* HelpLinkColor() {
passwordField_ = [self textFieldWithText:controller_->password()
color:[self nameColor]
+ font:[self textFont]
alignment:NSLeftTextAlignment];
[self addSubview:passwordField_];
- passwordSubtextField_ = [self textFieldWithText:controller_->SuggestedText()
- color:[self subtextColor]
- alignment:NSRightTextAlignment];
- [self addSubview:passwordSubtextField_];
+ passwordTitleField_ = [self textFieldWithText:controller_->SuggestedText()
+ color:[self nameColor]
+ font:[self boldFont]
+ alignment:NSLeftTextAlignment];
+ [self addSubview:passwordTitleField_];
+
+ keyIcon_ = ResourceBundle::GetSharedInstance()
groby-ooo-7-16 2014/08/19 23:32:18 There's nothing retaining keyIcon_ - it can (and w
dconnelly 2014/08/20 17:07:05 Done.
+ .GetImageNamed(IDR_GENERATE_PASSWORD_KEY)
+ .ToNSImage();
scoped_nsobject<HyperlinkTextView> helpTextView(
[[HyperlinkTextView alloc] initWithFrame:NSZeroRect]);
@@ -84,8 +99,14 @@ NSColor* HelpLinkColor() {
withName:@""
linkColor:HelpLinkColor()];
[helpTextView setDelegate:self];
+ // Remove the underlining.
[[helpTextView textContainer] setLineFragmentPadding:0.0f];
Ilya Sherman 2014/08/19 22:32:17 Is this still needed, in addition to the code you
dconnelly 2014/08/20 17:07:06 Done.
[helpTextView setVerticallyResizable:YES];
+ [helpTextView setLinkTextAttributes:nil];
groby-ooo-7-16 2014/08/19 23:32:18 setLinkTextAttributes:nil does nothing for Hyperli
dconnelly 2014/08/20 17:07:06 Done.
+ NSTextStorage* text = [helpTextView textStorage];
+ [text addAttribute:NSUnderlineStyleAttributeName
+ value:[NSNumber numberWithInt:NSUnderlineStyleNone]
+ range:controller_->HelpTextLinkRange().ToNSRange()];
groby-ooo-7-16 2014/08/19 23:32:18 Is this cleared with UI review? HyperlinkTextView
dconnelly 2014/08/20 17:07:06 This came from UI mocks: https://code.google.com/p
[self addSubview:helpTextView];
helpTextView_ = helpTextView.get();
groby-ooo-7-16 2014/08/19 23:32:18 Why? Why not make helpTextView_ a scoped_nsobject?
dconnelly 2014/08/20 17:07:06 Agreed. I've now converted all the __weak pointer
}
@@ -102,32 +123,80 @@ NSColor* HelpLinkColor() {
[self drawBackgroundAndBorder];
+ const CGFloat width =
+ NSWidth(NSRectFromCGRect(controller_->popup_bounds().ToCGRect()));
+
if (controller_->password_selected()) {
// Draw a highlight under the suggested password.
- NSRect highlightBounds = [self passwordBounds];
+ NSRect highlightBounds = [self passwordSectionBoundsForWidth:width];
[[self highlightColor] set];
[NSBezierPath fillRect:highlightBounds];
}
// Render the background of the help text.
[HelpTextBackgroundColor() set];
- [NSBezierPath fillRect:[self helpBounds]];
+ [NSBezierPath fillRect:[self helpBoundsForWidth:width]];
groby-ooo-7-16 2014/08/19 23:32:18 Why not just set a background color on the help te
dconnelly 2014/08/20 17:07:06 Done.
// Render the divider.
[DividerColor() set];
groby-ooo-7-16 2014/08/19 23:32:17 Usually, you draw dividers by just having an NSBox
dconnelly 2014/08/20 17:07:06 You can't change its color that way. I've replaced
- [NSBezierPath fillRect:[self dividerBounds]];
+ [NSBezierPath fillRect:[self dividerBoundsForWidth:width]];
+
+ // Render the key icon.
+ [keyIcon_ drawInRect:[self iconBoundsForWidth:width]
groby-ooo-7-16 2014/08/19 23:32:18 Can you use an NSImageView instead?
dconnelly 2014/08/20 17:07:05 Done.
+ fromRect:{ NSZeroPoint, [keyIcon_ size] }
groby-ooo-7-16 2014/08/19 23:32:18 Passing in NSZeroRect automatically specifies the
dconnelly 2014/08/20 17:07:05 Done.
+ operation:NSCompositeSourceOver
+ fraction:1.0
+ respectFlipped:YES
+ hints:nil];
}
#pragma mark Public API:
-- (void)updateBoundsAndRedrawPopup {
- [self positionView:passwordField_ inRect:[self passwordBounds]];
- [self positionView:passwordSubtextField_ inRect:[self passwordBounds]];
- [self positionView:helpTextView_ inRect:[self helpBounds]];
+- (NSSize)preferredSize {
+ const CGFloat popupWidth = controller_->GetMinimumWidth();
+ NSRect helpBounds = [self helpBoundsForWidth:popupWidth];
+ CGFloat height =
+ (controller_->display_password()
+ ? NSHeight([self passwordSectionBoundsForWidth:popupWidth])
+ : 0) +
+ NSHeight([self dividerBoundsForWidth:popupWidth]) + NSHeight(helpBounds) +
+ 2 * autofill::kPopupBorderThickness;
+ return NSMakeSize(popupWidth + 2 * autofill::kPopupBorderThickness, height);
+}
+
+- (void)updatePassword {
+ [self setText:controller_->password()
+ color:[self nameColor]
+ font:[self textFont]
+ alignment:NSLeftTextAlignment
+ forField:passwordField_];
Ilya Sherman 2014/08/19 22:32:17 Is it not possible to update the text without need
dconnelly 2014/08/20 17:07:05 I thought not, but I found a way. Done.
+}
+- (void)updateBoundsAndRedrawPopup {
+ const CGFloat width =
+ NSWidth(NSRectFromCGRect(controller_->popup_bounds().ToCGRect()));
groby-ooo-7-16 2014/08/19 23:32:18 Just width = controller->popup_bounds().width() N
dconnelly 2014/08/20 17:07:05 Done.
+ // The password can change while the bubble is shown: if the user has
Ilya Sherman 2014/08/19 22:32:17 nit: "if" -> "If"
dconnelly 2014/08/20 17:07:06 TIL. Done.
+ // accepted the password and then selects the form again and starts deleting
+ // the password, the field will be initially invisible and then become
+ // visible.
+ [self updatePassword];
Ilya Sherman 2014/08/19 22:32:17 nit: Can this be moved into the if-stmt below?
dconnelly 2014/08/20 17:07:05 Done.
+ if (controller_->display_password()) {
+ [self positionView:passwordTitleField_
+ inRect:[self passwordSectionTitleBoundsForWidth:width]];
+ [self positionView:passwordField_
+ inRect:[self passwordBoundsForWidth:width]];
+ }
+ [self positionView:helpTextView_ inRect:[self helpBoundsForWidth:width]];
[super updateBoundsAndRedrawPopup];
}
+- (BOOL)isPointInPasswordBounds:(CGPoint)point {
+ const CGFloat width =
+ NSWidth(NSRectFromCGRect(controller_->popup_bounds().ToCGRect()));
+ return CGRectContainsPoint(
+ NSRectToCGRect([self passwordSectionBoundsForWidth:width]), point);
Ilya Sherman 2014/08/19 22:32:17 Can you use NSPointInRect instead? (In general, N
dconnelly 2014/08/20 17:07:05 Done.
+}
+
- (void)controllerDestroyed {
controller_ = NULL;
[super delegateDestroyed];
@@ -144,15 +213,17 @@ NSColor* HelpLinkColor() {
#pragma mark Private helpers:
-- (NSTextField*)textFieldWithText:(const base::string16&)text
- color:(NSColor*)color
- alignment:(NSTextAlignment)alignment {
+- (void)setText:(const base::string16&)text
+ color:(NSColor*)color
+ font:(NSFont*)font
+ alignment:(NSTextAlignment)alignment
+ forField:(NSTextField*)field {
groby-ooo-7-16 2014/08/19 23:32:17 This seem overkill, but I'm not sure how many diff
dconnelly 2014/08/20 17:07:06 Done.
scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
[[NSMutableParagraphStyle alloc] init]);
[paragraphStyle setAlignment:alignment];
NSDictionary* textAttributes = @{
- NSFontAttributeName : [self textFont],
+ NSFontAttributeName : font,
NSForegroundColorAttributeName : color,
NSParagraphStyleAttributeName : paragraphStyle
};
@@ -162,9 +233,20 @@ NSColor* HelpLinkColor() {
initWithString:base::SysUTF16ToNSString(text)
attributes:textAttributes]);
+ [field setAttributedStringValue:attributedString];
+}
+
+- (NSTextField*)textFieldWithText:(const base::string16&)text
+ color:(NSColor*)color
+ font:(NSFont*)font
+ alignment:(NSTextAlignment)alignment {
NSTextField* textField =
[[[NSTextField alloc] initWithFrame:NSZeroRect] autorelease];
- [textField setAttributedStringValue:attributedString];
+ [self setText:text
+ color:color
+ font:font
+ alignment:alignment
+ forField:textField];
[textField setEditable:NO];
[textField setSelectable:NO];
[textField setDrawsBackground:NO];
@@ -182,16 +264,99 @@ NSColor* HelpLinkColor() {
NSInsetRect(frame, 0, floor(-delta.height/2)).origin];
}
-- (NSRect)passwordBounds {
- return NSZeroRect;
+- (NSRect)passwordSectionBoundsForWidth:(CGFloat)width {
groby-ooo-7-16 2014/08/19 23:32:18 Using bounds in the name is confusing. Usually, [s
dconnelly 2014/08/20 17:07:06 I think all this is confusing, so I've removed the
+ if (!controller_->display_password())
+ return NSZeroRect;
+ return NSMakeRect(
+ autofill::kPopupBorderThickness,
+ autofill::kPopupBorderThickness,
+ width - 2 * autofill::kPopupBorderThickness,
+ PasswordGenerationPopupController::kPopupPasswordSectionHeight);
+}
+
+- (NSSize)sizeOfSingleLineString:(const base::string16&)string
+ withFont:(NSFont*)font {
+ NSRect textFrame = [base::SysUTF16ToNSString(string)
+ boundingRectWithSize:NSMakeSize(MAXFLOAT, MAXFLOAT)
+ options:0
+ attributes:@{ NSFontAttributeName : font }];
+ return textFrame.size;
Ilya Sherman 2014/08/19 22:32:17 I feel like this code must already exist somewhere
dconnelly 2014/08/20 17:07:06 Done.
+}
+
+- (NSRect)passwordSectionTitleBoundsForWidth:(CGFloat)width {
+ if (!controller_->display_password())
+ return NSZeroRect;
+ NSRect passwordSectionBounds = [self passwordSectionBoundsForWidth:width];
+ NSSize passwordSize = [self sizeOfSingleLineString:controller_->password()
+ withFont:[self boldFont]];
+ const CGFloat y = MidY(passwordSectionBounds) -
+ (kPasswordSectionVerticalSeparation / 2.0) -
groby-ooo-7-16 2014/08/19 23:32:18 Be careful with rounding. Currently, kPasswordSect
dconnelly 2014/08/20 17:07:05 Done.
+ passwordSize.height;
groby-ooo-7-16 2014/08/19 23:32:18 You seem to just care about the height of the text
dconnelly 2014/08/20 17:07:06 It's deprecated. I think this should be fine, as t
+ const CGFloat x = NSMaxX([self iconBoundsForWidth:width]);
+ return NSMakeRect(
+ x, y, NSWidth(passwordSectionBounds) - x, passwordSize.height);
+}
+
+- (NSRect)passwordBoundsForWidth:(CGFloat)width {
+ NSRect passwordSectionBounds = [self passwordSectionBoundsForWidth:width];
+ NSSize titleSize = [self sizeOfSingleLineString:controller_->SuggestedText()
+ withFont:[self textFont]];
+ const CGFloat y = MidY(passwordSectionBounds) +
+ (kPasswordSectionVerticalSeparation / 2.0);
+ const CGFloat x = NSMaxX([self iconBoundsForWidth:width]);
+ return NSMakeRect(x, y, NSWidth(passwordSectionBounds) - x, titleSize.height);
+}
+
+- (NSRect)dividerBoundsForWidth:(CGFloat)width {
+ if (!controller_->display_password())
+ return NSZeroRect;
+ return NSMakeRect(autofill::kPopupBorderThickness,
+ NSMaxY([self passwordSectionBoundsForWidth:width]),
+ width - 2 * autofill::kPopupBorderThickness,
+ kDividerWidth);
groby-ooo-7-16 2014/08/19 23:32:18 Why is the last param kDividerWidth? Shouldn't tha
dconnelly 2014/08/20 17:07:06 Poor naming. I was thinking of the line as having
+}
+
+- (NSRect)helpBoundsForWidth:(CGFloat)width {
+ NSSize size =
+ NSMakeSize(width - 2 * autofill::kPopupBorderThickness, MAXFLOAT);
+ NSStringDrawingOptions options =
+ NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin;
+ NSDictionary* attributes = @{ NSFontAttributeName : [self textFont] };
+ NSRect textFrame = [base::SysUTF16ToNSString(controller_->HelpText())
+ boundingRectWithSize:size
+ options:options
+ attributes:attributes];
groby-ooo-7-16 2014/08/19 23:32:18 Ideally, you don't want to compute field sizes at
dconnelly 2014/08/20 17:07:05 Done.
+ const int verticalPadding =
+ autofill::PasswordGenerationPopupController::kHelpVerticalPadding;
+ size.height = NSHeight(textFrame) + 2 * verticalPadding;
+
+ // The help section falls immediately above and to the right of the border.
+ NSPoint origin = NSMakePoint(autofill::kPopupBorderThickness,
+ controller_->display_password()
+ ? NSMaxY([self dividerBoundsForWidth:width])
+ : autofill::kPopupBorderThickness);
+
+ return { origin, size };
}
-- (NSRect)helpBounds {
- return NSZeroRect;
+- (NSRect)iconBoundsForWidth:(CGFloat)width {
+ if (!controller_->display_password())
+ return NSZeroRect;
+ NSRect passwordSectionBounds = [self passwordSectionBoundsForWidth:width];
+ CGFloat passwordMidY = MidY(passwordSectionBounds);
+ NSSize iconSize = [keyIcon_ size];
+ return NSMakeRect(PasswordGenerationPopupController::kHorizontalPadding,
+ passwordMidY - (iconSize.height / 2.0),
+ iconSize.width,
+ iconSize.height);
}
-- (NSRect)dividerBounds {
- return NSZeroRect;
+- (NSFont*)boldFont {
+ return ResourceBundle::GetSharedInstance()
groby-ooo-7-16 2014/08/19 23:32:18 Fonts grabbed with DeriveWithStyle don't always lo
dconnelly 2014/08/20 17:07:06 Done.
+ .GetFontList(ResourceBundle::SmallFont)
+ .DeriveWithStyle(gfx::Font::BOLD)
+ .GetPrimaryFont()
+ .GetNativeFont();
}
- (NSFont*)textFont {

Powered by Google App Engine
This is Rietveld 408576698