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

Unified Diff: chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.mm

Issue 1409223005: Change the password bubble on Mac so the columns are resized dynamically. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix the crash Created 5 years, 2 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/passwords/manage_password_item_view_controller.mm
diff --git a/chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.mm b/chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.mm
index e856750c7367ab79a0eb0bba817fb9a435e1affb..b7d83a29efd5e7bf6ca1f1737350777f670ee6f9 100644
--- a/chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.mm
+++ b/chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.mm
@@ -4,12 +4,16 @@
#import "chrome/browser/ui/cocoa/passwords/manage_password_item_view_controller.h"
+#include <utility>
+
#include "base/logging.h"
+#include "base/mac/foundation_util.h"
#include "base/strings/string16.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/chrome_style.h"
#import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_content_view_controller.h"
+#import "chrome/browser/ui/cocoa/passwords/password_item_views.h"
#include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
#include "grit/components_strings.h"
#include "grit/generated_resources.h"
@@ -24,15 +28,10 @@ using namespace password_manager::mac::ui;
namespace {
-const SkColor kHoverColor = SkColorSetARGBInline(0xFF, 0xEB, 0xEB, 0xEB);
-
// Constants shared with toolkit-views layout_constants.h.
const CGFloat kItemLabelSpacing = 10;
const CGFloat kRelatedControlVerticalSpacing = 8;
-
-NSColor* HoverColor() {
- return gfx::SkColorToCalibratedNSColor(kHoverColor);
-}
+const CGFloat kDesiredRowWidth = kDesiredBubbleWidth - 2 * kFramePadding;
NSFont* LabelFont() {
return [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
@@ -43,32 +42,29 @@ NSSize LabelSize(int resourceID) {
sizeWithAttributes:@{NSFontAttributeName : LabelFont()}];
}
-CGFloat FirstFieldWidth() {
- const CGFloat undoExplanationWidth =
- LabelSize(IDS_MANAGE_PASSWORDS_DELETED).width;
- const CGFloat kUsernameWidth =
- ManagePasswordsBubbleModel::UsernameFieldWidth();
- const CGFloat width = std::max(kUsernameWidth, undoExplanationWidth);
- return width;
-}
-
-CGFloat SecondFieldWidth() {
- const CGFloat undoLinkWidth =
- LabelSize(IDS_MANAGE_PASSWORDS_UNDO).width;
- const CGFloat kPasswordWidth =
- ManagePasswordsBubbleModel::PasswordFieldWidth();
- const CGFloat width = std::max(kPasswordWidth, undoLinkWidth);
- return width;
+std::pair<CGFloat, CGFloat> GetResizedColumns(
+ CGFloat maxWidth, std::pair<CGFloat, CGFloat> columnsWidth) {
+ // Free space can be negative.
+ CGFloat freeSpace =
+ maxWidth - (columnsWidth.first + columnsWidth.second + kItemLabelSpacing);
+ if (freeSpace >= 0) {
+ return std::make_pair(columnsWidth.first + freeSpace / 2,
+ columnsWidth.second + freeSpace / 2);
+ }
+ // Make sure that the sizes are nonnegative.
+ CGFloat firstColumnPercent =
+ columnsWidth.first / (columnsWidth.first + columnsWidth.second);
+ return std::make_pair(
+ columnsWidth.first + freeSpace * firstColumnPercent,
+ columnsWidth.second + freeSpace * (1 - firstColumnPercent));
}
-CGFloat ItemWidth() {
- const CGFloat width =
- FirstFieldWidth() +
- kItemLabelSpacing +
- SecondFieldWidth() +
- kItemLabelSpacing +
- chrome_style::GetCloseButtonSize();
- return width;
+CGFloat ManagePasswordItemWidth() {
+ const CGFloat undoExplanationWidth =
+ LabelSize(IDS_MANAGE_PASSWORDS_DELETED).width;
+ const CGFloat undoLinkWidth = LabelSize(IDS_MANAGE_PASSWORDS_UNDO).width;
+ return std::max(kDesiredRowWidth,
+ undoExplanationWidth + kItemLabelSpacing + undoLinkWidth);
}
void InitLabel(NSTextField* textField, const base::string16& text) {
@@ -78,6 +74,7 @@ void InitLabel(NSTextField* textField, const base::string16& text) {
[textField setDrawsBackground:NO];
[textField setBezeled:NO];
[textField setFont:LabelFont()];
+ [[textField cell] setLineBreakMode:NSLineBreakByTruncatingTail];
[textField sizeToFit];
}
@@ -89,37 +86,29 @@ NSTextField* Label(const base::string16& text) {
}
NSTextField* UsernameLabel(const base::string16& text) {
- NSTextField* textField = Label(text);
- [textField
- setFrameSize:NSMakeSize(FirstFieldWidth(), NSHeight([textField frame]))];
- return textField;
+ return Label(text);
}
NSSecureTextField* PasswordLabel(const base::string16& text) {
base::scoped_nsobject<NSSecureTextField> textField(
[[NSSecureTextField alloc] initWithFrame:NSZeroRect]);
InitLabel(textField, text);
- [textField
- setFrameSize:NSMakeSize(SecondFieldWidth(), NSHeight([textField frame]))];
return textField.autorelease();
}
NSTextField* FederationLabel(const base::string16& text) {
- NSTextField* textField = Label(text);
- [textField
- setFrameSize:NSMakeSize(SecondFieldWidth(), NSHeight([textField frame]))];
- return textField;
+ return Label(text);
}
base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
- return form.username_value.empty() ?
- l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EMPTY_LOGIN) :
- form.username_value;
+ return form.username_value.empty()
+ ? l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EMPTY_LOGIN)
+ : form.username_value;
}
} // namespace
-@implementation ManagePasswordItemUndoView
+@implementation UndoPasswordItemView
- (id)initWithTarget:(id)target action:(SEL)action {
if ((self = [super init])) {
// The button should look like a link.
@@ -130,46 +119,58 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
[cell setShouldUnderline:NO];
[cell setUnderlineOnHover:NO];
[cell setTextColor:gfx::SkColorToCalibratedNSColor(
- chrome_style::GetLinkColor())];
+ chrome_style::GetLinkColor())];
[undoButton_ setCell:cell.get()];
[undoButton_ sizeToFit];
[undoButton_ setTarget:target];
[undoButton_ setAction:action];
-
- const CGFloat width = ItemWidth();
- CGFloat curX = 0;
- CGFloat curY = kRelatedControlVerticalSpacing;
+ [self addSubview:undoButton_];
// Add the explanation text.
- NSTextField* label =
- Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED));
- [label setFrameOrigin:NSMakePoint(curX, curY)];
- [self addSubview:label];
-
- // The undo button should be right-aligned.
- curX = width - NSWidth([undoButton_ frame]);
- [undoButton_ setFrameOrigin:NSMakePoint(curX, curY)];
- [self addSubview:undoButton_ ];
-
- // Move to the top-right of the delete button.
- curX = NSMaxX([undoButton_ frame]);
- curY = NSMaxY([undoButton_ frame]) + kRelatedControlVerticalSpacing;
-
- // Update the frame.
- DCHECK_EQ(width, curX);
- [self setFrameSize:NSMakeSize(curX, curY)];
+ label_.reset([Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED))
+ retain]);
+ [self addSubview:label_];
}
return self;
}
+
+#pragma mark PasswordItemTwoColumnView
+
+- (void)layoutWithFirstColumn:(CGFloat)firstWidth
+ secondColumn:(CGFloat)secondWidth {
+ const CGFloat width = ManagePasswordItemWidth();
+ CGFloat curX = 0;
+ CGFloat curY = kRelatedControlVerticalSpacing;
+ [label_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // The undo button should be right-aligned.
+ curX = width - NSWidth([undoButton_ frame]);
+ [undoButton_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // Move to the top-right of the delete button.
+ curX = NSMaxX([undoButton_ frame]);
+ curY = NSMaxY([undoButton_ frame]) + kRelatedControlVerticalSpacing;
+
+ // Update the frame.
+ [self setFrameSize:NSMakeSize(curX, curY)];
+}
+
+- (CGFloat)firstColumnWidth {
+ // This view doesn't have columns aligned with username/password.
+ return 0;
+}
+
+- (CGFloat)secondColumnWidth {
+ // This view doesn't have columns aligned with username/password.
+ return 0;
+}
@end
-@implementation ManagePasswordItemUndoView (Testing)
+@implementation UndoPasswordItemView (Testing)
- (NSButton*)undoButton {
return undoButton_.get();
}
@end
-@implementation ManagePasswordItemManageView
+@implementation ManagePasswordItemView
- (id)initWithForm:(const autofill::PasswordForm&)form
target:(id)target
action:(SEL)action {
@@ -188,44 +189,68 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
setPressedImage:bundle.GetImageNamed(IDR_CLOSE_2_P).ToNSImage()];
[deleteButton_ setTarget:target];
[deleteButton_ setAction:action];
-
- const CGFloat width = ItemWidth();
- CGFloat curX = 0;
- CGFloat curY = kRelatedControlVerticalSpacing;
+ [self addSubview:deleteButton_];
// Add the username.
usernameField_.reset([UsernameLabel(GetDisplayUsername(form)) retain]);
- [usernameField_ setFrameOrigin:NSMakePoint(curX, curY)];
[self addSubview:usernameField_];
- // Move to the right of the username and add the password.
- curX = NSMaxX([usernameField_ frame]) + kItemLabelSpacing;
- passwordField_.reset([PasswordLabel(form.password_value) retain]);
- [passwordField_ setFrameOrigin:NSMakePoint(curX, curY)];
+ if (form.federation_url.is_empty()) {
+ passwordField_.reset([PasswordLabel(form.password_value) retain]);
+ } else {
+ base::string16 text = l10n_util::GetStringFUTF16(
+ IDS_PASSWORDS_VIA_FEDERATION,
+ base::UTF8ToUTF16(form.federation_url.host()));
+ passwordField_.reset([FederationLabel(text) retain]);
+ }
[self addSubview:passwordField_];
+ }
+ return self;
+}
- // The delete button should be right-aligned.
- curX = width - NSWidth([deleteButton_ frame]);
- [deleteButton_ setFrameOrigin:NSMakePoint(curX, curY)];
- [self addSubview:deleteButton_];
+#pragma mark PasswordItemTwoColumnView
- // Move to the top-right of the delete button.
- curX = NSMaxX([deleteButton_ frame]);
- curY = NSMaxY([deleteButton_ frame]) + kRelatedControlVerticalSpacing;
+- (void)layoutWithFirstColumn:(CGFloat)firstWidth
+ secondColumn:(CGFloat)secondWidth {
+ const CGFloat width = ManagePasswordItemWidth();
+ std::pair<CGFloat, CGFloat> sizes = GetResizedColumns(
+ width - NSWidth([deleteButton_ frame]) - kRelatedControlVerticalSpacing,
+ std::make_pair(firstWidth, secondWidth));
+ [usernameField_
+ setFrameSize:NSMakeSize(sizes.first, NSHeight([usernameField_ frame]))];
+ [passwordField_
+ setFrameSize:NSMakeSize(sizes.second, NSHeight([passwordField_ frame]))];
+ CGFloat curX = 0;
+ CGFloat curY = kRelatedControlVerticalSpacing;
+ [usernameField_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // Move to the right of the username and add the password.
+ curX = NSMaxX([usernameField_ frame]) + kItemLabelSpacing;
+ [passwordField_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // The delete button should be right-aligned.
+ curX = width - NSWidth([deleteButton_ frame]);
+ [deleteButton_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // Move to the top-right of the delete button.
+ curX = NSMaxX([deleteButton_ frame]);
+ curY = NSMaxY([deleteButton_ frame]) + kRelatedControlVerticalSpacing;
- // Update the frame.
- DCHECK_EQ(width, curX);
- [self setFrameSize:NSMakeSize(curX, curY)];
- }
- return self;
+ // Update the frame.
+ [self setFrameSize:NSMakeSize(curX, curY)];
+}
+
+- (CGFloat)firstColumnWidth {
+ return NSWidth([usernameField_ frame]);
+}
+
+- (CGFloat)secondColumnWidth {
+ return NSWidth([passwordField_ frame]);
}
@end
-@implementation ManagePasswordItemManageView (Testing)
+@implementation ManagePasswordItemView (Testing)
- (NSTextField*)usernameField {
return usernameField_.get();
}
-- (NSSecureTextField*)passwordField {
+- (NSTextField*)passwordField {
return passwordField_.get();
}
- (NSButton*)deleteButton {
@@ -233,59 +258,71 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
}
@end
-@implementation ManagePasswordItemPendingView
+@implementation PendingPasswordItemView
- (id)initWithForm:(const autofill::PasswordForm&)form {
if ((self = [super initWithFrame:NSZeroRect])) {
- CGFloat curX = 0;
- CGFloat curY = kRelatedControlVerticalSpacing;
-
// Add the username.
usernameField_.reset([UsernameLabel(GetDisplayUsername(form)) retain]);
- [usernameField_ setFrameOrigin:NSMakePoint(curX, curY)];
[self addSubview:usernameField_];
- // Move to the right of the username and add the password.
- curX = NSMaxX([usernameField_ frame]) + kItemLabelSpacing;
if (form.federation_url.is_empty()) {
passwordField_.reset([PasswordLabel(form.password_value) retain]);
} else {
base::string16 text = l10n_util::GetStringFUTF16(
IDS_PASSWORDS_VIA_FEDERATION,
base::UTF8ToUTF16(form.federation_url.host()));
- federationField_.reset([FederationLabel(text) retain]);
+ passwordField_.reset([FederationLabel(text) retain]);
}
+ [self addSubview:passwordField_];
+ }
+ return self;
+}
- NSTextField* secondField =
- passwordField_ ? passwordField_.get() : federationField_.get();
- [secondField setFrameOrigin:NSMakePoint(curX, curY)];
- [self addSubview:secondField];
+#pragma mark PasswordItemTwoColumnView
- // Move to the top-right of the password.
- curY = NSMaxY([secondField frame]) + kRelatedControlVerticalSpacing;
+- (void)layoutWithFirstColumn:(CGFloat)firstWidth
+ secondColumn:(CGFloat)secondWidth {
+ std::pair<CGFloat, CGFloat> sizes = GetResizedColumns(
+ kDesiredRowWidth,
+ std::make_pair(firstWidth, secondWidth));
+ [usernameField_
+ setFrameSize:NSMakeSize(sizes.first, NSHeight([usernameField_ frame]))];
+ [passwordField_
+ setFrameSize:NSMakeSize(sizes.second, NSHeight([passwordField_ frame]))];
+ CGFloat curX = 0;
+ CGFloat curY = kRelatedControlVerticalSpacing;
+ [usernameField_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // Move to the right of the username and add the password.
+ curX = NSMaxX([usernameField_ frame]) + kItemLabelSpacing;
+ [passwordField_ setFrameOrigin:NSMakePoint(curX, curY)];
+ // Move to the top-right of the password.
+ curX = NSMaxX([passwordField_ frame]);
+ curY = NSMaxY([passwordField_ frame]) + kRelatedControlVerticalSpacing;
- // Update the frame.
- [self setFrameSize:NSMakeSize(ItemWidth(), curY)];
- }
- return self;
+ // Update the frame.
+ [self setFrameSize:NSMakeSize(curX, curY)];
}
+- (CGFloat)firstColumnWidth {
+ return NSWidth([usernameField_ frame]);
+}
+
+- (CGFloat)secondColumnWidth {
+ return NSWidth([passwordField_ frame]);
+}
@end
-@implementation ManagePasswordItemPendingView (Testing)
+@implementation PendingPasswordItemView (Testing)
- (NSTextField*)usernameField {
return usernameField_.get();
}
-- (NSSecureTextField*)passwordField {
+- (NSTextField*)passwordField {
return passwordField_.get();
}
-- (NSTextField*)federationField {
- return federationField_.get();
-}
-
@end
@interface ManagePasswordItemViewController ()
@@ -297,23 +334,20 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
// Find the next content view.
- (void)updateContent;
-
-// Repaint the content.
-- (void)layoutContent;
@end
@implementation ManagePasswordItemViewController
-- (id)initWithModel:(ManagePasswordsBubbleModel*)model
- passwordForm:(const autofill::PasswordForm&)passwordForm
- position:(password_manager::ui::PasswordItemPosition)position {
+- (id)initWithDelegate:(id<PasswordItemDelegate>)delegate
+ passwordForm:(const autofill::PasswordForm*)passwordForm {
if ((self = [super initWithNibName:nil bundle:nil])) {
- model_ = model;
- position_ = position;
+ delegate_ = delegate;
passwordForm_ = passwordForm;
- state_ = model_->state() == password_manager::ui::PENDING_PASSWORD_STATE
- ? MANAGE_PASSWORD_ITEM_STATE_PENDING
- : MANAGE_PASSWORD_ITEM_STATE_MANAGE;
+ if ([delegate_ model]->state() ==
+ password_manager::ui::PENDING_PASSWORD_STATE)
+ state_ = MANAGE_PASSWORD_ITEM_STATE_PENDING;
+ else
+ state_ = MANAGE_PASSWORD_ITEM_STATE_MANAGE;
[self updateContent];
}
return self;
@@ -323,46 +357,53 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
DCHECK_EQ(MANAGE_PASSWORD_ITEM_STATE_MANAGE, state_);
state_ = MANAGE_PASSWORD_ITEM_STATE_DELETED;
[self refresh];
- model_->OnPasswordAction(passwordForm_,
- ManagePasswordsBubbleModel::REMOVE_PASSWORD);
+ [delegate_ model]->OnPasswordAction(
+ *passwordForm_, ManagePasswordsBubbleModel::REMOVE_PASSWORD);
}
- (void)onUndoClicked:(id)sender {
DCHECK_EQ(MANAGE_PASSWORD_ITEM_STATE_DELETED, state_);
state_ = MANAGE_PASSWORD_ITEM_STATE_MANAGE;
[self refresh];
- model_->OnPasswordAction(passwordForm_,
- ManagePasswordsBubbleModel::ADD_PASSWORD);
+ [delegate_ model]->OnPasswordAction(*passwordForm_,
+ ManagePasswordsBubbleModel::ADD_PASSWORD);
}
- (void)refresh {
[self updateContent];
- [self layoutContent];
+ [self layoutWithFirstColumn:[delegate_ firstColumnMaxWidth]
+ secondColumn:[delegate_ secondColumnMaxWidth]];
}
- (void)updateContent {
switch (state_) {
- default:
- NOTREACHED();
case MANAGE_PASSWORD_ITEM_STATE_PENDING:
contentView_.reset(
- [[ManagePasswordItemPendingView alloc] initWithForm:passwordForm_]);
+ [[PendingPasswordItemView alloc] initWithForm:*passwordForm_]);
return;
case MANAGE_PASSWORD_ITEM_STATE_MANAGE:
- contentView_.reset([[ManagePasswordItemManageView alloc]
- initWithForm:passwordForm_
+ contentView_.reset([[ManagePasswordItemView alloc]
+ initWithForm:*passwordForm_
target:self
action:@selector(onDeleteClicked:)]);
return;
case MANAGE_PASSWORD_ITEM_STATE_DELETED:
- contentView_.reset([[ManagePasswordItemUndoView alloc]
+ contentView_.reset([[UndoPasswordItemView alloc]
initWithTarget:self
action:@selector(onUndoClicked:)]);
return;
};
}
-- (void)layoutContent {
+- (void)loadView {
+ self.view = [[[NSView alloc] initWithFrame:NSZeroRect] autorelease];
+}
+
+#pragma mark PasswordItemTwoColumnView
+
+- (void)layoutWithFirstColumn:(CGFloat)firstWidth
+ secondColumn:(CGFloat)secondWidth {
+ [contentView_ layoutWithFirstColumn:firstWidth secondColumn:secondWidth];
// Update the view size according to the content view size.
const NSSize contentSize = [contentView_ frame].size;
[self.view setFrameSize:contentSize];
@@ -371,9 +412,12 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
[self.view setSubviews:@[ contentView_ ]];
}
-- (void)loadView {
- self.view = [[[NSView alloc] initWithFrame:NSZeroRect] autorelease];
- [self layoutContent];
+- (CGFloat)firstColumnWidth {
+ return [contentView_ firstColumnWidth];
+}
+
+- (CGFloat)secondColumnWidth {
+ return [contentView_ secondColumnWidth];
}
@end
@@ -388,43 +432,73 @@ base::string16 GetDisplayUsername(const autofill::PasswordForm& form) {
return contentView_.get();
}
-- (autofill::PasswordForm)passwordForm {
- return passwordForm_;
-}
-
@end
-@implementation ManagePasswordItemClickableView
+@implementation PasswordsListViewController
+
+@synthesize firstColumnMaxWidth = firstColumnMaxWidth_;
+@synthesize secondColumnMaxWidth = secondColumnMaxWidth_;
-- (void)drawRect:(NSRect)dirtyRect {
- [super drawRect:dirtyRect];
- if (hovering_) {
- [HoverColor() setFill];
- NSRectFill(dirtyRect);
+- (id)initWithModel:(ManagePasswordsBubbleModel*)model
+ forms:(const PasswordFormsVector&)password_forms {
+ if ((self = [super initWithNibName:nil bundle:nil])) {
+ base::scoped_nsobject<NSMutableArray> items(
+ [[NSMutableArray arrayWithCapacity:password_forms.size()] retain]);
+ model_ = model;
+ // Create the controllers.
+ for (const autofill::PasswordForm* form : password_forms) {
+ base::scoped_nsobject<ManagePasswordItemViewController> item(
+ [[ManagePasswordItemViewController alloc] initWithDelegate:self
+ passwordForm:form]);
+ [items addObject:item.get()];
+ }
+ itemViews_.reset(items.release());
}
+ return self;
}
-- (void)mouseEntered:(NSEvent*)event {
- hovering_ = YES;
- [self setNeedsDisplay:YES];
+- (void)loadView {
+ base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]);
+
+ // Create the subviews.
+ for (id object in itemViews_.get()) {
+ ManagePasswordItemViewController* passwordController =
+ base::mac::ObjCCast<ManagePasswordItemViewController>(object);
+ NSView* itemView = [passwordController view];
+ [view addSubview:itemView];
+ firstColumnMaxWidth_ =
+ std::max(firstColumnMaxWidth_, [passwordController firstColumnWidth]);
+ secondColumnMaxWidth_ =
+ std::max(secondColumnMaxWidth_, [passwordController secondColumnWidth]);
+ }
+ // Lay out the items.
+ NSPoint curPos = {};
+ CGFloat maxX = 0;
+ for (id object in [itemViews_ reverseObjectEnumerator]) {
+ ManagePasswordItemViewController* passwordController =
+ base::mac::ObjCCast<ManagePasswordItemViewController>(object);
+ [passwordController layoutWithFirstColumn:firstColumnMaxWidth_
+ secondColumn:secondColumnMaxWidth_];
+ NSView* itemView = [passwordController view];
+ // The items stack up on each other.
+ [itemView setFrameOrigin:curPos];
+ maxX = NSMaxX([itemView frame]);
+ curPos.y = NSMaxY([itemView frame]);
+ }
+ [view setFrameSize:NSMakeSize(maxX, curPos.y)];
+ [self setView:view];
}
-- (void)mouseExited:(NSEvent*)event {
- hovering_ = NO;
- [self setNeedsDisplay:YES];
+- (ManagePasswordsBubbleModel*)model {
+ return model_;
}
-- (void)updateTrackingAreas {
- [super updateTrackingAreas];
- if (trackingArea_.get())
- [self removeTrackingArea:trackingArea_.get()];
- NSTrackingAreaOptions options =
- NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow;
- trackingArea_.reset([[CrTrackingArea alloc] initWithRect:[self bounds]
- options:options
- owner:self
- userInfo:nil]);
- [self addTrackingArea:trackingArea_.get()];
+@end
+
+@implementation PasswordsListViewController (Testing)
+
+- (NSArray*)itemViews {
+ return itemViews_.get();
}
@end

Powered by Google App Engine
This is Rietveld 408576698