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 #include "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" | 5 #include "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/mac/mac_util.h" | 9 #include "base/mac/mac_util.h" |
10 #import "base/mac/sdk_forward_declarations.h" | 10 #import "base/mac/sdk_forward_declarations.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
13 #include "chrome/browser/search/search.h" | 13 #include "chrome/browser/search/search.h" |
14 #include "chrome/browser/ui/cocoa/browser_window_controller.h" | 14 #include "chrome/browser/ui/cocoa/browser_window_controller.h" |
15 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h" | 15 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h" |
16 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_separator_view.h" | 16 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_separator_view.h" |
17 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" | 17 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" |
18 #include "components/omnibox/browser/autocomplete_match.h" | 18 #include "components/omnibox/browser/autocomplete_match.h" |
19 #include "components/omnibox/browser/autocomplete_match_type.h" | 19 #include "components/omnibox/browser/autocomplete_match_type.h" |
20 #include "components/omnibox/browser/omnibox_edit_model.h" | 20 #include "components/omnibox/browser/omnibox_edit_model.h" |
21 #include "components/omnibox/browser/omnibox_popup_model.h" | 21 #include "components/omnibox/browser/omnibox_popup_model.h" |
22 #include "grit/theme_resources.h" | 22 #include "grit/theme_resources.h" |
23 #include "skia/ext/skia_utils_mac.h" | 23 #include "skia/ext/skia_utils_mac.h" |
24 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h " | 24 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h " |
25 #import "ui/base/cocoa/cocoa_base_utils.h" | 25 #import "ui/base/cocoa/cocoa_base_utils.h" |
26 #import "ui/base/cocoa/flipped_view.h" | 26 #import "ui/base/cocoa/flipped_view.h" |
27 #include "ui/base/cocoa/window_size_constants.h" | 27 #include "ui/base/cocoa/window_size_constants.h" |
28 #include "ui/base/material_design/material_design_controller.h" | |
29 #include "ui/gfx/color_palette.h" | |
28 #include "ui/gfx/geometry/rect.h" | 30 #include "ui/gfx/geometry/rect.h" |
31 #include "ui/gfx/image/image_skia_util_mac.h" | |
32 #include "ui/gfx/paint_vector_icon.h" | |
29 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 33 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
30 #include "ui/gfx/text_elider.h" | 34 #include "ui/gfx/text_elider.h" |
35 #include "ui/gfx/vector_icons_public.h" | |
31 | 36 |
32 namespace { | 37 namespace { |
33 | 38 |
39 const int kPopupPaddingVertical = 5; | |
40 const int kMaterialPopupPaddingVertical = 4; | |
41 | |
34 // Padding between matrix and the top and bottom of the popup window. | 42 // Padding between matrix and the top and bottom of the popup window. |
35 const CGFloat kPopupPaddingVertical = 5.0; | 43 CGFloat PopupPaddingVertical() { |
44 if (!ui::MaterialDesignController::IsModeMaterial()) { | |
45 return kPopupPaddingVertical; | |
46 } | |
47 return kMaterialPopupPaddingVertical; | |
48 } | |
36 | 49 |
37 // Animation duration when animating the popup window smaller. | 50 // Animation duration when animating the popup window smaller. |
38 const NSTimeInterval kShrinkAnimationDuration = 0.1; | 51 const NSTimeInterval kShrinkAnimationDuration = 0.1; |
39 | 52 |
53 } // namespace | |
54 | |
40 // Background colors for different states of the popup elements. | 55 // Background colors for different states of the popup elements. |
41 NSColor* BackgroundColor() { | 56 // Static. |
tapted
2016/04/28 14:29:44
// static
(I guess this is one exception to the "
shrike
2016/04/28 21:05:35
Done.
| |
42 return [NSColor controlBackgroundColor]; | 57 |
tapted
2016/04/28 14:29:44
remove blank line
shrike
2016/04/28 21:05:35
Done.
| |
58 NSColor* OmniboxPopupViewMac::BackgroundColor(BOOL is_dark_theme) { | |
59 const CGFloat kMDDarkControlBackround = 40 / 255.; | |
60 return is_dark_theme | |
61 ? [NSColor colorWithGenericGamma22White:kMDDarkControlBackround alpha:1] | |
62 : [NSColor controlBackgroundColor]; | |
43 } | 63 } |
44 | 64 |
45 } // namespace | |
46 | |
47 OmniboxPopupViewMac::OmniboxPopupViewMac(OmniboxView* omnibox_view, | 65 OmniboxPopupViewMac::OmniboxPopupViewMac(OmniboxView* omnibox_view, |
48 OmniboxEditModel* edit_model, | 66 OmniboxEditModel* edit_model, |
49 NSTextField* field) | 67 NSTextField* field) |
50 : omnibox_view_(omnibox_view), | 68 : omnibox_view_(omnibox_view), |
51 model_(new OmniboxPopupModel(this, edit_model)), | 69 model_(new OmniboxPopupModel(this, edit_model)), |
52 field_(field), | 70 field_(field), |
53 popup_(nil), | 71 popup_(nil), |
54 target_popup_frame_(NSZeroRect) { | 72 target_popup_frame_(NSZeroRect) { |
55 DCHECK(omnibox_view); | 73 DCHECK(omnibox_view); |
56 DCHECK(edit_model); | 74 DCHECK(edit_model); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 NSImage* answerImage = nil; | 113 NSImage* answerImage = nil; |
96 if (!model_->answer_bitmap().isNull()) { | 114 if (!model_->answer_bitmap().isNull()) { |
97 answerImage = | 115 answerImage = |
98 gfx::Image::CreateFrom1xBitmap(model_->answer_bitmap()).CopyNSImage(); | 116 gfx::Image::CreateFrom1xBitmap(model_->answer_bitmap()).CopyNSImage(); |
99 } | 117 } |
100 [matrix_ setController:[[OmniboxPopupTableController alloc] | 118 [matrix_ setController:[[OmniboxPopupTableController alloc] |
101 initWithMatchResults:result | 119 initWithMatchResults:result |
102 tableView:matrix_ | 120 tableView:matrix_ |
103 popupView:*this | 121 popupView:*this |
104 answerImage:answerImage]]; | 122 answerImage:answerImage]]; |
105 [matrix_ setSeparator:[OmniboxPopupCell createSeparatorString]]; | 123 BOOL is_dark_theme = [matrix_ hasDarkTheme]; |
124 [matrix_ setSeparator: | |
125 [OmniboxPopupCell createSeparatorStringForDarkTheme:is_dark_theme]]; | |
106 | 126 |
107 // Update the selection before placing (and displaying) the window. | 127 // Update the selection before placing (and displaying) the window. |
108 PaintUpdatesNow(); | 128 PaintUpdatesNow(); |
109 | 129 |
110 // Calculate the matrix size manually rather than using -sizeToCells | 130 // Calculate the matrix size manually rather than using -sizeToCells |
111 // because actually resizing the matrix messed up the popup size | 131 // because actually resizing the matrix messed up the popup size |
112 // animation. | 132 // animation. |
113 DCHECK_EQ([matrix_ intercellSpacing].height, 0.0); | 133 DCHECK_EQ([matrix_ intercellSpacing].height, 0.0); |
114 PositionPopup(NSHeight([matrix_ frame])); | 134 PositionPopup(NSHeight([matrix_ frame])); |
115 } | 135 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 defer:NO]); | 178 defer:NO]); |
159 [popup_ setBackgroundColor:[NSColor clearColor]]; | 179 [popup_ setBackgroundColor:[NSColor clearColor]]; |
160 [popup_ setOpaque:NO]; | 180 [popup_ setOpaque:NO]; |
161 | 181 |
162 // Use a flipped view to pin the matrix top the top left. This is needed | 182 // Use a flipped view to pin the matrix top the top left. This is needed |
163 // for animated resize. | 183 // for animated resize. |
164 base::scoped_nsobject<FlippedView> contentView( | 184 base::scoped_nsobject<FlippedView> contentView( |
165 [[FlippedView alloc] initWithFrame:NSZeroRect]); | 185 [[FlippedView alloc] initWithFrame:NSZeroRect]); |
166 [popup_ setContentView:contentView]; | 186 [popup_ setContentView:contentView]; |
167 | 187 |
188 BOOL is_dark_theme = ui::MaterialDesignController::IsModeMaterial() && | |
189 [[field_ window] hasDarkTheme]; | |
190 | |
168 // View to draw a background beneath the matrix. | 191 // View to draw a background beneath the matrix. |
169 background_view_.reset([[NSBox alloc] initWithFrame:NSZeroRect]); | 192 background_view_.reset([[NSBox alloc] initWithFrame:NSZeroRect]); |
170 [background_view_ setBoxType:NSBoxCustom]; | 193 [background_view_ setBoxType:NSBoxCustom]; |
171 [background_view_ setBorderType:NSNoBorder]; | 194 [background_view_ setBorderType:NSNoBorder]; |
172 [background_view_ setFillColor:BackgroundColor()]; | 195 [background_view_ setFillColor:BackgroundColor(is_dark_theme)]; |
173 [background_view_ setContentViewMargins:NSZeroSize]; | 196 [background_view_ setContentViewMargins:NSZeroSize]; |
174 [contentView addSubview:background_view_]; | 197 [contentView addSubview:background_view_]; |
175 | 198 |
176 matrix_.reset([[OmniboxPopupMatrix alloc] initWithObserver:this]); | 199 matrix_.reset([[OmniboxPopupMatrix alloc] initWithObserver:this |
200 forDarkTheme:is_dark_theme]); | |
177 [background_view_ addSubview:matrix_]; | 201 [background_view_ addSubview:matrix_]; |
178 | 202 |
179 top_separator_view_.reset( | 203 top_separator_view_.reset( |
180 [[OmniboxPopupTopSeparatorView alloc] initWithFrame:NSZeroRect]); | 204 [[OmniboxPopupTopSeparatorView alloc] initWithFrame:NSZeroRect]); |
181 [contentView addSubview:top_separator_view_]; | 205 [contentView addSubview:top_separator_view_]; |
182 | 206 |
183 bottom_separator_view_.reset( | 207 bottom_separator_view_.reset( |
184 [[OmniboxPopupBottomSeparatorView alloc] initWithFrame:NSZeroRect]); | 208 [[OmniboxPopupBottomSeparatorView alloc] initWithFrame:NSZeroRect |
209 forDarkTheme:is_dark_theme]); | |
185 [contentView addSubview:bottom_separator_view_]; | 210 [contentView addSubview:bottom_separator_view_]; |
186 | 211 |
187 // TODO(dtseng): Ignore until we provide NSAccessibility support. | 212 // TODO(dtseng): Ignore until we provide NSAccessibility support. |
188 [popup_ accessibilitySetOverrideValue:NSAccessibilityUnknownRole | 213 [popup_ accessibilitySetOverrideValue:NSAccessibilityUnknownRole |
189 forAttribute:NSAccessibilityRoleAttribute]; | 214 forAttribute:NSAccessibilityRoleAttribute]; |
190 } | 215 } |
191 } | 216 } |
192 | 217 |
193 void OmniboxPopupViewMac::PositionPopup(const CGFloat matrixHeight) { | 218 void OmniboxPopupViewMac::PositionPopup(const CGFloat matrixHeight) { |
194 BrowserWindowController* controller = | 219 BrowserWindowController* controller = |
195 [BrowserWindowController browserWindowControllerForView:field_]; | 220 [BrowserWindowController browserWindowControllerForView:field_]; |
196 NSRect anchor_rect_base = [controller omniboxPopupAnchorRect]; | 221 NSRect anchor_rect_base = [controller omniboxPopupAnchorRect]; |
197 | 222 |
198 // Calculate the popup's position on the screen. | 223 // Calculate the popup's position on the screen. |
199 NSRect popup_frame = anchor_rect_base; | 224 NSRect popup_frame = anchor_rect_base; |
200 // Size to fit the matrix and shift down by the size. | 225 // Size to fit the matrix and shift down by the size. |
201 popup_frame.size.height = matrixHeight + kPopupPaddingVertical * 2.0; | 226 popup_frame.size.height = matrixHeight + PopupPaddingVertical() * 2.0; |
202 popup_frame.size.height += [OmniboxPopupTopSeparatorView preferredHeight]; | 227 popup_frame.size.height += [OmniboxPopupTopSeparatorView preferredHeight]; |
203 popup_frame.size.height += [OmniboxPopupBottomSeparatorView preferredHeight]; | 228 popup_frame.size.height += [OmniboxPopupBottomSeparatorView preferredHeight]; |
204 popup_frame.origin.y -= NSHeight(popup_frame); | 229 popup_frame.origin.y -= NSHeight(popup_frame); |
205 | 230 |
206 // Shift to screen coordinates. | 231 // Shift to screen coordinates. |
207 if ([controller window]) { | 232 if ([controller window]) { |
208 popup_frame = [[controller window] convertRectToScreen:popup_frame]; | 233 popup_frame = [[controller window] convertRectToScreen:popup_frame]; |
209 } | 234 } |
210 | 235 |
211 // Top separator. | 236 // Top separator. |
(...skipping 13 matching lines...) Expand all Loading... | |
225 [bottom_separator_view_ setFrame:bottom_separator_frame]; | 250 [bottom_separator_view_ setFrame:bottom_separator_frame]; |
226 | 251 |
227 // Background view. | 252 // Background view. |
228 NSRect background_rect = NSZeroRect; | 253 NSRect background_rect = NSZeroRect; |
229 background_rect.size.width = NSWidth(popup_frame); | 254 background_rect.size.width = NSWidth(popup_frame); |
230 background_rect.size.height = NSHeight(popup_frame) - | 255 background_rect.size.height = NSHeight(popup_frame) - |
231 NSHeight(top_separator_frame) - NSHeight(bottom_separator_frame); | 256 NSHeight(top_separator_frame) - NSHeight(bottom_separator_frame); |
232 background_rect.origin.y = NSMaxY(top_separator_frame); | 257 background_rect.origin.y = NSMaxY(top_separator_frame); |
233 [background_view_ setFrame:background_rect]; | 258 [background_view_ setFrame:background_rect]; |
234 | 259 |
235 // Calculate the width of the table based on backing out the popup's border | 260 // In Material Design, the table is the width of the window. In non-MD, |
261 // calculate the width of the table based on backing out the popup's border | |
236 // from the width of the field. | 262 // from the width of the field. |
237 const CGFloat tableWidth = NSWidth([field_ bounds]); | 263 CGFloat table_width = NSWidth([background_view_ bounds]); |
238 DCHECK_GT(tableWidth, 0.0); | 264 bool is_mode_material = ui::MaterialDesignController::IsModeMaterial(); |
265 if (!is_mode_material) { | |
266 table_width = NSWidth([field_ bounds]); | |
267 } | |
268 DCHECK_GT(table_width, 0.0); | |
239 | 269 |
240 // Matrix. | 270 // Matrix. |
241 NSPoint field_origin_base = | 271 NSPoint field_origin_base = |
242 [field_ convertPoint:[field_ bounds].origin toView:nil]; | 272 [field_ convertPoint:[field_ bounds].origin toView:nil]; |
243 NSRect matrix_frame = NSZeroRect; | 273 NSRect matrix_frame = NSZeroRect; |
244 matrix_frame.origin.x = field_origin_base.x - NSMinX(anchor_rect_base); | 274 matrix_frame.origin.x = 0; |
245 matrix_frame.origin.y = kPopupPaddingVertical; | 275 if (!is_mode_material) { |
246 matrix_frame.size.width = tableWidth; | 276 matrix_frame.origin.x = field_origin_base.x - NSMinX(anchor_rect_base); |
277 } else { | |
278 [matrix_ setContentLeftPadding:field_origin_base.x]; | |
279 } | |
280 matrix_frame.origin.y = PopupPaddingVertical(); | |
281 matrix_frame.size.width = table_width; | |
247 matrix_frame.size.height = matrixHeight; | 282 matrix_frame.size.height = matrixHeight; |
248 [matrix_ setFrame:matrix_frame]; | 283 [matrix_ setFrame:matrix_frame]; |
249 [[[matrix_ tableColumns] objectAtIndex:0] setWidth:tableWidth]; | 284 [[[matrix_ tableColumns] objectAtIndex:0] setWidth:table_width]; |
250 | 285 |
251 // Don't play animation games on first display. | 286 // Don't play animation games on first display. |
252 target_popup_frame_ = popup_frame; | 287 target_popup_frame_ = popup_frame; |
253 if (![popup_ parentWindow]) { | 288 if (![popup_ parentWindow]) { |
254 DCHECK(![popup_ isVisible]); | 289 DCHECK(![popup_ isVisible]); |
255 [popup_ setFrame:popup_frame display:NO]; | 290 [popup_ setFrame:popup_frame display:NO]; |
256 [[field_ window] addChildWindow:popup_ ordered:NSWindowAbove]; | 291 [[field_ window] addChildWindow:popup_ ordered:NSWindowAbove]; |
257 return; | 292 return; |
258 } | 293 } |
259 DCHECK([popup_ isVisible]); | 294 DCHECK([popup_ isVisible]); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 [NSAnimationContext endGrouping]; | 330 [NSAnimationContext endGrouping]; |
296 | 331 |
297 if (!animate) { | 332 if (!animate) { |
298 // Restore the original animations dictionary. This does not reinstate any | 333 // Restore the original animations dictionary. This does not reinstate any |
299 // previously running animations. | 334 // previously running animations. |
300 [popup_ setAnimations:savedAnimations]; | 335 [popup_ setAnimations:savedAnimations]; |
301 } | 336 } |
302 } | 337 } |
303 | 338 |
304 NSImage* OmniboxPopupViewMac::ImageForMatch( | 339 NSImage* OmniboxPopupViewMac::ImageForMatch( |
305 const AutocompleteMatch& match) const { | 340 const AutocompleteMatch& match, |
341 BOOL ignore_dark_theme) const { | |
306 gfx::Image image = model_->GetIconIfExtensionMatch(match); | 342 gfx::Image image = model_->GetIconIfExtensionMatch(match); |
307 if (!image.IsEmpty()) | 343 if (!image.IsEmpty()) |
308 return image.AsNSImage(); | 344 return image.AsNSImage(); |
309 | 345 |
310 const int resource_id = model_->IsStarredMatch(match) ? | 346 if (!ui::MaterialDesignController::IsModeMaterial()) { |
311 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type); | 347 const int resource_id = model_->IsStarredMatch(match) ? |
312 return OmniboxViewMac::ImageForResource(resource_id); | 348 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type); |
349 return OmniboxViewMac::ImageForResource(resource_id); | |
350 } | |
351 bool is_dark_mode = !ignore_dark_theme && [matrix_ hasDarkTheme]; | |
352 const SkColor icon_color = | |
353 is_dark_mode ? SkColorSetA(SK_ColorWHITE, 0xCC) : gfx::kChromeIconGrey; | |
354 const gfx::VectorIconId vector_icon_id = model_->IsStarredMatch(match) | |
355 ? gfx::VectorIconId::LOCATION_BAR_STAR | |
356 : AutocompleteMatch::TypeToVectorIcon(match.type); | |
357 const int kIconSize = 16; | |
358 return NSImageFromImageSkia(gfx::CreateVectorIcon(vector_icon_id, | |
359 kIconSize, | |
360 icon_color)); | |
313 } | 361 } |
314 | 362 |
315 void OmniboxPopupViewMac::OpenURLForRow(size_t row, | 363 void OmniboxPopupViewMac::OpenURLForRow(size_t row, |
316 WindowOpenDisposition disposition) { | 364 WindowOpenDisposition disposition) { |
317 DCHECK_LT(row, GetResult().size()); | 365 DCHECK_LT(row, GetResult().size()); |
318 omnibox_view_->OpenMatch(GetResult().match_at(row), disposition, GURL(), | 366 omnibox_view_->OpenMatch(GetResult().match_at(row), disposition, GURL(), |
319 base::string16(), row); | 367 base::string16(), row); |
320 } | 368 } |
OLD | NEW |