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

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

Issue 17774002: OmniboxPopupViewMac refactoring Part 3 (truncation) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 | 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 #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"
11 #include "chrome/browser/autocomplete/autocomplete_match.h" 11 #include "chrome/browser/autocomplete/autocomplete_match.h"
12 #include "chrome/browser/search/search.h" 12 #include "chrome/browser/search/search.h"
13 #include "chrome/browser/ui/cocoa/browser_window_controller.h" 13 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
14 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h" 14 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h"
15 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" 15 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
16 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" 16 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
17 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 17 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
18 #include "chrome/browser/ui/omnibox/omnibox_popup_non_view.h" 18 #include "chrome/browser/ui/omnibox/omnibox_popup_non_view.h"
19 #include "grit/theme_resources.h" 19 #include "grit/theme_resources.h"
20 #include "skia/ext/skia_utils_mac.h" 20 #include "skia/ext/skia_utils_mac.h"
21 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" 21 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h"
22 #import "ui/base/cocoa/cocoa_event_utils.h" 22 #import "ui/base/cocoa/cocoa_event_utils.h"
23 #import "ui/base/cocoa/flipped_view.h" 23 #import "ui/base/cocoa/flipped_view.h"
24 #include "ui/base/cocoa/window_size_constants.h" 24 #include "ui/base/cocoa/window_size_constants.h"
25 #include "ui/base/resource/resource_bundle.h" 25 #include "ui/base/resource/resource_bundle.h"
26 #include "ui/base/text/text_elider.h"
27 #include "ui/gfx/rect.h" 26 #include "ui/gfx/rect.h"
28 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
29 27
30 namespace { 28 namespace {
31 29
32 // How much to adjust the cell sizing up from the default determined 30 // How much to adjust the cell sizing up from the default determined
33 // by the font. 31 // by the font.
34 const CGFloat kCellHeightAdjust = 6.0; 32 const CGFloat kCellHeightAdjust = 6.0;
35 33
36 // Padding between matrix and the top and bottom of the popup window. 34 // Padding between matrix and the top and bottom of the popup window.
37 const CGFloat kPopupPaddingVertical = 5.0; 35 const CGFloat kPopupPaddingVertical = 5.0;
38 36
39 // How far to offset the text column from the left.
40 const CGFloat kTextXOffset = 28.0;
41
42 // Animation duration when animating the popup window smaller. 37 // Animation duration when animating the popup window smaller.
43 const NSTimeInterval kShrinkAnimationDuration = 0.1; 38 const NSTimeInterval kShrinkAnimationDuration = 0.1;
44 39
45 // Maximum fraction of the popup width that can be used to display match
46 // contents.
47 const CGFloat kMaxContentsFraction = 0.7;
48
49 // Background colors for different states of the popup elements. 40 // Background colors for different states of the popup elements.
50 NSColor* BackgroundColor() { 41 NSColor* BackgroundColor() {
51 return [NSColor controlBackgroundColor]; 42 return [NSColor controlBackgroundColor];
52 } 43 }
53 44
54 NSColor* ContentTextColor() { 45 NSColor* ContentTextColor() {
55 return [NSColor blackColor]; 46 return [NSColor blackColor];
56 } 47 }
57 NSColor* DimContentTextColor() { 48 NSColor* DimContentTextColor() {
58 return [NSColor darkGrayColor]; 49 return [NSColor darkGrayColor];
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 DCHECK_GT(matrix_width, 0.0); 109 DCHECK_GT(matrix_width, 0.0);
119 110
120 // Load the results into the popup's matrix. 111 // Load the results into the popup's matrix.
121 const size_t rows = GetResult().size(); 112 const size_t rows = GetResult().size();
122 DCHECK_GT(rows, 0U); 113 DCHECK_GT(rows, 0U);
123 [matrix_ renewRows:rows columns:1]; 114 [matrix_ renewRows:rows columns:1];
124 for (size_t ii = 0; ii < rows; ++ii) { 115 for (size_t ii = 0; ii < rows; ++ii) {
125 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0]; 116 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0];
126 const AutocompleteMatch& match = GetResult().match_at(ii); 117 const AutocompleteMatch& match = GetResult().match_at(ii);
127 [cell setImage:ImageForMatch(match)]; 118 [cell setImage:ImageForMatch(match)];
128 [cell setAttributedTitle:MatchText(match, result_font, matrix_width)]; 119 [cell setContentText:DecorateMatchedString(match.contents,
120 match.contents_class,
121 ContentTextColor(),
122 DimContentTextColor(),
123 result_font)];
124 if (match.description.empty()) {
125 [cell setDescriptionText:nil];
126 } else {
127 NSMutableAttributedString* description =
128 DecorateMatchedString(match.description,
129 match.description_class,
130 DimContentTextColor(),
131 DimContentTextColor(),
132 result_font);
133 NSString* rawEnDash = @" \u2013 ";
134 [description replaceCharactersInRange:NSMakeRange(0, 0)
135 withString:rawEnDash];
Scott Hess - ex-Googler 2013/06/28 01:02:48 I almost want to have the spc en-dash spc sequence
sail 2013/06/28 18:41:16 Done.
136 [cell setDescriptionText:description];
137 }
129 } 138 }
130 139
131 // Set the cell size to fit a line of text in the cell's font. All 140 // Set the cell size to fit a line of text in the cell's font. All
132 // cells should use the same font and each should layout in one 141 // cells should use the same font and each should layout in one
133 // line, so they should all be about the same height. 142 // line, so they should all be about the same height.
134 const NSSize cell_size = [[matrix_ cellAtRow:0 column:0] cellSize]; 143 const NSSize cell_size = [[matrix_ cellAtRow:0 column:0] cellSize];
135 DCHECK_GT(cell_size.height, 0.0); 144 DCHECK_GT(cell_size.height, 0.0);
136 const CGFloat cell_height = cell_size.height + kCellHeightAdjust; 145 const CGFloat cell_height = cell_size.height + kCellHeightAdjust;
137 [matrix_ setCellSize:NSMakeSize(matrix_width, cell_height)]; 146 [matrix_ setCellSize:NSMakeSize(matrix_width, cell_height)];
138 147
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 size_t row) { 179 size_t row) {
171 OpenURLForRow(row, 180 OpenURLForRow(row,
172 ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent])); 181 ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]));
173 } 182 }
174 183
175 void OmniboxPopupViewMac::OnMatrixRowMiddleClicked(OmniboxPopupMatrix* matrix, 184 void OmniboxPopupViewMac::OnMatrixRowMiddleClicked(OmniboxPopupMatrix* matrix,
176 size_t row) { 185 size_t row) {
177 OpenURLForRow(row, NEW_BACKGROUND_TAB); 186 OpenURLForRow(row, NEW_BACKGROUND_TAB);
178 } 187 }
179 188
180 // Return the text to show for the match, based on the match's
181 // contents and description. Result will be in |font|, with the
182 // boldfaced version used for matches.
183 NSAttributedString* OmniboxPopupViewMac::MatchText(
184 const AutocompleteMatch& match,
185 gfx::Font& font,
186 float cell_width) {
187 NSMutableAttributedString *as =
188 DecorateMatchedString(match.contents,
189 match.contents_class,
190 ContentTextColor(),
191 DimContentTextColor(),
192 font);
193
194 // If there is a description, append it, separated from the contents
195 // with an en dash, and decorated with a distinct color.
196 if (!match.description.empty()) {
197 // Make sure the current string fits w/in kMaxContentsFraction of
198 // the cell to make sure the description will be at least
199 // partially visible.
200 // TODO(shess): Consider revising our NSCell subclass to have two
201 // bits and just draw them right, rather than truncating here.
202 const float text_width = cell_width - kTextXOffset;
203 as = ElideString(as, match.contents, font,
204 text_width * kMaxContentsFraction);
205
206 NSDictionary* attributes = @{
207 NSFontAttributeName : font.GetNativeFont(),
208 NSForegroundColorAttributeName : ContentTextColor()
209 };
210 NSString* raw_en_dash = @" \u2013 ";
211 NSAttributedString* en_dash =
212 [[[NSAttributedString alloc] initWithString:raw_en_dash
213 attributes:attributes] autorelease];
214
215 // In Windows, a boolean force_dim is passed as true for the
216 // description. Here, we pass the dim text color for both normal and dim,
217 // to accomplish the same thing.
218 NSAttributedString* description =
219 DecorateMatchedString(match.description, match.description_class,
220 DimContentTextColor(),
221 DimContentTextColor(),
222 font);
223
224 [as appendAttributedString:en_dash];
225 [as appendAttributedString:description];
226 }
227
228 NSMutableParagraphStyle* style =
229 [[[NSMutableParagraphStyle alloc] init] autorelease];
230 [style setLineBreakMode:NSLineBreakByTruncatingTail];
231 [style setTighteningFactorForTruncation:0.0];
232 [as addAttribute:NSParagraphStyleAttributeName value:style
233 range:NSMakeRange(0, [as length])];
234
235 return as;
236 }
237
238 // static 189 // static
239 NSMutableAttributedString* OmniboxPopupViewMac::DecorateMatchedString( 190 NSMutableAttributedString* OmniboxPopupViewMac::DecorateMatchedString(
240 const string16& match_string, 191 const string16& match_string,
241 const AutocompleteMatch::ACMatchClassifications& classifications, 192 const AutocompleteMatch::ACMatchClassifications& classifications,
242 NSColor* text_color, 193 NSColor* text_color,
243 NSColor* dim_text_color, 194 NSColor* dim_text_color,
244 gfx::Font& font) { 195 gfx::Font& font) {
245 // Cache for on-demand computation of the bold version of |font|. 196 // Cache for on-demand computation of the bold version of |font|.
246 NSFont* bold_font = nil; 197 NSFont* bold_font = nil;
247 198
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 if (0 != (i->style & ACMatchClassification::DIM)) { 244 if (0 != (i->style & ACMatchClassification::DIM)) {
294 [as addAttribute:NSForegroundColorAttributeName 245 [as addAttribute:NSForegroundColorAttributeName
295 value:dim_text_color 246 value:dim_text_color
296 range:range]; 247 range:range];
297 } 248 }
298 } 249 }
299 250
300 return as; 251 return as;
301 } 252 }
302 253
303 NSMutableAttributedString* OmniboxPopupViewMac::ElideString(
304 NSMutableAttributedString* a_string,
305 const string16& original_string,
306 const gfx::Font& font,
307 const float width) {
308 // If it already fits, nothing to be done.
309 if ([a_string size].width <= width) {
310 return a_string;
311 }
312
313 // If ElideText() decides to do nothing, nothing to be done.
314 const string16 elided =
315 ui::ElideText(original_string, font, width, ui::ELIDE_AT_END);
316 if (0 == elided.compare(original_string)) {
317 return a_string;
318 }
319
320 // If everything was elided away, clear the string.
321 if (elided.empty()) {
322 [a_string deleteCharactersInRange:NSMakeRange(0, [a_string length])];
323 return a_string;
324 }
325
326 // The ellipses should be the last character, and everything before
327 // that should match the original string.
328 const size_t i(elided.length() - 1);
329 DCHECK_NE(0, elided.compare(0, i, original_string));
330
331 // Replace the end of |aString| with the ellipses from |elided|.
332 NSString* s = base::SysUTF16ToNSString(elided.substr(i));
333 [a_string replaceCharactersInRange:NSMakeRange(i, [a_string length] - i)
334 withString:s];
335
336 return a_string;
337 }
338
339 const AutocompleteResult& OmniboxPopupViewMac::GetResult() const { 254 const AutocompleteResult& OmniboxPopupViewMac::GetResult() const {
340 return model_->result(); 255 return model_->result();
341 } 256 }
342 257
343 void OmniboxPopupViewMac::CreatePopupIfNeeded() { 258 void OmniboxPopupViewMac::CreatePopupIfNeeded() {
344 if (!popup_) { 259 if (!popup_) {
345 popup_.reset( 260 popup_.reset(
346 [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater 261 [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
347 styleMask:NSBorderlessWindowMask 262 styleMask:NSBorderlessWindowMask
348 backing:NSBackingStoreBuffered 263 backing:NSBackingStoreBuffered
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 void OmniboxPopupViewMac::OpenURLForRow(size_t row, 362 void OmniboxPopupViewMac::OpenURLForRow(size_t row,
448 WindowOpenDisposition disposition) { 363 WindowOpenDisposition disposition) {
449 DCHECK_GE(row, 0u); 364 DCHECK_GE(row, 0u);
450 365
451 // OpenMatch() may close the popup, which will clear the result set and, by 366 // OpenMatch() may close the popup, which will clear the result set and, by
452 // extension, |match| and its contents. So copy the relevant match out to 367 // extension, |match| and its contents. So copy the relevant match out to
453 // make sure it stays alive until the call completes. 368 // make sure it stays alive until the call completes.
454 AutocompleteMatch match = GetResult().match_at(row); 369 AutocompleteMatch match = GetResult().match_at(row);
455 omnibox_view_->OpenMatch(match, disposition, GURL(), row); 370 omnibox_view_->OpenMatch(match, disposition, GURL(), row);
456 } 371 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698