| Index: chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.mm
|
| diff --git a/chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.mm
|
| index 356f79584bb0b76af00e593ea71c498b0ac036d9..5eb3c2bf48eb97504e1a63da78b3137fda6c93f9 100644
|
| --- a/chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.mm
|
| +++ b/chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.mm
|
| @@ -11,6 +11,7 @@
|
| #include "chrome/browser/ui/cocoa/autofill/autofill_popup_view_bridge.h"
|
| #include "components/autofill/core/browser/popup_item_ids.h"
|
| #include "grit/ui_resources.h"
|
| +#include "ui/base/cocoa/window_size_constants.h"
|
| #include "ui/base/resource/resource_bundle.h"
|
| #include "ui/gfx/font_list.h"
|
| #include "ui/gfx/image/image.h"
|
| @@ -19,47 +20,138 @@
|
|
|
| using autofill::AutofillPopupView;
|
|
|
| -namespace {
|
| +@implementation AutofillPopupBaseViewCocoa
|
|
|
| -NSColor* BackgroundColor() {
|
| +#pragma mark -
|
| +#pragma mark Colors
|
| +
|
| +- (NSColor*)backgroundColor {
|
| return [NSColor whiteColor];
|
| }
|
|
|
| -// The color of the border around the popup.
|
| -NSColor* BorderColor() {
|
| +- (NSColor*)borderColor {
|
| return [NSColor colorForControlTint:[NSColor currentControlTint]];
|
| }
|
|
|
| -NSColor* SeparatorColor() {
|
| +- (NSColor*)separatorColor {
|
| return [NSColor colorWithCalibratedWhite:220 / 255.0 alpha:1];
|
| }
|
|
|
| -NSColor* HighlightColor() {
|
| +- (NSColor*)highlightColor {
|
| return [NSColor selectedControlColor];
|
| }
|
|
|
| -NSColor* NameColor() {
|
| +- (NSColor*)nameColor {
|
| return [NSColor blackColor];
|
| }
|
|
|
| -NSColor* WarningColor() {
|
| +- (NSColor*)warningColor {
|
| return [NSColor grayColor];
|
| }
|
|
|
| -NSColor* SubtextColor() {
|
| +- (NSColor*)subtextColor {
|
| return [NSColor grayColor];
|
| }
|
|
|
| -} // namespace
|
| +#pragma mark -
|
| +#pragma mark Public methods
|
| +
|
| +- (id)initWithAutofillPopupViewDelegate:
|
| + (autofill::AutofillPopupViewDelegate*)delegate frame:(NSRect)frame {
|
| + self = [super initWithFrame:frame];
|
| + if (self)
|
| + delegate_ = delegate;
|
| +
|
| + return self;
|
| +}
|
| +
|
| +- (void)controllerDestroyed {
|
| + delegate_ = NULL;
|
| +}
|
| +
|
| +- (void)drawSeparatorWithBounds:(NSRect)bounds {
|
| + [[self separatorColor] set];
|
| + [NSBezierPath fillRect:bounds];
|
| +}
|
| +
|
| +// A slight optimization for drawing:
|
| +// https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaViewsGuide/Optimizing/Optimizing.html
|
| +- (BOOL)isOpaque {
|
| + return YES;
|
| +}
|
| +
|
| +- (BOOL)isFlipped {
|
| + // Flipped so that it's easier to share controller logic with other OSes.
|
| + return YES;
|
| +}
|
| +
|
| +- (void)drawBackgroundAndBorderInRect:(NSRect)dirtyRect {
|
| + // The inset is needed since the border is centered on the |path|.
|
| + // TODO(isherman): We should consider using asset-based drawing for the
|
| + // border, creating simple bitmaps for the view's border and background, and
|
| + // drawing them using NSDrawNinePartImage().
|
| + CGFloat inset = autofill::kPopupBorderThickness / 2.0;
|
| + NSRect borderRect = NSInsetRect([self bounds], inset, inset);
|
| + NSBezierPath* path = [NSBezierPath bezierPathWithRect:borderRect];
|
| + [[self backgroundColor] setFill];
|
| + [path fill];
|
| + [path setLineWidth:autofill::kPopupBorderThickness];
|
| + [[self borderColor] setStroke];
|
| + [path stroke];
|
| +}
|
| +
|
| +#pragma mark -
|
| +#pragma mark Messages from AutofillPopupViewBridge:
|
| +
|
| +- (void)updateBoundsAndRedrawPopup {
|
| + NSRect frame = NSRectFromCGRect(delegate_->popup_bounds().ToCGRect());
|
| +
|
| + // Flip coordinates back into Cocoa-land. The controller's platform-neutral
|
| + // coordinate space places the origin at the top-left of the first screen,
|
| + // whereas Cocoa's coordinate space expects the origin to be at the
|
| + // bottom-left of this same screen.
|
| + NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
| + frame.origin.y = NSMaxY([screen frame]) - NSMaxY(frame);
|
| +
|
| + // TODO(isherman): The view should support scrolling if the popup gets too
|
| + // big to fit on the screen.
|
| + [[self window] setFrame:frame display:YES];
|
| + [self setNeedsDisplay:YES];
|
| +}
|
| +
|
| +- (void)showPopup {
|
| + NSWindow* window =
|
| + [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
|
| + styleMask:NSBorderlessWindowMask
|
| + backing:NSBackingStoreBuffered
|
| + defer:YES];
|
| + [window setContentView:self];
|
| +
|
| + // Telling Cocoa that the window is opaque enables some drawing optimizations.
|
| + [window setOpaque:YES];
|
| +
|
| + [self updateBoundsAndRedrawPopup];
|
| + [[delegate_->container_view() window] addChildWindow:window
|
| + ordered:NSWindowAbove];
|
| +}
|
| +
|
| +- (void)hidePopup {
|
| + [self controllerDestroyed];
|
| +
|
| + // Remove the child window before closing, otherwise it can mess up
|
| + // display ordering.
|
| + NSWindow* window = [self window];
|
| + [[window parentWindow] removeChildWindow:window];
|
| + [window close];
|
| +}
|
| +
|
| +@end
|
|
|
| #pragma mark -
|
| #pragma mark Private methods
|
|
|
| @interface AutofillPopupViewCocoa ()
|
|
|
| -// Draws a thin separator in the popup UI.
|
| -- (void)drawSeparatorWithBounds:(NSRect)bounds;
|
| -
|
| // Draws an Autofill suggestion in the given |bounds|, labeled with the given
|
| // |name| and |subtext| hint. If the suggestion |isSelected|, then it is drawn
|
| // with a highlight. |index| determines the font to use, as well as the icon,
|
| @@ -88,7 +180,7 @@ NSColor* SubtextColor() {
|
|
|
| - (id)initWithController:(autofill::AutofillPopupController*)controller
|
| frame:(NSRect)frame {
|
| - self = [super initWithFrame:frame];
|
| + self = [super initWithAutofillPopupViewDelegate:controller frame:frame];
|
| if (self)
|
| controller_ = controller;
|
|
|
| @@ -98,35 +190,12 @@ NSColor* SubtextColor() {
|
| #pragma mark -
|
| #pragma mark NSView implementation:
|
|
|
| -// A slight optimization for drawing:
|
| -// https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaViewsGuide/Optimizing/Optimizing.html
|
| -- (BOOL)isOpaque {
|
| - return YES;
|
| -}
|
| -
|
| -- (BOOL)isFlipped {
|
| - // Flipped so that it's easier to share controller logic with other OSes.
|
| - return YES;
|
| -}
|
| -
|
| - (void)drawRect:(NSRect)dirtyRect {
|
| // If the view is in the process of being destroyed, don't bother drawing.
|
| if (!controller_)
|
| return;
|
|
|
| - // Draw the popup's background and border.
|
| - // The inset is needed since the border is centered on the |path|.
|
| - // TODO(isherman): We should consider using asset-based drawing for the
|
| - // border, creating simple bitmaps for the view's border and background, and
|
| - // drawing them using NSDrawNinePartImage().
|
| - CGFloat inset = autofill::kPopupBorderThickness / 2.0;
|
| - NSRect borderRect = NSInsetRect([self bounds], inset, inset);
|
| - NSBezierPath* path = [NSBezierPath bezierPathWithRect:borderRect];
|
| - [BackgroundColor() setFill];
|
| - [path fill];
|
| - [path setLineWidth:autofill::kPopupBorderThickness];
|
| - [BorderColor() setStroke];
|
| - [path stroke];
|
| + [self drawBackgroundAndBorderInRect:dirtyRect];
|
|
|
| for (size_t i = 0; i < controller_->names().size(); ++i) {
|
| // Skip rows outside of the dirty rect.
|
| @@ -196,14 +265,15 @@ NSColor* SubtextColor() {
|
| controller_ = NULL;
|
| }
|
|
|
| +- (void)invalidateRow:(size_t)row {
|
| + NSRect dirty_rect =
|
| + NSRectFromCGRect(controller_->GetRowBounds(row).ToCGRect());
|
| + [self setNeedsDisplayInRect:dirty_rect];
|
| +}
|
| +
|
| #pragma mark -
|
| #pragma mark Private API:
|
|
|
| -- (void)drawSeparatorWithBounds:(NSRect)bounds {
|
| - [SeparatorColor() set];
|
| - [NSBezierPath fillRect:bounds];
|
| -}
|
| -
|
| - (void)drawSuggestionWithName:(NSString*)name
|
| subtext:(NSString*)subtext
|
| index:(size_t)index
|
| @@ -211,14 +281,14 @@ NSColor* SubtextColor() {
|
| selected:(BOOL)isSelected {
|
| // If this row is selected, highlight it.
|
| if (isSelected) {
|
| - [HighlightColor() set];
|
| + [[self highlightColor] set];
|
| [NSBezierPath fillRect:bounds];
|
| }
|
|
|
| BOOL isRTL = controller_->IsRTL();
|
|
|
| NSColor* nameColor =
|
| - controller_->IsWarning(index) ? WarningColor() : NameColor();
|
| + controller_->IsWarning(index) ? [self warningColor] : [self nameColor];
|
| NSDictionary* nameAttributes =
|
| [NSDictionary dictionaryWithObjectsAndKeys:
|
| controller_->GetNameFontListForRow(index).GetPrimaryFont().
|
| @@ -262,7 +332,9 @@ NSColor* SubtextColor() {
|
| NSDictionary* subtextAttributes =
|
| [NSDictionary dictionaryWithObjectsAndKeys:
|
| controller_->subtext_font_list().GetPrimaryFont().GetNativeFont(),
|
| - NSFontAttributeName, SubtextColor(), NSForegroundColorAttributeName,
|
| + NSFontAttributeName,
|
| + [self subtextColor],
|
| + NSForegroundColorAttributeName,
|
| nil];
|
| NSSize subtextSize = [subtext sizeWithAttributes:subtextAttributes];
|
| x += isRTL ? 0 : -subtextSize.width;
|
|
|