Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 using autofill::AutofillPopupView; | 21 using autofill::AutofillPopupView; |
| 22 | 22 |
| 23 @interface AutofillPopupViewCocoa () | 23 @interface AutofillPopupViewCocoa () |
| 24 | 24 |
| 25 #pragma mark - | 25 #pragma mark - |
| 26 #pragma mark Private methods | 26 #pragma mark Private methods |
| 27 | 27 |
| 28 // Draws an Autofill suggestion in the given |bounds|, labeled with the given | 28 // Draws an Autofill suggestion in the given |bounds|, labeled with the given |
| 29 // |name| and |subtext| hint. If the suggestion |isSelected|, then it is drawn | 29 // |name| and |subtext| hint. If the suggestion |isSelected|, then it is drawn |
| 30 // with a highlight. |index| determines the font to use, as well as the icon, | 30 // with a highlight. |index| determines the font to use, as well as the icon, |
| 31 // if the row requires it -- such as for credit cards. | 31 // if the row requires it -- such as for credit cards. |imageFirst| indicates |
| 32 // whether the image should be drawn before the name, and with the same | |
| 33 // alignment, or whether it should be drawn afterwards, with the opposite | |
| 34 // alignment. | |
| 32 - (void)drawSuggestionWithName:(NSString*)name | 35 - (void)drawSuggestionWithName:(NSString*)name |
| 33 subtext:(NSString*)subtext | 36 subtext:(NSString*)subtext |
| 34 index:(size_t)index | 37 index:(size_t)index |
| 35 bounds:(NSRect)bounds | 38 bounds:(NSRect)bounds |
| 36 selected:(BOOL)isSelected; | 39 selected:(BOOL)isSelected |
| 40 imageFirst:(BOOL)imageFirst; | |
| 41 | |
|
groby-ooo-7-16
2014/05/22 21:22:17
Since this covers three functions, might want to m
erikchen
2014/05/22 22:24:35
Done.
| |
| 42 // If rightAlign == YES | |
|
groby-ooo-7-16
2014/05/22 21:22:17
nit:|rightAlign|, period
erikchen
2014/05/22 22:24:35
Done.
| |
| 43 // Draws the widget with right border aligned to |x|. | |
| 44 // Returns the x value of left border of the widget. | |
| 45 // If rightAlign == NO. | |
| 46 // Draws the widget with left border aligned to |x|. | |
| 47 // Returns the x value of right border of the widget. | |
| 48 - (CGFloat)drawName:(NSString*)name | |
| 49 atX:(CGFloat)x | |
| 50 index:(size_t)index | |
| 51 rightAlign:(BOOL)rightAlign | |
| 52 bounds:(NSRect)bounds; | |
| 53 - (CGFloat)drawIconAtIndex:(size_t)index | |
| 54 atX:(CGFloat)x | |
| 55 rightAlign:(BOOL)rightAlign | |
| 56 bounds:(NSRect)bounds; | |
| 57 - (CGFloat)drawSubtext:(NSString*)subtext | |
| 58 atX:(CGFloat)x | |
| 59 rightAlign:(BOOL)rightAlign | |
| 60 bounds:(NSRect)bounds; | |
| 37 | 61 |
| 38 // Returns the icon for the row with the given |index|, or |nil| if there is | 62 // Returns the icon for the row with the given |index|, or |nil| if there is |
| 39 // none. | 63 // none. |
| 40 - (NSImage*)iconAtIndex:(size_t)index; | 64 - (NSImage*)iconAtIndex:(size_t)index; |
| 41 | 65 |
| 42 @end | 66 @end |
| 43 | 67 |
| 44 @implementation AutofillPopupViewCocoa | 68 @implementation AutofillPopupViewCocoa |
| 45 | 69 |
| 46 #pragma mark - | 70 #pragma mark - |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 70 | 94 |
| 71 [self drawBackgroundAndBorder]; | 95 [self drawBackgroundAndBorder]; |
| 72 | 96 |
| 73 for (size_t i = 0; i < controller_->names().size(); ++i) { | 97 for (size_t i = 0; i < controller_->names().size(); ++i) { |
| 74 // Skip rows outside of the dirty rect. | 98 // Skip rows outside of the dirty rect. |
| 75 NSRect rowBounds = | 99 NSRect rowBounds = |
| 76 NSRectFromCGRect(controller_->GetRowBounds(i).ToCGRect()); | 100 NSRectFromCGRect(controller_->GetRowBounds(i).ToCGRect()); |
| 77 if (!NSIntersectsRect(rowBounds, dirtyRect)) | 101 if (!NSIntersectsRect(rowBounds, dirtyRect)) |
| 78 continue; | 102 continue; |
| 79 | 103 |
| 104 BOOL needsDraw = NO; | |
| 105 BOOL imageFirst = NO; | |
| 80 if (controller_->identifiers()[i] == autofill::POPUP_ITEM_ID_SEPARATOR) { | 106 if (controller_->identifiers()[i] == autofill::POPUP_ITEM_ID_SEPARATOR) { |
| 81 [self drawSeparatorWithBounds:rowBounds]; | 107 [self drawSeparatorWithBounds:rowBounds]; |
|
groby-ooo-7-16
2014/05/22 21:22:17
Add a return here, then you can skip needsDraw alt
erikchen
2014/05/22 22:24:35
Done. I also simplified the following else if/else
| |
| 108 } else if (controller_->identifiers()[i] == | |
| 109 autofill::POPUP_ITEM_ID_MAC_ACCESS_CONTACTS) { | |
| 110 needsDraw = YES; | |
| 111 imageFirst = YES; | |
| 82 } else { | 112 } else { |
| 113 needsDraw = YES; | |
| 114 imageFirst = NO; | |
| 115 } | |
| 116 | |
| 117 if (needsDraw) { | |
| 83 NSString* name = SysUTF16ToNSString(controller_->names()[i]); | 118 NSString* name = SysUTF16ToNSString(controller_->names()[i]); |
| 84 NSString* subtext = SysUTF16ToNSString(controller_->subtexts()[i]); | 119 NSString* subtext = SysUTF16ToNSString(controller_->subtexts()[i]); |
| 85 BOOL isSelected = static_cast<int>(i) == controller_->selected_line(); | 120 BOOL isSelected = static_cast<int>(i) == controller_->selected_line(); |
| 86 [self drawSuggestionWithName:name | 121 [self drawSuggestionWithName:name |
| 87 subtext:subtext | 122 subtext:subtext |
| 88 index:i | 123 index:i |
| 89 bounds:rowBounds | 124 bounds:rowBounds |
| 90 selected:isSelected]; | 125 selected:isSelected |
| 126 imageFirst:imageFirst]; | |
| 91 } | 127 } |
| 92 } | 128 } |
| 93 } | 129 } |
| 94 | 130 |
| 95 #pragma mark - | 131 #pragma mark - |
| 96 #pragma mark Public API: | 132 #pragma mark Public API: |
| 97 | 133 |
| 98 - (void)controllerDestroyed { | 134 - (void)controllerDestroyed { |
| 99 // Since the |controller_| either already has been destroyed or is about to | 135 // Since the |controller_| either already has been destroyed or is about to |
| 100 // be, about the only thing we can safely do with it is to null it out. | 136 // be, about the only thing we can safely do with it is to null it out. |
| 101 controller_ = NULL; | 137 controller_ = NULL; |
| 102 [super delegateDestroyed]; | 138 [super delegateDestroyed]; |
| 103 } | 139 } |
| 104 | 140 |
| 105 - (void)invalidateRow:(size_t)row { | 141 - (void)invalidateRow:(size_t)row { |
| 106 NSRect dirty_rect = | 142 NSRect dirty_rect = |
| 107 NSRectFromCGRect(controller_->GetRowBounds(row).ToCGRect()); | 143 NSRectFromCGRect(controller_->GetRowBounds(row).ToCGRect()); |
| 108 [self setNeedsDisplayInRect:dirty_rect]; | 144 [self setNeedsDisplayInRect:dirty_rect]; |
| 109 } | 145 } |
| 110 | 146 |
| 111 #pragma mark - | 147 #pragma mark - |
| 112 #pragma mark Private API: | 148 #pragma mark Private API: |
| 113 | 149 |
| 114 - (void)drawSuggestionWithName:(NSString*)name | 150 - (void)drawSuggestionWithName:(NSString*)name |
| 115 subtext:(NSString*)subtext | 151 subtext:(NSString*)subtext |
| 116 index:(size_t)index | 152 index:(size_t)index |
| 117 bounds:(NSRect)bounds | 153 bounds:(NSRect)bounds |
| 118 selected:(BOOL)isSelected { | 154 selected:(BOOL)isSelected |
| 155 imageFirst:(BOOL)imageFirst { | |
| 119 // If this row is selected, highlight it. | 156 // If this row is selected, highlight it. |
| 120 if (isSelected) { | 157 if (isSelected) { |
| 121 [[self highlightColor] set]; | 158 [[self highlightColor] set]; |
| 122 [NSBezierPath fillRect:bounds]; | 159 [NSBezierPath fillRect:bounds]; |
| 123 } | 160 } |
| 124 | 161 |
| 125 BOOL isRTL = controller_->IsRTL(); | 162 BOOL isRTL = controller_->IsRTL(); |
| 126 | 163 |
| 164 // The X values of the left and right borders of the autofill widget. | |
| 165 CGFloat leftX = bounds.origin.x + AutofillPopupView::kEndPadding; | |
|
groby-ooo-7-16
2014/05/22 21:22:17
NSMinX(bounds) + padding
erikchen
2014/05/22 22:24:35
Done.
| |
| 166 CGFloat rightX = | |
| 167 bounds.origin.x + bounds.size.width - AutofillPopupView::kEndPadding; | |
|
groby-ooo-7-16
2014/05/22 21:22:17
NSMaxX(bounds) + padding;
erikchen
2014/05/22 22:24:35
Done.
| |
| 168 | |
| 169 // All comments within the scope of this conditional assume RTL == NO. This | |
| 170 // allows the comments to more succinctly describe the intended behavior. All | |
| 171 // logic is simply inverted for RTL == YES. | |
|
groby-ooo-7-16
2014/05/22 21:22:17
I _think_ all that can be expressed a bit more con
erikchen
2014/05/22 22:24:35
I simplified the logic following your example, but
| |
| 172 if (imageFirst) { | |
| 173 // Draw the icon at the left border. | |
| 174 CGFloat x = isRTL ? rightX : leftX; | |
| 175 x = [self drawIconAtIndex:index atX:x rightAlign:isRTL bounds:bounds]; | |
| 176 // Draw the name immediately to the right of the icon. | |
| 177 [self drawName:name atX:x index:index rightAlign:isRTL bounds:bounds]; | |
| 178 | |
| 179 // Draw the subtext at the right border, right aligned. | |
| 180 x = isRTL ? leftX : rightX; | |
| 181 [self drawSubtext:subtext atX:x rightAlign:!isRTL bounds:bounds]; | |
| 182 } else { | |
| 183 // Draw the name at the left border. | |
| 184 CGFloat x = isRTL ? rightX : leftX; | |
| 185 [self drawName:name atX:x index:index rightAlign:isRTL bounds:bounds]; | |
| 186 | |
| 187 // Draw the icon at the right border, right aligned. | |
| 188 x = isRTL ? leftX : rightX; | |
| 189 x = [self drawIconAtIndex:index atX:x rightAlign:!isRTL bounds:bounds]; | |
| 190 // Draw the subtext immediately to the left of the icon, right aligned. | |
| 191 [self drawSubtext:subtext atX:x rightAlign:!isRTL bounds:bounds]; | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 - (CGFloat)drawName:(NSString*)name | |
| 196 atX:(CGFloat)x | |
| 197 index:(size_t)index | |
| 198 rightAlign:(BOOL)rightAlign | |
| 199 bounds:(NSRect)bounds { | |
| 127 NSColor* nameColor = | 200 NSColor* nameColor = |
| 128 controller_->IsWarning(index) ? [self warningColor] : [self nameColor]; | 201 controller_->IsWarning(index) ? [self warningColor] : [self nameColor]; |
| 129 NSDictionary* nameAttributes = | 202 NSDictionary* nameAttributes = |
| 130 [NSDictionary dictionaryWithObjectsAndKeys: | 203 [NSDictionary dictionaryWithObjectsAndKeys: |
| 131 controller_->GetNameFontListForRow(index).GetPrimaryFont(). | 204 controller_->GetNameFontListForRow(index).GetPrimaryFont(). |
| 132 GetNativeFont(), | 205 GetNativeFont(), |
| 133 NSFontAttributeName, nameColor, NSForegroundColorAttributeName, | 206 NSFontAttributeName, nameColor, NSForegroundColorAttributeName, |
| 134 nil]; | 207 nil]; |
| 135 NSSize nameSize = [name sizeWithAttributes:nameAttributes]; | 208 NSSize nameSize = [name sizeWithAttributes:nameAttributes]; |
| 136 CGFloat x = bounds.origin.x + | 209 x -= rightAlign ? nameSize.width : 0; |
| 137 (isRTL ? | |
| 138 bounds.size.width - AutofillPopupView::kEndPadding - nameSize.width : | |
| 139 AutofillPopupView::kEndPadding); | |
| 140 CGFloat y = bounds.origin.y + (bounds.size.height - nameSize.height) / 2; | 210 CGFloat y = bounds.origin.y + (bounds.size.height - nameSize.height) / 2; |
| 141 | 211 |
| 142 [name drawAtPoint:NSMakePoint(x, y) withAttributes:nameAttributes]; | 212 [name drawAtPoint:NSMakePoint(x, y) withAttributes:nameAttributes]; |
| 143 | 213 |
| 144 // The x-coordinate will be updated as each element is drawn. | 214 x += rightAlign ? 0 : nameSize.width; |
| 145 x = bounds.origin.x + | 215 return x; |
| 146 (isRTL ? | 216 } |
| 147 AutofillPopupView::kEndPadding : | |
| 148 bounds.size.width - AutofillPopupView::kEndPadding); | |
| 149 | 217 |
| 150 // Draw the Autofill icon, if one exists. | 218 - (CGFloat)drawIconAtIndex:(size_t)index |
| 219 atX:(CGFloat)x | |
| 220 rightAlign:(BOOL)rightAlign | |
| 221 bounds:(NSRect)bounds { | |
| 151 NSImage* icon = [self iconAtIndex:index]; | 222 NSImage* icon = [self iconAtIndex:index]; |
| 152 if (icon) { | 223 if (!icon) |
| 153 NSSize iconSize = [icon size]; | 224 return x; |
| 154 x += isRTL ? 0 : -iconSize.width; | 225 NSSize iconSize = [icon size]; |
| 155 y = bounds.origin.y + (bounds.size.height - iconSize.height) / 2; | 226 x -= rightAlign ? iconSize.width : 0; |
| 227 CGFloat y = bounds.origin.y + (bounds.size.height - iconSize.height) / 2; | |
| 156 [icon drawInRect:NSMakeRect(x, y, iconSize.width, iconSize.height) | 228 [icon drawInRect:NSMakeRect(x, y, iconSize.width, iconSize.height) |
| 157 fromRect:NSZeroRect | 229 fromRect:NSZeroRect |
| 158 operation:NSCompositeSourceOver | 230 operation:NSCompositeSourceOver |
| 159 fraction:1.0 | 231 fraction:1.0 |
| 160 respectFlipped:YES | 232 respectFlipped:YES |
| 161 hints:nil]; | 233 hints:nil]; |
| 162 | 234 |
| 163 x += isRTL ? | 235 x += rightAlign ? -AutofillPopupView::kIconPadding |
| 164 iconSize.width + AutofillPopupView::kIconPadding : | 236 : iconSize.width + AutofillPopupView::kIconPadding; |
| 165 -AutofillPopupView::kIconPadding; | 237 return x; |
| 166 } | 238 } |
| 167 | 239 |
| 168 // Draw the subtext. | 240 - (CGFloat)drawSubtext:(NSString*)subtext |
| 241 atX:(CGFloat)x | |
| 242 rightAlign:(BOOL)rightAlign | |
| 243 bounds:(NSRect)bounds { | |
| 169 NSDictionary* subtextAttributes = | 244 NSDictionary* subtextAttributes = |
| 170 [NSDictionary dictionaryWithObjectsAndKeys: | 245 [NSDictionary dictionaryWithObjectsAndKeys: |
| 171 controller_->subtext_font_list().GetPrimaryFont().GetNativeFont(), | 246 controller_->subtext_font_list().GetPrimaryFont().GetNativeFont(), |
| 172 NSFontAttributeName, | 247 NSFontAttributeName, |
| 173 [self subtextColor], | 248 [self subtextColor], |
| 174 NSForegroundColorAttributeName, | 249 NSForegroundColorAttributeName, |
| 175 nil]; | 250 nil]; |
| 176 NSSize subtextSize = [subtext sizeWithAttributes:subtextAttributes]; | 251 NSSize subtextSize = [subtext sizeWithAttributes:subtextAttributes]; |
| 177 x += isRTL ? 0 : -subtextSize.width; | 252 x -= rightAlign ? subtextSize.width : 0; |
| 178 y = bounds.origin.y + (bounds.size.height - subtextSize.height) / 2; | 253 CGFloat y = bounds.origin.y + (bounds.size.height - subtextSize.height) / 2; |
| 179 | 254 |
| 180 [subtext drawAtPoint:NSMakePoint(x, y) withAttributes:subtextAttributes]; | 255 [subtext drawAtPoint:NSMakePoint(x, y) withAttributes:subtextAttributes]; |
| 256 x += rightAlign ? 0 : subtextSize.width; | |
| 257 return x; | |
| 181 } | 258 } |
| 182 | 259 |
| 183 - (NSImage*)iconAtIndex:(size_t)index { | 260 - (NSImage*)iconAtIndex:(size_t)index { |
| 184 if (controller_->icons()[index].empty()) | 261 if (controller_->icons()[index].empty()) |
| 185 return nil; | 262 return nil; |
| 186 | 263 |
| 187 int iconId = controller_->GetIconResourceID(controller_->icons()[index]); | 264 int iconId = controller_->GetIconResourceID(controller_->icons()[index]); |
| 188 DCHECK_NE(-1, iconId); | 265 DCHECK_NE(-1, iconId); |
| 189 | 266 |
| 190 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 267 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 191 return rb.GetNativeImageNamed(iconId).ToNSImage(); | 268 return rb.GetNativeImageNamed(iconId).ToNSImage(); |
| 192 } | 269 } |
| 193 | 270 |
| 194 @end | 271 @end |
| OLD | NEW |