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

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

Issue 2906893004: Omnibox UI Experiments: Port Vertical Layout experiment to Mac Cocoa. (Closed)
Patch Set: fix camel case Created 3 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/omnibox/omnibox_popup_cell.h" 5 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
11 11
12 #include "base/feature_list.h"
12 #include "base/i18n/rtl.h" 13 #include "base/i18n/rtl.h"
13 #include "base/mac/foundation_util.h" 14 #include "base/mac/foundation_util.h"
14 #include "base/mac/objc_property_releaser.h" 15 #include "base/mac/objc_property_releaser.h"
15 #include "base/mac/scoped_nsobject.h" 16 #include "base/mac/scoped_nsobject.h"
16 #include "base/metrics/field_trial_params.h" 17 #include "base/metrics/field_trial_params.h"
17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/strings/sys_string_conversions.h" 20 #include "base/strings/sys_string_conversions.h"
20 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
21 #include "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" 22 #include "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h"
(...skipping 11 matching lines...) Expand all
33 34
34 namespace { 35 namespace {
35 36
36 // Extra padding beyond the vertical text padding. 37 // Extra padding beyond the vertical text padding.
37 constexpr CGFloat kMaterialExtraVerticalImagePadding = 2.0; 38 constexpr CGFloat kMaterialExtraVerticalImagePadding = 2.0;
38 39
39 constexpr CGFloat kMaterialTextStartOffset = 27.0; 40 constexpr CGFloat kMaterialTextStartOffset = 27.0;
40 41
41 constexpr CGFloat kMaterialImageXOffset = 6.0; 42 constexpr CGFloat kMaterialImageXOffset = 6.0;
42 43
44 constexpr CGFloat kDefaultVerticalMargin = 3.0;
45
46 constexpr CGFloat kDefaultTextHeight = 19;
47
43 // Returns the margin that should appear at the top and bottom of the result. 48 // Returns the margin that should appear at the top and bottom of the result.
44 CGFloat GetVerticalMargin() { 49 CGFloat GetVerticalMargin() {
45 constexpr CGFloat kDefaultVerticalMargin = 3.0;
46
47 return base::GetFieldTrialParamByFeatureAsInt( 50 return base::GetFieldTrialParamByFeatureAsInt(
48 omnibox::kUIExperimentVerticalMargin, 51 omnibox::kUIExperimentVerticalMargin,
49 OmniboxFieldTrial::kUIVerticalMarginParam, kDefaultVerticalMargin); 52 OmniboxFieldTrial::kUIVerticalMarginParam, kDefaultVerticalMargin);
50 } 53 }
51 54
52 // Flips the given |rect| in context of the given |frame|. 55 // Flips the given |rect| in context of the given |frame|.
53 NSRect FlipIfRTL(NSRect rect, NSRect frame) { 56 NSRect FlipIfRTL(NSRect rect, NSRect frame) {
54 DCHECK_LE(NSMinX(frame), NSMinX(rect)); 57 DCHECK_LE(NSMinX(frame), NSMinX(rect));
55 DCHECK_GE(NSMaxX(frame), NSMaxX(rect)); 58 DCHECK_GE(NSMaxX(frame), NSMaxX(rect));
56 if (base::i18n::IsRTL()) { 59 if (base::i18n::IsRTL()) {
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 [CreateAnswerLine(match.answer->second_line(), isDarkTheme) retain]; 420 [CreateAnswerLine(match.answer->second_line(), isDarkTheme) retain];
418 maxLines_ = match.answer->second_line().num_text_lines(); 421 maxLines_ = match.answer->second_line().num_text_lines();
419 } else { 422 } else {
420 contents_ = [CreateClassifiedAttributedString( 423 contents_ = [CreateClassifiedAttributedString(
421 match.contents, ContentTextColor(isDarkTheme), match.contents_class, 424 match.contents, ContentTextColor(isDarkTheme), match.contents_class,
422 isDarkTheme) retain]; 425 isDarkTheme) retain];
423 if (!match.description.empty()) { 426 if (!match.description.empty()) {
424 description_ = [CreateClassifiedAttributedString( 427 description_ = [CreateClassifiedAttributedString(
425 match.description, DimTextColor(isDarkTheme), 428 match.description, DimTextColor(isDarkTheme),
426 match.description_class, isDarkTheme) retain]; 429 match.description_class, isDarkTheme) retain];
430
431 if (base::FeatureList::IsEnabled(
432 omnibox::kUIExperimentVerticalLayout) &&
433 !AutocompleteMatch::IsSearchType(match.type)) {
434 // Somtimes swap the contents and description in vertical layouts.
groby-ooo-7-16 2017/05/31 00:14:51 When is "sometimes"?
tommycli 2017/05/31 18:20:40 Done.
435 // TODO(tommycli): If vertical layouts become permanent, swap these
436 // in the underlying match instead of the UI code.
groby-ooo-7-16 2017/05/31 00:14:51 Rendering order should not really affect anything
tommycli 2017/05/31 18:20:40 Done.
437 NSAttributedString* temp = contents_;
groby-ooo-7-16 2017/05/31 00:14:51 std::swap(contents_, description_)
tommycli 2017/05/31 18:20:40 Done. Always forget that ObjC is also C++ ... or i
438 contents_ = description_;
439 description_ = temp;
440 }
427 } 441 }
428 maxLines_ = 1;
429 } 442 }
430 propertyReleaser_OmniboxPopupCellData_.Init(self, 443 propertyReleaser_OmniboxPopupCellData_.Init(self,
431 [OmniboxPopupCellData class]); 444 [OmniboxPopupCellData class]);
432 } 445 }
433 return self; 446 return self;
434 } 447 }
435 448
436 - (instancetype)copyWithZone:(NSZone*)zone { 449 - (instancetype)copyWithZone:(NSZone*)zone {
437 return [self retain]; 450 return [self retain];
438 } 451 }
(...skipping 17 matching lines...) Expand all
456 } else { 469 } else {
457 [HoveredBackgroundColor(isDarkTheme) set]; 470 [HoveredBackgroundColor(isDarkTheme) set];
458 } 471 }
459 NSRectFillUsingOperation(cellFrame, NSCompositeSourceOver); 472 NSRectFillUsingOperation(cellFrame, NSCompositeSourceOver);
460 } 473 }
461 474
462 [self drawMatchWithFrame:cellFrame inView:controlView]; 475 [self drawMatchWithFrame:cellFrame inView:controlView];
463 } 476 }
464 477
465 - (void)drawMatchWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { 478 - (void)drawMatchWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
479 bool isVerticalLayout =
480 base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout);
481
466 OmniboxPopupCellData* cellData = 482 OmniboxPopupCellData* cellData =
467 base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]); 483 base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]);
468 OmniboxPopupMatrix* tableView = 484 OmniboxPopupMatrix* tableView =
469 base::mac::ObjCCastStrict<OmniboxPopupMatrix>(controlView); 485 base::mac::ObjCCastStrict<OmniboxPopupMatrix>(controlView);
470 CGFloat remainingWidth = [OmniboxPopupCell getContentAreaWidth:cellFrame] - 486 CGFloat remainingWidth = [OmniboxPopupCell getContentAreaWidth:cellFrame] -
471 [tableView contentLeftPadding]; 487 [tableView contentLeftPadding];
472 CGFloat contentsWidth = [cellData getMatchContentsWidth]; 488 CGFloat contentsWidth = [cellData getMatchContentsWidth];
473 CGFloat separatorWidth = [[tableView separator] size].width; 489 CGFloat separatorWidth = [[tableView separator] size].width;
474 CGFloat descriptionWidth = 490 CGFloat descriptionWidth =
475 [cellData description] ? [[cellData description] size].width : 0; 491 [cellData description] ? [[cellData description] size].width : 0;
476 int contentsMaxWidth, descriptionMaxWidth; 492 int contentsMaxWidth, descriptionMaxWidth;
477 OmniboxPopupModel::ComputeMatchMaxWidths( 493 OmniboxPopupModel::ComputeMatchMaxWidths(
478 ceilf(contentsWidth), ceilf(separatorWidth), ceilf(descriptionWidth), 494 ceilf(contentsWidth), ceilf(separatorWidth), ceilf(descriptionWidth),
479 ceilf(remainingWidth), 495 ceilf(remainingWidth), [cellData isAnswer] || isVerticalLayout,
480 [cellData isAnswer], 496 !AutocompleteMatch::IsSearchType([cellData matchType]), &contentsMaxWidth,
481 !AutocompleteMatch::IsSearchType([cellData matchType]),
482 &contentsMaxWidth,
483 &descriptionMaxWidth); 497 &descriptionMaxWidth);
484 498
499 CGFloat halfLineHeight = (kDefaultTextHeight + kDefaultVerticalMargin) / 2;
500
485 NSWindow* parentWindow = [[controlView window] parentWindow]; 501 NSWindow* parentWindow = [[controlView window] parentWindow];
486 BOOL isDarkTheme = [parentWindow hasDarkTheme]; 502 BOOL isDarkTheme = [parentWindow hasDarkTheme];
487 NSRect imageRect = cellFrame; 503 NSRect imageRect = cellFrame;
488 NSImage* theImage = 504 NSImage* theImage =
489 isDarkTheme ? [cellData incognitoImage] : [cellData image]; 505 isDarkTheme ? [cellData incognitoImage] : [cellData image];
490 imageRect.size = [theImage size]; 506 imageRect.size = [theImage size];
491 imageRect.origin.x += kMaterialImageXOffset + [tableView contentLeftPadding]; 507 imageRect.origin.x += kMaterialImageXOffset + [tableView contentLeftPadding];
492 imageRect.origin.y += 508 imageRect.origin.y +=
493 GetVerticalMargin() + kMaterialExtraVerticalImagePadding; 509 GetVerticalMargin() + kMaterialExtraVerticalImagePadding;
510 if (isVerticalLayout)
511 imageRect.origin.y += halfLineHeight;
494 [theImage drawInRect:FlipIfRTL(imageRect, cellFrame) 512 [theImage drawInRect:FlipIfRTL(imageRect, cellFrame)
495 fromRect:NSZeroRect 513 fromRect:NSZeroRect
496 operation:NSCompositeSourceOver 514 operation:NSCompositeSourceOver
497 fraction:1.0 515 fraction:1.0
498 respectFlipped:YES 516 respectFlipped:YES
499 hints:nil]; 517 hints:nil];
500 518
501 NSPoint origin = 519 CGFloat left = kMaterialTextStartOffset + [tableView contentLeftPadding];
502 NSMakePoint(kMaterialTextStartOffset + [tableView contentLeftPadding], 520 NSPoint origin = NSMakePoint(left, GetVerticalMargin());
503 GetVerticalMargin()); 521
522 // For matches lacking description in vertical layout, center vertically.
523 if (isVerticalLayout && descriptionMaxWidth == 0)
524 origin.y += halfLineHeight;
525
504 if ([cellData matchType] == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) { 526 if ([cellData matchType] == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) {
505 // Tail suggestions are rendered with a prefix (usually ellipsis), which 527 // Tail suggestions are rendered with a prefix (usually ellipsis), which
506 // appear vertically stacked. 528 // appear vertically stacked.
507 origin.x += [self drawMatchPrefixWithFrame:cellFrame 529 origin.x += [self drawMatchPrefixWithFrame:cellFrame
508 tableView:tableView 530 tableView:tableView
509 withContentsMaxWidth:&contentsMaxWidth 531 withContentsMaxWidth:&contentsMaxWidth
510 forDarkTheme:isDarkTheme]; 532 forDarkTheme:isDarkTheme];
511 } 533 }
512 origin.x += [self drawMatchPart:[cellData contents] 534 origin.x += [self drawMatchPart:[cellData contents]
513 withFrame:cellFrame 535 withFrame:cellFrame
514 origin:origin 536 origin:origin
515 withMaxWidth:contentsMaxWidth 537 withMaxWidth:contentsMaxWidth
516 forDarkTheme:isDarkTheme]; 538 forDarkTheme:isDarkTheme];
517 539
518 if (descriptionMaxWidth > 0) { 540 if (descriptionMaxWidth > 0) {
519 if ([cellData isAnswer]) { 541 if ([cellData isAnswer]) {
520 origin = NSMakePoint( 542 origin = NSMakePoint(left, [OmniboxPopupCell getContentTextHeight:false] -
521 kMaterialTextStartOffset + [tableView contentLeftPadding], 543 GetVerticalMargin());
522 [OmniboxPopupCell getContentTextHeight] - GetVerticalMargin());
523 CGFloat imageSize = [tableView answerLineHeight]; 544 CGFloat imageSize = [tableView answerLineHeight];
524 NSRect imageRect = 545 NSRect imageRect =
525 NSMakeRect(NSMinX(cellFrame) + origin.x, NSMinY(cellFrame) + origin.y, 546 NSMakeRect(NSMinX(cellFrame) + origin.x, NSMinY(cellFrame) + origin.y,
526 imageSize, imageSize); 547 imageSize, imageSize);
527 [[cellData answerImage] drawInRect:FlipIfRTL(imageRect, cellFrame) 548 [[cellData answerImage] drawInRect:FlipIfRTL(imageRect, cellFrame)
528 fromRect:NSZeroRect 549 fromRect:NSZeroRect
529 operation:NSCompositeSourceOver 550 operation:NSCompositeSourceOver
530 fraction:1.0 551 fraction:1.0
531 respectFlipped:YES 552 respectFlipped:YES
532 hints:nil]; 553 hints:nil];
533 if ([cellData answerImage]) { 554 if ([cellData answerImage]) {
534 origin.x += imageSize + kMaterialImageXOffset; 555 origin.x += imageSize + kMaterialImageXOffset;
535 556
536 // Have to nudge the baseline down 1pt in Material Design for the text 557 // Have to nudge the baseline down 1pt in Material Design for the text
537 // that follows, so that it's the same as the bottom of the image. 558 // that follows, so that it's the same as the bottom of the image.
538 origin.y += 1; 559 origin.y += 1;
539 } 560 }
540 } else { 561 } else {
541 origin.x += [self drawMatchPart:[tableView separator] 562 if (isVerticalLayout) {
542 withFrame:cellFrame 563 origin.x = left;
groby-ooo-7-16 2017/05/31 00:14:51 If you assign the whole point: origin = NSMakePoi
tommycli 2017/05/31 18:20:39 Hey. I actually need to add to the y coordinate, r
groby-ooo-7-16 2017/05/31 19:24:16 And so you do. TIL my brain skips characters at co
543 origin:origin 564 origin.y += halfLineHeight * 2;
544 withMaxWidth:separatorWidth 565 } else {
545 forDarkTheme:isDarkTheme]; 566 origin.x += [self drawMatchPart:[tableView separator]
567 withFrame:cellFrame
568 origin:origin
569 withMaxWidth:separatorWidth
570 forDarkTheme:isDarkTheme];
571 }
546 } 572 }
547 origin.x += [self drawMatchPart:[cellData description] 573 [self drawMatchPart:[cellData description]
548 withFrame:cellFrame 574 withFrame:cellFrame
549 origin:origin 575 origin:origin
550 withMaxWidth:descriptionMaxWidth 576 withMaxWidth:descriptionMaxWidth
551 forDarkTheme:isDarkTheme]; 577 forDarkTheme:isDarkTheme];
552 } 578 }
553 } 579 }
554 580
555 - (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame 581 - (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame
556 tableView:(OmniboxPopupMatrix*)tableView 582 tableView:(OmniboxPopupMatrix*)tableView
557 withContentsMaxWidth:(int*)contentsMaxWidth 583 withContentsMaxWidth:(int*)contentsMaxWidth
558 forDarkTheme:(BOOL)isDarkTheme { 584 forDarkTheme:(BOOL)isDarkTheme {
559 OmniboxPopupCellData* cellData = 585 OmniboxPopupCellData* cellData =
560 base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]); 586 base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]);
561 CGFloat offset = 0.0f; 587 CGFloat offset = 0.0f;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 + (NSAttributedString*)createSeparatorStringForDarkTheme:(BOOL)isDarkTheme { 714 + (NSAttributedString*)createSeparatorStringForDarkTheme:(BOOL)isDarkTheme {
689 base::string16 raw_separator = 715 base::string16 raw_separator =
690 l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR); 716 l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR);
691 return CreateAttributedString(raw_separator, DimTextColor(isDarkTheme)); 717 return CreateAttributedString(raw_separator, DimTextColor(isDarkTheme));
692 } 718 }
693 719
694 + (CGFloat)getContentAreaWidth:(NSRect)cellFrame { 720 + (CGFloat)getContentAreaWidth:(NSRect)cellFrame {
695 return NSWidth(cellFrame) - kMaterialTextStartOffset; 721 return NSWidth(cellFrame) - kMaterialTextStartOffset;
696 } 722 }
697 723
698 + (CGFloat)getContentTextHeight { 724 + (CGFloat)getContentTextHeight:(BOOL)isTwoLine {
699 constexpr CGFloat kDefaultTextHeight = 19; 725 CGFloat height = kDefaultTextHeight + 2 * GetVerticalMargin();
700 return kDefaultTextHeight + 2 * GetVerticalMargin(); 726 if (isTwoLine)
727 height += kDefaultTextHeight + kDefaultVerticalMargin;
728 return height;
701 } 729 }
702 730
703 @end 731 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698