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 #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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 gfx::Font result_font(OmniboxViewMac::GetFieldFont()); | 116 gfx::Font result_font(OmniboxViewMac::GetFieldFont()); |
| 117 | 117 |
| 118 // Calculate the width of the matrix based on backing out the popup's border | 118 // Calculate the width of the matrix based on backing out the popup's border |
| 119 // from the width of the field. | 119 // from the width of the field. |
| 120 const CGFloat matrix_width = NSWidth([field_ bounds]); | 120 const CGFloat matrix_width = NSWidth([field_ bounds]); |
| 121 DCHECK_GT(matrix_width, 0.0); | 121 DCHECK_GT(matrix_width, 0.0); |
| 122 | 122 |
| 123 // Load the results into the popup's matrix. | 123 // Load the results into the popup's matrix. |
| 124 DCHECK_GT(rows, 0U); | 124 DCHECK_GT(rows, 0U); |
| 125 [matrix_ renewRows:rows columns:1]; | 125 [matrix_ renewRows:rows columns:1]; |
| 126 | |
| 127 CGFloat max_contents_width = 0; | |
| 128 CGFloat max_required_width = 0; | |
| 126 for (size_t ii = 0; ii < rows; ++ii) { | 129 for (size_t ii = 0; ii < rows; ++ii) { |
| 127 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0]; | 130 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0]; |
| 128 const AutocompleteMatch& match = GetResult().match_at(ii + start_match); | 131 const AutocompleteMatch& match = GetResult().match_at(ii + start_match); |
| 129 [cell setImage:ImageForMatch(match)]; | 132 [cell setImage:ImageForMatch(match)]; |
| 130 [cell setAttributedTitle:MatchText(match, result_font, matrix_width)]; | 133 NSAttributedString* match_text = |
| 134 MatchText(match, result_font, matrix_width); | |
| 135 [cell setRequiredWidth:0.0f]; | |
| 136 [cell setContentsWidth:0.0f]; | |
| 137 | |
| 138 if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_INFINITE) { | |
| 139 // Use ignored_prefix from the fill_into_edit to compute the | |
| 140 // required_width and max_required_width. | |
| 141 size_t input_start = | |
| 142 (match.transition == content::PAGE_TRANSITION_KEYWORD) ? | |
| 143 match.keyword.length() + 1 : 0; | |
| 144 size_t contents_index = | |
| 145 match.fill_into_edit.length() - match.contents.length(); | |
| 146 | |
| 147 string16 ignored_prefix = match.fill_into_edit.substr(input_start, | |
| 148 contents_index - input_start); | |
| 149 NSMutableAttributedString* ignored_prefix_as = CreateAttributedString( | |
| 150 ignored_prefix, ContentTextColor(), result_font); | |
| 151 [ignored_prefix_as appendAttributedString:match_text]; | |
| 152 CGFloat required_width = [ignored_prefix_as size].width; | |
| 153 [cell setRequiredWidth:required_width]; | |
| 154 if (required_width > max_required_width) | |
| 155 max_required_width = required_width; | |
| 156 | |
| 157 // Use ellipsis prefix to compute the contents_width and | |
| 158 // max_contents_width. | |
| 159 NSMutableAttributedString* ellipsis_prefix = CreateAttributedString( | |
| 160 base::string16(gfx::kEllipsisUTF16).append(UTF8ToUTF16(" ")), | |
| 161 ContentTextColor(), result_font); | |
| 162 [ellipsis_prefix appendAttributedString:match_text]; | |
| 163 CGFloat contents_width = [ellipsis_prefix size].width; | |
| 164 [cell setContentsWidth:contents_width]; | |
| 165 if (contents_width > max_contents_width) | |
| 166 max_contents_width = contents_width; | |
| 167 match_text = ellipsis_prefix; | |
| 168 } | |
| 169 [cell setAttributedTitle:match_text]; | |
| 170 } | |
| 171 | |
| 172 | |
| 173 for (size_t ii = 0; ii < rows; ++ii) { | |
| 174 const AutocompleteMatch& match = GetResult().match_at(ii + start_match); | |
| 175 OmniboxPopupCell* cell = [matrix_ cellAtRow:ii column:0]; | |
| 176 [cell setMaxRequiredWidth:0]; | |
| 177 [cell setMaxContentsWidth:0]; | |
| 178 if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_INFINITE) { | |
| 179 [cell setMaxRequiredWidth:max_required_width]; | |
| 180 [cell setMaxContentsWidth:max_contents_width]; | |
| 181 } | |
|
Scott Hess - ex-Googler
2013/12/16 22:22:05
I feel like we're missing each other, here. I'm c
Anuj
2013/12/19 05:36:13
My problem is that the implementations of omnibox
Scott Hess - ex-Googler
2013/12/19 20:12:50
That helps maintainability of your feature, but do
| |
| 131 } | 182 } |
| 132 | 183 |
| 133 // Set the cell size to fit a line of text in the cell's font. All | 184 // Set the cell size to fit a line of text in the cell's font. All |
| 134 // cells should use the same font and each should layout in one | 185 // cells should use the same font and each should layout in one |
| 135 // line, so they should all be about the same height. | 186 // line, so they should all be about the same height. |
| 136 const NSSize cell_size = [[matrix_ cellAtRow:0 column:0] cellSize]; | 187 const NSSize cell_size = [[matrix_ cellAtRow:0 column:0] cellSize]; |
| 137 DCHECK_GT(cell_size.height, 0.0); | 188 DCHECK_GT(cell_size.height, 0.0); |
| 138 const CGFloat cell_height = cell_size.height + kCellHeightAdjust; | 189 const CGFloat cell_height = cell_size.height + kCellHeightAdjust; |
| 139 [matrix_ setCellSize:NSMakeSize(matrix_width, cell_height)]; | 190 [matrix_ setCellSize:NSMakeSize(matrix_width, cell_height)]; |
| 140 | 191 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 [[[NSMutableParagraphStyle alloc] init] autorelease]; | 289 [[[NSMutableParagraphStyle alloc] init] autorelease]; |
| 239 [style setLineBreakMode:NSLineBreakByTruncatingTail]; | 290 [style setLineBreakMode:NSLineBreakByTruncatingTail]; |
| 240 [style setTighteningFactorForTruncation:0.0]; | 291 [style setTighteningFactorForTruncation:0.0]; |
| 241 [as addAttribute:NSParagraphStyleAttributeName value:style | 292 [as addAttribute:NSParagraphStyleAttributeName value:style |
| 242 range:NSMakeRange(0, [as length])]; | 293 range:NSMakeRange(0, [as length])]; |
| 243 | 294 |
| 244 return as; | 295 return as; |
| 245 } | 296 } |
| 246 | 297 |
| 247 // static | 298 // static |
| 248 NSMutableAttributedString* OmniboxPopupViewMac::DecorateMatchedString( | 299 NSMutableAttributedString* OmniboxPopupViewMac::CreateAttributedString( |
|
Scott Hess - ex-Googler
2013/12/16 22:22:05
I think DecorateMatchedString() was a static membe
Anuj
2013/12/19 05:36:13
Moved to the anonymous namespace.
| |
| 249 const base::string16& match_string, | 300 const base::string16& match_string, |
| 250 const AutocompleteMatch::ACMatchClassifications& classifications, | |
| 251 NSColor* text_color, | 301 NSColor* text_color, |
| 252 NSColor* dim_text_color, | |
| 253 gfx::Font& font) { | 302 gfx::Font& font) { |
| 254 // Cache for on-demand computation of the bold version of |font|. | |
| 255 NSFont* bold_font = nil; | |
| 256 | 303 |
| 257 // Start out with a string using the default style info. | 304 // Start out with a string using the default style info. |
| 258 NSString* s = base::SysUTF16ToNSString(match_string); | 305 NSString* s = base::SysUTF16ToNSString(match_string); |
| 259 NSDictionary* attributes = @{ | 306 NSDictionary* attributes = @{ |
| 260 NSFontAttributeName : font.GetNativeFont(), | 307 NSFontAttributeName : font.GetNativeFont(), |
| 261 NSForegroundColorAttributeName : text_color | 308 NSForegroundColorAttributeName : text_color |
| 262 }; | 309 }; |
| 263 NSMutableAttributedString* as = | 310 NSMutableAttributedString* as = |
| 264 [[[NSMutableAttributedString alloc] initWithString:s | 311 [[[NSMutableAttributedString alloc] initWithString:s |
| 265 attributes:attributes] | 312 attributes:attributes] |
| 266 autorelease]; | 313 autorelease]; |
| 314 return as; | |
| 315 } | |
| 316 | |
| 317 // static | |
| 318 NSMutableAttributedString* OmniboxPopupViewMac::DecorateMatchedString( | |
| 319 const base::string16& match_string, | |
| 320 const AutocompleteMatch::ACMatchClassifications& classifications, | |
| 321 NSColor* text_color, | |
| 322 NSColor* dim_text_color, | |
| 323 gfx::Font& font) { | |
| 324 | |
| 325 NSMutableAttributedString* as = | |
| 326 CreateAttributedString(match_string, text_color, font); | |
| 327 | |
| 328 size_t match_length = match_string.length(); | |
| 267 | 329 |
| 268 // As a protective measure, bail if the length of the match string is not | 330 // As a protective measure, bail if the length of the match string is not |
| 269 // the same as the length of the converted NSString. http://crbug.com/121703 | 331 // the same as the length of the converted NSString. http://crbug.com/121703 |
| 270 if ([s length] != match_string.size()) | 332 if ([as length] != match_length) |
| 271 return as; | 333 return as; |
| 272 | 334 |
| 335 // Cache for on-demand computation of the bold version of |font|. | |
| 336 NSFont* bold_font = nil; | |
|
Scott Hess - ex-Googler
2013/12/16 22:22:05
The next comment should come after a whitespace li
Anuj
2013/12/19 05:36:13
Done.
| |
| 273 // Mark up the runs which differ from the default. | 337 // Mark up the runs which differ from the default. |
| 274 for (ACMatchClassifications::const_iterator i = classifications.begin(); | 338 for (ACMatchClassifications::const_iterator i = classifications.begin(); |
| 275 i != classifications.end(); ++i) { | 339 i != classifications.end(); ++i) { |
| 276 const BOOL is_last = (i+1) == classifications.end(); | 340 const BOOL is_last = (i+1) == classifications.end(); |
| 277 const NSInteger next_offset = | 341 const NSInteger next_offset = |
| 278 (is_last ? [s length] : static_cast<NSInteger>((i + 1)->offset)); | 342 (is_last ? match_length : static_cast<NSInteger>((i + 1)->offset)); |
| 279 const NSInteger location = static_cast<NSInteger>(i->offset); | 343 const NSInteger location = static_cast<NSInteger>(i->offset); |
| 280 const NSInteger length = next_offset - static_cast<NSInteger>(i->offset); | 344 const NSInteger length = next_offset - static_cast<NSInteger>(i->offset); |
| 281 // Guard against bad, off-the-end classification ranges. | 345 // Guard against bad, off-the-end classification ranges. |
| 282 if (i->offset >= [s length] || length <= 0) | 346 if (i->offset >= match_length || length <= 0) |
| 283 break; | 347 break; |
| 284 const NSRange range = NSMakeRange(location, | 348 const NSRange range = NSMakeRange(location, |
| 285 MIN(length, static_cast<NSInteger>([s length]) - location)); | 349 MIN(length, static_cast<NSInteger>(match_length) - location)); |
| 286 | 350 |
| 287 if (0 != (i->style & ACMatchClassification::URL)) { | 351 if (0 != (i->style & ACMatchClassification::URL)) { |
| 288 [as addAttribute:NSForegroundColorAttributeName | 352 [as addAttribute:NSForegroundColorAttributeName |
| 289 value:URLTextColor() | 353 value:URLTextColor() |
| 290 range:range]; | 354 range:range]; |
| 291 } | 355 } |
| 292 | 356 |
| 293 if (0 != (i->style & ACMatchClassification::MATCH)) { | 357 if (0 != (i->style & ACMatchClassification::MATCH)) { |
| 294 if (!bold_font) { | 358 if (!bold_font) { |
| 295 NSFontManager* font_manager = [NSFontManager sharedFontManager]; | 359 NSFontManager* font_manager = [NSFontManager sharedFontManager]; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 return OmniboxViewMac::ImageForResource(resource_id); | 556 return OmniboxViewMac::ImageForResource(resource_id); |
| 493 } | 557 } |
| 494 | 558 |
| 495 void OmniboxPopupViewMac::OpenURLForRow(size_t row, | 559 void OmniboxPopupViewMac::OpenURLForRow(size_t row, |
| 496 WindowOpenDisposition disposition) { | 560 WindowOpenDisposition disposition) { |
| 497 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0; | 561 size_t start_match = model_->result().ShouldHideTopMatch() ? 1 : 0; |
| 498 row += start_match; | 562 row += start_match; |
| 499 DCHECK_LT(row, GetResult().size()); | 563 DCHECK_LT(row, GetResult().size()); |
| 500 omnibox_view_->OpenMatch(GetResult().match_at(row), disposition, GURL(), row); | 564 omnibox_view_->OpenMatch(GetResult().match_at(row), disposition, GURL(), row); |
| 501 } | 565 } |
| OLD | NEW |