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

Side by Side Diff: chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.mm

Issue 267183002: Password manager: Implement password generation UI for Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More implementation Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #import "chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.h" 5 #import "chrome/browser/ui/cocoa/autofill/autofill_popup_view_cocoa.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/sys_string_conversions.h" 8 #include "base/strings/sys_string_conversions.h"
9 #include "chrome/browser/ui/autofill/autofill_popup_controller.h" 9 #include "chrome/browser/ui/autofill/autofill_popup_controller.h"
10 #include "chrome/browser/ui/autofill/popup_constants.h" 10 #include "chrome/browser/ui/autofill/popup_constants.h"
11 #include "chrome/browser/ui/cocoa/autofill/autofill_popup_view_bridge.h" 11 #include "chrome/browser/ui/cocoa/autofill/autofill_popup_view_bridge.h"
12 #include "components/autofill/core/browser/popup_item_ids.h" 12 #include "components/autofill/core/browser/popup_item_ids.h"
13 #include "grit/ui_resources.h" 13 #include "grit/ui_resources.h"
14 #include "ui/base/cocoa/window_size_constants.h"
14 #include "ui/base/resource/resource_bundle.h" 15 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/gfx/font_list.h" 16 #include "ui/gfx/font_list.h"
16 #include "ui/gfx/image/image.h" 17 #include "ui/gfx/image/image.h"
17 #include "ui/gfx/point.h" 18 #include "ui/gfx/point.h"
18 #include "ui/gfx/rect.h" 19 #include "ui/gfx/rect.h"
19 20
20 using autofill::AutofillPopupView; 21 using autofill::AutofillPopupView;
21 22
22 namespace { 23 @implementation AutofillPopupBaseViewCocoa
23 24
24 NSColor* BackgroundColor() { 25 #pragma mark -
26 #pragma mark Colors
27
28 - (NSColor*)backgroundColor {
25 return [NSColor whiteColor]; 29 return [NSColor whiteColor];
26 } 30 }
27 31
28 // The color of the border around the popup. 32 - (NSColor*)borderColor {
29 NSColor* BorderColor() {
30 return [NSColor colorForControlTint:[NSColor currentControlTint]]; 33 return [NSColor colorForControlTint:[NSColor currentControlTint]];
31 } 34 }
32 35
33 NSColor* SeparatorColor() { 36 - (NSColor*)separatorColor {
34 return [NSColor colorWithCalibratedWhite:220 / 255.0 alpha:1]; 37 return [NSColor colorWithCalibratedWhite:220 / 255.0 alpha:1];
35 } 38 }
36 39
37 NSColor* HighlightColor() { 40 - (NSColor*)highlightColor {
38 return [NSColor selectedControlColor]; 41 return [NSColor selectedControlColor];
39 } 42 }
40 43
41 NSColor* NameColor() { 44 - (NSColor*)nameColor {
42 return [NSColor blackColor]; 45 return [NSColor blackColor];
43 } 46 }
44 47
45 NSColor* WarningColor() { 48 - (NSColor*)warningColor {
46 return [NSColor grayColor]; 49 return [NSColor grayColor];
47 } 50 }
48 51
49 NSColor* SubtextColor() { 52 - (NSColor*)subtextColor {
50 return [NSColor grayColor]; 53 return [NSColor grayColor];
51 } 54 }
52 55
53 } // namespace 56 #pragma mark -
57 #pragma mark Public methods
58
59 - (id)initWithAutofillPopupViewDelegate:
60 (autofill::AutofillPopupViewDelegate*)delegate frame:(NSRect)frame {
61 self = [super initWithFrame:frame];
62 if (self)
63 delegate_ = delegate;
64
65 return self;
66 }
67
68 - (void)controllerDestroyed {
69 delegate_ = NULL;
70 }
71
72 - (void)drawSeparatorWithBounds:(NSRect)bounds {
73 [[self separatorColor] set];
74 [NSBezierPath fillRect:bounds];
75 }
76
77 // A slight optimization for drawing:
78 // https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Cocoa ViewsGuide/Optimizing/Optimizing.html
79 - (BOOL)isOpaque {
80 return YES;
81 }
82
83 - (BOOL)isFlipped {
84 // Flipped so that it's easier to share controller logic with other OSes.
85 return YES;
86 }
87
88 - (void)drawBackgroundAndBorderInRect:(NSRect)dirtyRect {
89 // The inset is needed since the border is centered on the |path|.
90 // TODO(isherman): We should consider using asset-based drawing for the
91 // border, creating simple bitmaps for the view's border and background, and
92 // drawing them using NSDrawNinePartImage().
93 CGFloat inset = autofill::kPopupBorderThickness / 2.0;
94 NSRect borderRect = NSInsetRect([self bounds], inset, inset);
95 NSBezierPath* path = [NSBezierPath bezierPathWithRect:borderRect];
96 [[self backgroundColor] setFill];
97 [path fill];
98 [path setLineWidth:autofill::kPopupBorderThickness];
99 [[self borderColor] setStroke];
100 [path stroke];
101 }
102
103 #pragma mark -
104 #pragma mark Messages from AutofillPopupViewBridge:
105
106 - (void)updateBoundsAndRedrawPopup {
107 NSRect frame = NSRectFromCGRect(delegate_->popup_bounds().ToCGRect());
108
109 // Flip coordinates back into Cocoa-land. The controller's platform-neutral
110 // coordinate space places the origin at the top-left of the first screen,
111 // whereas Cocoa's coordinate space expects the origin to be at the
112 // bottom-left of this same screen.
113 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
114 frame.origin.y = NSMaxY([screen frame]) - NSMaxY(frame);
115
116 // TODO(isherman): The view should support scrolling if the popup gets too
117 // big to fit on the screen.
118 [[self window] setFrame:frame display:YES];
119 [self setNeedsDisplay:YES];
120 }
121
122 - (void)showPopup {
123 NSWindow* window =
124 [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
125 styleMask:NSBorderlessWindowMask
126 backing:NSBackingStoreBuffered
127 defer:YES];
128 [window setContentView:self];
129
130 // Telling Cocoa that the window is opaque enables some drawing optimizations.
131 [window setOpaque:YES];
132
133 [self updateBoundsAndRedrawPopup];
134 [[delegate_->container_view() window] addChildWindow:window
135 ordered:NSWindowAbove];
136 }
137
138 - (void)hidePopup {
139 [self controllerDestroyed];
140
141 // Remove the child window before closing, otherwise it can mess up
142 // display ordering.
143 NSWindow* window = [self window];
144 [[window parentWindow] removeChildWindow:window];
145 [window close];
146 }
147
148 @end
54 149
55 #pragma mark - 150 #pragma mark -
56 #pragma mark Private methods 151 #pragma mark Private methods
57 152
58 @interface AutofillPopupViewCocoa () 153 @interface AutofillPopupViewCocoa ()
59 154
60 // Draws a thin separator in the popup UI.
61 - (void)drawSeparatorWithBounds:(NSRect)bounds;
62
63 // Draws an Autofill suggestion in the given |bounds|, labeled with the given 155 // Draws an Autofill suggestion in the given |bounds|, labeled with the given
64 // |name| and |subtext| hint. If the suggestion |isSelected|, then it is drawn 156 // |name| and |subtext| hint. If the suggestion |isSelected|, then it is drawn
65 // with a highlight. |index| determines the font to use, as well as the icon, 157 // with a highlight. |index| determines the font to use, as well as the icon,
66 // if the row requires it -- such as for credit cards. 158 // if the row requires it -- such as for credit cards.
67 - (void)drawSuggestionWithName:(NSString*)name 159 - (void)drawSuggestionWithName:(NSString*)name
68 subtext:(NSString*)subtext 160 subtext:(NSString*)subtext
69 index:(size_t)index 161 index:(size_t)index
70 bounds:(NSRect)bounds 162 bounds:(NSRect)bounds
71 selected:(BOOL)isSelected; 163 selected:(BOOL)isSelected;
72 164
73 // Returns the icon for the row with the given |index|, or |nil| if there is 165 // Returns the icon for the row with the given |index|, or |nil| if there is
74 // none. 166 // none.
75 - (NSImage*)iconAtIndex:(size_t)index; 167 - (NSImage*)iconAtIndex:(size_t)index;
76 168
77 @end 169 @end
78 170
79 @implementation AutofillPopupViewCocoa 171 @implementation AutofillPopupViewCocoa
80 172
81 #pragma mark - 173 #pragma mark -
82 #pragma mark Initialisers 174 #pragma mark Initialisers
83 175
84 - (id)initWithFrame:(NSRect)frame { 176 - (id)initWithFrame:(NSRect)frame {
85 NOTREACHED(); 177 NOTREACHED();
86 return [self initWithController:NULL frame:frame]; 178 return [self initWithController:NULL frame:frame];
87 } 179 }
88 180
89 - (id)initWithController:(autofill::AutofillPopupController*)controller 181 - (id)initWithController:(autofill::AutofillPopupController*)controller
90 frame:(NSRect)frame { 182 frame:(NSRect)frame {
91 self = [super initWithFrame:frame]; 183 self = [super initWithAutofillPopupViewDelegate:controller frame:frame];
92 if (self) 184 if (self)
93 controller_ = controller; 185 controller_ = controller;
94 186
95 return self; 187 return self;
96 } 188 }
97 189
98 #pragma mark - 190 #pragma mark -
99 #pragma mark NSView implementation: 191 #pragma mark NSView implementation:
100 192
101 // A slight optimization for drawing:
102 // https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Cocoa ViewsGuide/Optimizing/Optimizing.html
103 - (BOOL)isOpaque {
104 return YES;
105 }
106
107 - (BOOL)isFlipped {
108 // Flipped so that it's easier to share controller logic with other OSes.
109 return YES;
110 }
111
112 - (void)drawRect:(NSRect)dirtyRect { 193 - (void)drawRect:(NSRect)dirtyRect {
113 // If the view is in the process of being destroyed, don't bother drawing. 194 // If the view is in the process of being destroyed, don't bother drawing.
114 if (!controller_) 195 if (!controller_)
115 return; 196 return;
116 197
117 // Draw the popup's background and border. 198 [self drawBackgroundAndBorderInRect:dirtyRect];
118 // The inset is needed since the border is centered on the |path|.
119 // TODO(isherman): We should consider using asset-based drawing for the
120 // border, creating simple bitmaps for the view's border and background, and
121 // drawing them using NSDrawNinePartImage().
122 CGFloat inset = autofill::kPopupBorderThickness / 2.0;
123 NSRect borderRect = NSInsetRect([self bounds], inset, inset);
124 NSBezierPath* path = [NSBezierPath bezierPathWithRect:borderRect];
125 [BackgroundColor() setFill];
126 [path fill];
127 [path setLineWidth:autofill::kPopupBorderThickness];
128 [BorderColor() setStroke];
129 [path stroke];
130 199
131 for (size_t i = 0; i < controller_->names().size(); ++i) { 200 for (size_t i = 0; i < controller_->names().size(); ++i) {
132 // Skip rows outside of the dirty rect. 201 // Skip rows outside of the dirty rect.
133 NSRect rowBounds = 202 NSRect rowBounds =
134 NSRectFromCGRect(controller_->GetRowBounds(i).ToCGRect()); 203 NSRectFromCGRect(controller_->GetRowBounds(i).ToCGRect());
135 if (!NSIntersectsRect(rowBounds, dirtyRect)) 204 if (!NSIntersectsRect(rowBounds, dirtyRect))
136 continue; 205 continue;
137 206
138 if (controller_->identifiers()[i] == autofill::POPUP_ITEM_ID_SEPARATOR) { 207 if (controller_->identifiers()[i] == autofill::POPUP_ITEM_ID_SEPARATOR) {
139 [self drawSeparatorWithBounds:rowBounds]; 208 [self drawSeparatorWithBounds:rowBounds];
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 258
190 #pragma mark - 259 #pragma mark -
191 #pragma mark Public API: 260 #pragma mark Public API:
192 261
193 - (void)controllerDestroyed { 262 - (void)controllerDestroyed {
194 // Since the |controller_| either already has been destroyed or is about to 263 // Since the |controller_| either already has been destroyed or is about to
195 // be, about the only thing we can safely do with it is to null it out. 264 // be, about the only thing we can safely do with it is to null it out.
196 controller_ = NULL; 265 controller_ = NULL;
197 } 266 }
198 267
268 - (void)invalidateRow:(size_t)row {
269 NSRect dirty_rect =
270 NSRectFromCGRect(controller_->GetRowBounds(row).ToCGRect());
271 [self setNeedsDisplayInRect:dirty_rect];
272 }
273
199 #pragma mark - 274 #pragma mark -
200 #pragma mark Private API: 275 #pragma mark Private API:
201 276
202 - (void)drawSeparatorWithBounds:(NSRect)bounds {
203 [SeparatorColor() set];
204 [NSBezierPath fillRect:bounds];
205 }
206
207 - (void)drawSuggestionWithName:(NSString*)name 277 - (void)drawSuggestionWithName:(NSString*)name
208 subtext:(NSString*)subtext 278 subtext:(NSString*)subtext
209 index:(size_t)index 279 index:(size_t)index
210 bounds:(NSRect)bounds 280 bounds:(NSRect)bounds
211 selected:(BOOL)isSelected { 281 selected:(BOOL)isSelected {
212 // If this row is selected, highlight it. 282 // If this row is selected, highlight it.
213 if (isSelected) { 283 if (isSelected) {
214 [HighlightColor() set]; 284 [[self highlightColor] set];
215 [NSBezierPath fillRect:bounds]; 285 [NSBezierPath fillRect:bounds];
216 } 286 }
217 287
218 BOOL isRTL = controller_->IsRTL(); 288 BOOL isRTL = controller_->IsRTL();
219 289
220 NSColor* nameColor = 290 NSColor* nameColor =
221 controller_->IsWarning(index) ? WarningColor() : NameColor(); 291 controller_->IsWarning(index) ? [self warningColor] : [self nameColor];
222 NSDictionary* nameAttributes = 292 NSDictionary* nameAttributes =
223 [NSDictionary dictionaryWithObjectsAndKeys: 293 [NSDictionary dictionaryWithObjectsAndKeys:
224 controller_->GetNameFontListForRow(index).GetPrimaryFont(). 294 controller_->GetNameFontListForRow(index).GetPrimaryFont().
225 GetNativeFont(), 295 GetNativeFont(),
226 NSFontAttributeName, nameColor, NSForegroundColorAttributeName, 296 NSFontAttributeName, nameColor, NSForegroundColorAttributeName,
227 nil]; 297 nil];
228 NSSize nameSize = [name sizeWithAttributes:nameAttributes]; 298 NSSize nameSize = [name sizeWithAttributes:nameAttributes];
229 CGFloat x = bounds.origin.x + 299 CGFloat x = bounds.origin.x +
230 (isRTL ? 300 (isRTL ?
231 bounds.size.width - AutofillPopupView::kEndPadding - nameSize.width : 301 bounds.size.width - AutofillPopupView::kEndPadding - nameSize.width :
(...skipping 23 matching lines...) Expand all
255 325
256 x += isRTL ? 326 x += isRTL ?
257 iconSize.width + AutofillPopupView::kIconPadding : 327 iconSize.width + AutofillPopupView::kIconPadding :
258 -AutofillPopupView::kIconPadding; 328 -AutofillPopupView::kIconPadding;
259 } 329 }
260 330
261 // Draw the subtext. 331 // Draw the subtext.
262 NSDictionary* subtextAttributes = 332 NSDictionary* subtextAttributes =
263 [NSDictionary dictionaryWithObjectsAndKeys: 333 [NSDictionary dictionaryWithObjectsAndKeys:
264 controller_->subtext_font_list().GetPrimaryFont().GetNativeFont(), 334 controller_->subtext_font_list().GetPrimaryFont().GetNativeFont(),
265 NSFontAttributeName, SubtextColor(), NSForegroundColorAttributeName, 335 NSFontAttributeName,
336 [self subtextColor],
337 NSForegroundColorAttributeName,
266 nil]; 338 nil];
267 NSSize subtextSize = [subtext sizeWithAttributes:subtextAttributes]; 339 NSSize subtextSize = [subtext sizeWithAttributes:subtextAttributes];
268 x += isRTL ? 0 : -subtextSize.width; 340 x += isRTL ? 0 : -subtextSize.width;
269 y = bounds.origin.y + (bounds.size.height - subtextSize.height) / 2; 341 y = bounds.origin.y + (bounds.size.height - subtextSize.height) / 2;
270 342
271 [subtext drawAtPoint:NSMakePoint(x, y) withAttributes:subtextAttributes]; 343 [subtext drawAtPoint:NSMakePoint(x, y) withAttributes:subtextAttributes];
272 } 344 }
273 345
274 - (NSImage*)iconAtIndex:(size_t)index { 346 - (NSImage*)iconAtIndex:(size_t)index {
275 if (controller_->icons()[index].empty()) 347 if (controller_->icons()[index].empty())
276 return nil; 348 return nil;
277 349
278 int iconId = controller_->GetIconResourceID(controller_->icons()[index]); 350 int iconId = controller_->GetIconResourceID(controller_->icons()[index]);
279 DCHECK_NE(-1, iconId); 351 DCHECK_NE(-1, iconId);
280 352
281 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 353 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
282 return rb.GetNativeImageNamed(iconId).ToNSImage(); 354 return rb.GetNativeImageNamed(iconId).ToNSImage();
283 } 355 }
284 356
285 @end 357 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698