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

Side by Side Diff: chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm

Issue 1099403005: [AiS] changing mac omnibox suggestions form NSMatrix to NSTableView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moved description access to test code Created 5 years, 6 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
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 #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/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/strings/sys_string_conversions.h" 10 #include "base/strings/sys_string_conversions.h"
(...skipping 11 matching lines...) Expand all
22 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h " 22 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h "
23 #import "ui/base/cocoa/cocoa_base_utils.h" 23 #import "ui/base/cocoa/cocoa_base_utils.h"
24 #import "ui/base/cocoa/flipped_view.h" 24 #import "ui/base/cocoa/flipped_view.h"
25 #include "ui/base/cocoa/window_size_constants.h" 25 #include "ui/base/cocoa/window_size_constants.h"
26 #include "ui/gfx/geometry/rect.h" 26 #include "ui/gfx/geometry/rect.h"
27 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" 27 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
28 #include "ui/gfx/text_elider.h" 28 #include "ui/gfx/text_elider.h"
29 29
30 namespace { 30 namespace {
31 31
32 // How much to adjust the cell sizing up from the default determined
33 // by the font.
34 const CGFloat kCellHeightAdjust = 6.0;
35
36 // Padding between matrix and the top and bottom of the popup window. 32 // Padding between matrix and the top and bottom of the popup window.
37 const CGFloat kPopupPaddingVertical = 5.0; 33 const CGFloat kPopupPaddingVertical = 5.0;
38 34
39 // Animation duration when animating the popup window smaller. 35 // Animation duration when animating the popup window smaller.
40 const NSTimeInterval kShrinkAnimationDuration = 0.1; 36 const NSTimeInterval kShrinkAnimationDuration = 0.1;
41 37
42 // Background colors for different states of the popup elements. 38 // Background colors for different states of the popup elements.
43 NSColor* BackgroundColor() { 39 NSColor* BackgroundColor() {
44 return [NSColor controlBackgroundColor]; 40 return [NSColor controlBackgroundColor];
45 } 41 }
(...skipping 30 matching lines...) Expand all
76 DCHECK([NSThread isMainThread]); 72 DCHECK([NSThread isMainThread]);
77 const AutocompleteResult& result = GetResult(); 73 const AutocompleteResult& result = GetResult();
78 const size_t start_match = result.ShouldHideTopMatch() ? 1 : 0; 74 const size_t start_match = result.ShouldHideTopMatch() ? 1 : 0;
79 const size_t rows = result.size() - start_match; 75 const size_t rows = result.size() - start_match;
80 if (rows == 0) { 76 if (rows == 0) {
81 [[popup_ parentWindow] removeChildWindow:popup_]; 77 [[popup_ parentWindow] removeChildWindow:popup_];
82 [popup_ orderOut:nil]; 78 [popup_ orderOut:nil];
83 79
84 // Break references to |this| because the popup may not be 80 // Break references to |this| because the popup may not be
85 // deallocated immediately. 81 // deallocated immediately.
86 [matrix_ setDelegate:nil]; 82 [matrix_ setObserver:NULL];
87 matrix_.reset(); 83 matrix_.reset();
88 84
89 popup_.reset(nil); 85 popup_.reset(nil);
90 86
91 target_popup_frame_ = NSZeroRect; 87 target_popup_frame_ = NSZeroRect;
92 88
93 return; 89 return;
94 } 90 }
95 91
96 CreatePopupIfNeeded(); 92 CreatePopupIfNeeded();
97 93
98 // Calculate the width of the matrix based on backing out the popup's border 94 NSImage* answerImage = nil;
99 // from the width of the field. 95 if (!model_->answer_bitmap().isNull()) {
100 const CGFloat matrix_width = NSWidth([field_ bounds]); 96 answerImage =
101 DCHECK_GT(matrix_width, 0.0); 97 gfx::Image::CreateFrom1xBitmap(model_->answer_bitmap()).CopyNSImage();
102
103 // Load the results into the popup's matrix.
104 DCHECK_GT(rows, 0U);
105 [matrix_ renewRows:rows columns:1];
106 CGFloat max_match_contents_width = 0.0f;
107 CGFloat contents_offset = -1.0f;
108 for (size_t ii = 0; ii < rows; ++ii) {
109 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0];
110 const AutocompleteMatch& match = GetResult().match_at(ii + start_match);
111 [cell setImage:ImageForMatch(match)];
112 [cell setMatch:match];
113 // Only set the image on the one cell with match.answer.
114 if (match.answer && !model_->answer_bitmap().isNull()) {
115 NSImage* image =
116 gfx::Image::CreateFrom1xBitmap(model_->answer_bitmap()).CopyNSImage();
117 [cell setAnswerImage:image];
118 }
119 if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) {
120 max_match_contents_width = std::max(max_match_contents_width,
121 [cell getMatchContentsWidth]);
122 if (contents_offset < 0.0f) {
123 contents_offset = [OmniboxPopupCell computeContentsOffset:match];
124 }
125 [cell setContentsOffset:contents_offset];
126 }
127 } 98 }
128 99 [matrix_ setController:[[OmniboxPopupTableController alloc]
129 for (size_t ii = 0; ii < rows; ++ii) { 100 initWithMatchResults:result
130 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0]; 101 popupView:*this
131 [cell setMaxMatchContentsWidth:max_match_contents_width]; 102 answerImage:answerImage]];
132 }
133
134 // Set the cell size to fit a line of text in the cell's font. All
135 // cells should use the same font and each should layout in one
136 // line, so they should all be about the same height.
137 const NSSize cell_size = [[matrix_ cellAtRow:0 column:0] cellSize];
138 DCHECK_GT(cell_size.height, 0.0);
139 const CGFloat cell_height = cell_size.height + kCellHeightAdjust;
140 [matrix_ setCellSize:NSMakeSize(matrix_width, cell_height)];
141 103
142 // Update the selection before placing (and displaying) the window. 104 // Update the selection before placing (and displaying) the window.
143 PaintUpdatesNow(); 105 PaintUpdatesNow();
144 106
145 // Calculate the matrix size manually rather than using -sizeToCells 107 // Calculate the matrix size manually rather than using -sizeToCells
146 // because actually resizing the matrix messed up the popup size 108 // because actually resizing the matrix messed up the popup size
147 // animation. 109 // animation.
148 DCHECK_EQ([matrix_ intercellSpacing].height, 0.0); 110 DCHECK_EQ([matrix_ intercellSpacing].height, 0.0);
149 PositionPopup(rows * cell_height); 111 PositionPopup(NSHeight([matrix_ frame]));
150 } 112 }
151 113
152 gfx::Rect OmniboxPopupViewMac::GetTargetBounds() { 114 gfx::Rect OmniboxPopupViewMac::GetTargetBounds() {
153 // Flip the coordinate system before returning. 115 // Flip the coordinate system before returning.
154 NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; 116 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
155 NSRect monitor_frame = [screen frame]; 117 NSRect monitor_frame = [screen frame];
156 gfx::Rect bounds(NSRectToCGRect(target_popup_frame_)); 118 gfx::Rect bounds(NSRectToCGRect(target_popup_frame_));
157 bounds.set_y(monitor_frame.size.height - bounds.y() - bounds.height()); 119 bounds.set_y(monitor_frame.size.height - bounds.y() - bounds.height());
158 return bounds; 120 return bounds;
159 } 121 }
160 122
161 // This is only called by model in SetSelectedLine() after updating 123 // This is only called by model in SetSelectedLine() after updating
162 // everything. Popup should already be visible. 124 // everything. Popup should already be visible.
163 void OmniboxPopupViewMac::PaintUpdatesNow() { 125 void OmniboxPopupViewMac::PaintUpdatesNow() {
164 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0; 126 [matrix_ selectRowIndex:model_->selected_line()];
165 if (start_match > model_->selected_line()) {
166 [matrix_ deselectAllCells];
167 } else {
168 [matrix_ selectCellAtRow:model_->selected_line() - start_match column:0];
169 }
170
171 } 127 }
172 128
173 void OmniboxPopupViewMac::OnMatrixRowSelected(OmniboxPopupMatrix* matrix, 129 void OmniboxPopupViewMac::OnMatrixRowSelected(OmniboxPopupMatrix* matrix,
174 size_t row) { 130 size_t row) {
175 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0; 131 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0;
176 model_->SetSelectedLine(row + start_match, false, false); 132 model_->SetSelectedLine(row + start_match, false, false);
177 } 133 }
178 134
179 void OmniboxPopupViewMac::OnMatrixRowClicked(OmniboxPopupMatrix* matrix, 135 void OmniboxPopupViewMac::OnMatrixRowClicked(OmniboxPopupMatrix* matrix,
180 size_t row) { 136 size_t row) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 NSRect popup_frame = anchor_rect_base; 197 NSRect popup_frame = anchor_rect_base;
242 // Size to fit the matrix and shift down by the size. 198 // Size to fit the matrix and shift down by the size.
243 popup_frame.size.height = matrixHeight + kPopupPaddingVertical * 2.0; 199 popup_frame.size.height = matrixHeight + kPopupPaddingVertical * 2.0;
244 popup_frame.size.height += [OmniboxPopupTopSeparatorView preferredHeight]; 200 popup_frame.size.height += [OmniboxPopupTopSeparatorView preferredHeight];
245 popup_frame.size.height += [OmniboxPopupBottomSeparatorView preferredHeight]; 201 popup_frame.size.height += [OmniboxPopupBottomSeparatorView preferredHeight];
246 popup_frame.origin.y -= NSHeight(popup_frame); 202 popup_frame.origin.y -= NSHeight(popup_frame);
247 // Shift to screen coordinates. 203 // Shift to screen coordinates.
248 popup_frame.origin = 204 popup_frame.origin =
249 [[controller window] convertBaseToScreen:popup_frame.origin]; 205 [[controller window] convertBaseToScreen:popup_frame.origin];
250 206
251 // Do nothing if the popup is already animating to the given |frame|.
252 if (NSEqualRects(popup_frame, target_popup_frame_))
253 return;
254
255 // Top separator. 207 // Top separator.
256 NSRect top_separator_frame = NSZeroRect; 208 NSRect top_separator_frame = NSZeroRect;
257 top_separator_frame.size.width = NSWidth(popup_frame); 209 top_separator_frame.size.width = NSWidth(popup_frame);
258 top_separator_frame.size.height = 210 top_separator_frame.size.height =
259 [OmniboxPopupTopSeparatorView preferredHeight]; 211 [OmniboxPopupTopSeparatorView preferredHeight];
260 [top_separator_view_ setFrame:top_separator_frame]; 212 [top_separator_view_ setFrame:top_separator_frame];
261 213
262 // Bottom separator. 214 // Bottom separator.
263 NSRect bottom_separator_frame = NSZeroRect; 215 NSRect bottom_separator_frame = NSZeroRect;
264 bottom_separator_frame.size.width = NSWidth(popup_frame); 216 bottom_separator_frame.size.width = NSWidth(popup_frame);
265 bottom_separator_frame.size.height = 217 bottom_separator_frame.size.height =
266 [OmniboxPopupBottomSeparatorView preferredHeight]; 218 [OmniboxPopupBottomSeparatorView preferredHeight];
267 bottom_separator_frame.origin.y = 219 bottom_separator_frame.origin.y =
268 NSHeight(popup_frame) - NSHeight(bottom_separator_frame); 220 NSHeight(popup_frame) - NSHeight(bottom_separator_frame);
269 [bottom_separator_view_ setFrame:bottom_separator_frame]; 221 [bottom_separator_view_ setFrame:bottom_separator_frame];
270 222
271 // Background view. 223 // Background view.
272 NSRect background_rect = NSZeroRect; 224 NSRect background_rect = NSZeroRect;
273 background_rect.size.width = NSWidth(popup_frame); 225 background_rect.size.width = NSWidth(popup_frame);
274 background_rect.size.height = NSHeight(popup_frame) - 226 background_rect.size.height = NSHeight(popup_frame) -
275 NSHeight(top_separator_frame) - NSHeight(bottom_separator_frame); 227 NSHeight(top_separator_frame) - NSHeight(bottom_separator_frame);
276 background_rect.origin.y = NSMaxY(top_separator_frame); 228 background_rect.origin.y = NSMaxY(top_separator_frame);
277 [background_view_ setFrame:background_rect]; 229 [background_view_ setFrame:background_rect];
278 230
231 // Calculate the width of the table based on backing out the popup's border
232 // from the width of the field.
233 const CGFloat tableWidth = NSWidth([field_ bounds]);
234 DCHECK_GT(tableWidth, 0.0);
235
279 // Matrix. 236 // Matrix.
280 NSPoint field_origin_base = 237 NSPoint field_origin_base =
281 [field_ convertPoint:[field_ bounds].origin toView:nil]; 238 [field_ convertPoint:[field_ bounds].origin toView:nil];
282 NSRect matrix_frame = NSZeroRect; 239 NSRect matrix_frame = NSZeroRect;
283 matrix_frame.origin.x = field_origin_base.x - NSMinX(anchor_rect_base); 240 matrix_frame.origin.x = field_origin_base.x - NSMinX(anchor_rect_base);
284 matrix_frame.origin.y = kPopupPaddingVertical; 241 matrix_frame.origin.y = kPopupPaddingVertical;
285 matrix_frame.size.width = [matrix_ cellSize].width; 242 matrix_frame.size.width = tableWidth;
286 matrix_frame.size.height = matrixHeight; 243 matrix_frame.size.height = matrixHeight;
287 [matrix_ setFrame:matrix_frame]; 244 [matrix_ setFrame:matrix_frame];
288 245
289 NSRect current_poup_frame = [popup_ frame]; 246 NSRect current_poup_frame = [popup_ frame];
290 target_popup_frame_ = popup_frame; 247 target_popup_frame_ = popup_frame;
291 248
292 // Animate the frame change if the only change is that the height got smaller. 249 // Animate the frame change if the only change is that the height got smaller.
293 // Otherwise, resize immediately. 250 // Otherwise, resize immediately.
294 bool animate = (NSHeight(popup_frame) < NSHeight(current_poup_frame) && 251 bool animate = (NSHeight(popup_frame) < NSHeight(current_poup_frame) &&
295 NSWidth(popup_frame) == NSWidth(current_poup_frame)); 252 NSWidth(popup_frame) == NSWidth(current_poup_frame));
(...skipping 21 matching lines...) Expand all
317 if (!animate) { 274 if (!animate) {
318 // Restore the original animations dictionary. This does not reinstate any 275 // Restore the original animations dictionary. This does not reinstate any
319 // previously running animations. 276 // previously running animations.
320 [popup_ setAnimations:savedAnimations]; 277 [popup_ setAnimations:savedAnimations];
321 } 278 }
322 279
323 if (![popup_ isVisible]) 280 if (![popup_ isVisible])
324 [[field_ window] addChildWindow:popup_ ordered:NSWindowAbove]; 281 [[field_ window] addChildWindow:popup_ ordered:NSWindowAbove];
325 } 282 }
326 283
327 NSImage* OmniboxPopupViewMac::ImageForMatch(const AutocompleteMatch& match) { 284 NSImage* OmniboxPopupViewMac::ImageForMatch(
285 const AutocompleteMatch& match) const {
328 gfx::Image image = model_->GetIconIfExtensionMatch(match); 286 gfx::Image image = model_->GetIconIfExtensionMatch(match);
329 if (!image.IsEmpty()) 287 if (!image.IsEmpty())
330 return image.AsNSImage(); 288 return image.AsNSImage();
331 289
332 const int resource_id = model_->IsStarredMatch(match) ? 290 const int resource_id = model_->IsStarredMatch(match) ?
333 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type); 291 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type);
334 return OmniboxViewMac::ImageForResource(resource_id); 292 return OmniboxViewMac::ImageForResource(resource_id);
335 } 293 }
336 294
337 void OmniboxPopupViewMac::OpenURLForRow(size_t row, 295 void OmniboxPopupViewMac::OpenURLForRow(size_t row,
338 WindowOpenDisposition disposition) { 296 WindowOpenDisposition disposition) {
339 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0; 297 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0;
340 row += start_match; 298 row += start_match;
341 DCHECK_LT(row, GetResult().size()); 299 DCHECK_LT(row, GetResult().size());
342 omnibox_view_->OpenMatch(GetResult().match_at(row), disposition, GURL(), 300 omnibox_view_->OpenMatch(GetResult().match_at(row), disposition, GURL(),
343 base::string16(), row); 301 base::string16(), row);
344 } 302 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698