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

Unified Diff: chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.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: autorelease on column data cell 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
index 936ce5751103fb1b3bf15a41aa3f1b6258b4b182..c153e4e3ec22d347b0dfb892c8ad87c91fe097e9 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
@@ -8,6 +8,7 @@
#include <cmath>
#include "base/i18n/rtl.h"
+#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -24,6 +25,13 @@
namespace {
+// How much to adjust the cell sizing up from the default determined
+// by the font.
+const CGFloat kCellHeightAdjust = 6.0;
+
+// How large the icon should be when displayed.
+const CGFloat kImageSize = 19.0;
+
// How far to offset image column from the left.
const CGFloat kImageXOffset = 5.0;
@@ -279,85 +287,105 @@ NSAttributedString* CreateClassifiedAttributedString(
} // namespace
-@implementation OmniboxPopupCell
-
-- (instancetype)init {
- self = [super init];
- if (self) {
- [self setImagePosition:NSImageLeft];
- [self setBordered:NO];
- [self setButtonType:NSRadioButton];
-
- // Without this highlighting messes up white areas of images.
- [self setHighlightsBy:NSNoCellMask];
+@interface OmniboxPopupCell ()
+- (CGFloat)drawMatchPart:(NSAttributedString*)attributedString
+ withFrame:(NSRect)cellFrame
+ atOffset:(CGFloat)offset
+ withMaxWidth:(int)maxWidth;
+- (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame
+ tableView:(OmniboxPopupMatrix*)tableView
+ withContentsMaxWidth:(int*)contentsMaxWidth;
+- (void)drawMatchWithFrame:(NSRect)cellFrame inView:(NSView*)controlView;
+@end
- const base::string16& raw_separator =
- l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR);
- separator_.reset(
- [CreateAttributedString(raw_separator, DimTextColor()) retain]);
+@implementation OmniboxPopupCellData
+
+@synthesize contents = contents_;
+@synthesize description = description_;
+@synthesize prefix = prefix_;
+@synthesize image = image_;
+@synthesize answerImage = answerImage_;
+@synthesize contentsOffset = contentsOffset_;
+@synthesize isContentsRTL = isContentsRTL_;
+@synthesize matchType = matchType_;
+
+- (instancetype)initWithMatch:(const AutocompleteMatch&)match
+ contentsOffset:(CGFloat)contentsOffset
+ image:(NSImage*)image
+ answerImage:(NSImage*)answerImage {
+ if ((self = [super init])) {
+ image_ = [image retain];
+ answerImage_ = [answerImage retain];
+ contentsOffset_ = contentsOffset;
+
+ isContentsRTL_ =
+ (base::i18n::RIGHT_TO_LEFT ==
+ base::i18n::GetFirstStrongCharacterDirection(match.contents));
+ matchType_ = match.type;
+
+ // Prefix may not have any characters with strong directionality, and may
+ // take the UI directionality. But prefix needs to appear in continuation
+ // of the contents so we force the directionality.
+ NSTextAlignment textAlignment =
+ isContentsRTL_ ? NSRightTextAlignment : NSLeftTextAlignment;
+ prefix_ =
+ [CreateAttributedString(base::UTF8ToUTF16(match.GetAdditionalInfo(
+ kACMatchPropertyContentsPrefix)),
+ ContentTextColor(), textAlignment) retain];
+
+ contents_ = [CreateClassifiedAttributedString(
+ match.contents, ContentTextColor(), match.contents_class) retain];
+
+ if (match.answer) {
+ base::scoped_nsobject<NSMutableAttributedString> answerString(
+ [[NSMutableAttributedString alloc] init]);
+ DCHECK(!match.answer->second_line().text_fields().empty());
+ for (const SuggestionAnswer::TextField& textField :
+ match.answer->second_line().text_fields()) {
+ [answerString
+ appendAttributedString:CreateAnswerString(textField.text(),
+ textField.type())];
+ }
+ const base::string16 space(base::ASCIIToUTF16(" "));
+ const SuggestionAnswer::TextField* textField =
+ match.answer->second_line().additional_text();
+ if (textField) {
+ [answerString
+ appendAttributedString:CreateAnswerString(space + textField->text(),
+ textField->type())];
+ }
+ textField = match.answer->second_line().status_text();
+ if (textField) {
+ [answerString
+ appendAttributedString:CreateAnswerString(space + textField->text(),
+ textField->type())];
+ }
+ description_ = answerString.release();
+ } else if (!match.description.empty()) {
+ description_ = [CreateClassifiedAttributedString(
+ match.description, DimTextColor(), match.description_class) retain];
+ }
}
return self;
}
-- (void)setAnswerImage:(NSImage*)image {
- answerImage_.reset([image retain]);
+- (instancetype)copyWithZone:(NSZone*)zone {
+ return [self retain];
}
-- (void)setMatch:(const AutocompleteMatch&)match {
- match_ = match;
- NSAttributedString *contents = CreateClassifiedAttributedString(
- match_.contents, ContentTextColor(), match_.contents_class);
- [self setAttributedTitle:contents];
- [self setAnswerImage:nil];
- if (match_.answer) {
- base::scoped_nsobject<NSMutableAttributedString> answerString(
- [[NSMutableAttributedString alloc] init]);
- DCHECK(!match_.answer->second_line().text_fields().empty());
- for (const SuggestionAnswer::TextField& textField :
- match_.answer->second_line().text_fields()) {
- NSAttributedString* attributedString =
- CreateAnswerString(textField.text(), textField.type());
- [answerString appendAttributedString:attributedString];
- }
- const base::char16 space(' ');
- const SuggestionAnswer::TextField* textField =
- match_.answer->second_line().additional_text();
- if (textField) {
- [answerString
- appendAttributedString:CreateAnswerString(space + textField->text(),
- textField->type())];
- }
- textField = match_.answer->second_line().status_text();
- if (textField) {
- [answerString
- appendAttributedString:CreateAnswerString(space + textField->text(),
- textField->type())];
- }
- description_.reset(answerString.release());
- } else if (match_.description.empty()) {
- description_.reset();
- } else {
- description_.reset([CreateClassifiedAttributedString(
- match_.description, DimTextColor(), match_.description_class) retain]);
- }
+- (CGFloat)getMatchContentsWidth {
+ return [contents_ size].width;
}
-- (NSAttributedString*)description {
- return description_;
+- (CGFloat)rowHeight {
+ return kImageSize + kCellHeightAdjust;
}
-- (void)setMaxMatchContentsWidth:(CGFloat)maxMatchContentsWidth {
- maxMatchContentsWidth_ = maxMatchContentsWidth;
-}
+@end
-- (void)setContentsOffset:(CGFloat)contentsOffset {
- contentsOffset_ = contentsOffset;
-}
+@implementation OmniboxPopupCell
-// The default NSButtonCell drawing leaves the image flush left and
-// the title next to the image. This spaces things out to line up
-// with the star button and autocomplete field.
-- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
+- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
if ([self state] == NSOnState || [self isHighlighted]) {
if ([self state] == NSOnState)
[SelectedBackgroundColor() set];
@@ -370,154 +398,130 @@ NSAttributedString* CreateClassifiedAttributedString(
[path fill];
}
- // Put the image centered vertically but in a fixed column.
- NSImage* image = [self image];
- if (image) {
- NSRect imageRect = cellFrame;
- imageRect.size = [image size];
- imageRect.origin.y +=
- std::floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2.0);
- imageRect.origin.x += kImageXOffset;
- [image drawInRect:FlipIfRTL(imageRect, cellFrame)
- fromRect:NSZeroRect // Entire image
- operation:NSCompositeSourceOver
- fraction:1.0
- respectFlipped:YES
- hints:nil];
- }
-
[self drawMatchWithFrame:cellFrame inView:controlView];
}
- (void)drawMatchWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
- NSAttributedString* contents = [self attributedTitle];
-
+ OmniboxPopupCellData* cellData =
+ base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]);
+ OmniboxPopupMatrix* tableView =
+ base::mac::ObjCCastStrict<OmniboxPopupMatrix>(controlView);
CGFloat remainingWidth = GetContentAreaWidth(cellFrame);
- CGFloat contentsWidth = [self getMatchContentsWidth];
- CGFloat separatorWidth = [separator_ size].width;
- CGFloat descriptionWidth = description_.get() ? [description_ size].width : 0;
+ CGFloat contentsWidth = [cellData getMatchContentsWidth];
+ CGFloat separatorWidth = [[tableView separator] size].width;
+ CGFloat descriptionWidth =
+ [cellData description] ? [[cellData description] size].width : 0;
int contentsMaxWidth, descriptionMaxWidth;
OmniboxPopupModel::ComputeMatchMaxWidths(
- ceilf(contentsWidth),
- ceilf(separatorWidth),
- ceilf(descriptionWidth),
+ ceilf(contentsWidth), ceilf(separatorWidth), ceilf(descriptionWidth),
ceilf(remainingWidth),
- !AutocompleteMatch::IsSearchType(match_.type),
- &contentsMaxWidth,
+ !AutocompleteMatch::IsSearchType([cellData matchType]), &contentsMaxWidth,
&descriptionMaxWidth);
+ // Put the image centered vertically but in a fixed column.
+ NSRect imageRect = cellFrame;
+ imageRect.size = [[cellData image] size];
+ imageRect.origin.y +=
+ std::floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2.0);
+ imageRect.origin.x += kImageXOffset;
+ [[cellData image] drawInRect:FlipIfRTL(imageRect, cellFrame)
+ fromRect:NSZeroRect
+ operation:NSCompositeSourceOver
+ fraction:1.0
+ respectFlipped:YES
+ hints:nil];
+
CGFloat offset = kTextStartOffset;
- if (match_.type == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) {
+ if ([cellData matchType] == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) {
// Infinite suggestions are rendered with a prefix (usually ellipsis), which
// appear vertically stacked.
offset += [self drawMatchPrefixWithFrame:cellFrame
- inView:controlView
+ tableView:tableView
withContentsMaxWidth:&contentsMaxWidth];
}
- offset += [self drawMatchPart:contents
+ offset += [self drawMatchPart:[cellData contents]
withFrame:cellFrame
atOffset:offset
- withMaxWidth:contentsMaxWidth
- inView:controlView];
+ withMaxWidth:contentsMaxWidth];
if (descriptionMaxWidth != 0) {
- offset += [self drawMatchPart:separator_
+ offset += [self drawMatchPart:[tableView separator]
withFrame:cellFrame
atOffset:offset
- withMaxWidth:separatorWidth
- inView:controlView];
- if (answerImage_) {
+ withMaxWidth:separatorWidth];
NSRect imageRect = NSMakeRect(offset, NSMinY(cellFrame),
NSHeight(cellFrame), NSHeight(cellFrame));
- [answerImage_ drawInRect:FlipIfRTL(imageRect, cellFrame)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0
- respectFlipped:YES
- hints:nil];
- offset += NSWidth(imageRect);
- }
- offset += [self drawMatchPart:description_
- withFrame:cellFrame
- atOffset:offset
- withMaxWidth:descriptionMaxWidth
- inView:controlView];
+ [[cellData answerImage] drawInRect:FlipIfRTL(imageRect, cellFrame)
+ fromRect:NSZeroRect
+ operation:NSCompositeSourceOver
+ fraction:1.0
+ respectFlipped:YES
+ hints:nil];
+ if ([cellData answerImage])
+ offset += NSWidth(imageRect);
+ offset += [self drawMatchPart:[cellData description]
+ withFrame:cellFrame
+ atOffset:offset
+ withMaxWidth:descriptionMaxWidth];
}
}
- (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame
- inView:(NSView*)controlView
+ tableView:(OmniboxPopupMatrix*)tableView
withContentsMaxWidth:(int*)contentsMaxWidth {
+ OmniboxPopupCellData* cellData =
+ base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]);
CGFloat offset = 0.0f;
CGFloat remainingWidth = GetContentAreaWidth(cellFrame);
- bool isContentsRTL = (base::i18n::RIGHT_TO_LEFT ==
- base::i18n::GetFirstStrongCharacterDirection(match_.contents));
- // Prefix may not have any characters with strong directionality, and may take
- // the UI directionality. But prefix needs to appear in continuation of the
- // contents so we force the directionality.
- NSTextAlignment textAlignment = isContentsRTL ?
- NSRightTextAlignment : NSLeftTextAlignment;
- prefix_.reset([CreateAttributedString(base::UTF8ToUTF16(
- match_.GetAdditionalInfo(kACMatchPropertyContentsPrefix)),
- ContentTextColor(), textAlignment) retain]);
- CGFloat prefixWidth = [prefix_ size].width;
+ CGFloat prefixWidth = [[cellData prefix] size].width;
CGFloat prefixOffset = 0.0f;
- if (base::i18n::IsRTL() != isContentsRTL) {
+ if (base::i18n::IsRTL() != [cellData isContentsRTL]) {
// The contents is rendered between the contents offset extending towards
// the start edge, while prefix is rendered in opposite direction. Ideally
// the prefix should be rendered at |contentsOffset_|. If that is not
// sufficient to render the widest suggestion, we increase it to
- // |maxMatchContentsWidth_|. If |remainingWidth| is not sufficient to
+ // |maxMatchContentsWidth|. If |remainingWidth| is not sufficient to
// accommodate that, we reduce the offset so that the prefix gets rendered.
prefixOffset = std::min(
- remainingWidth - prefixWidth, std::max(contentsOffset_,
- maxMatchContentsWidth_));
+ remainingWidth - prefixWidth,
+ std::max([cellData contentsOffset], [tableView maxMatchContentsWidth]));
offset = std::max<CGFloat>(0.0, prefixOffset - *contentsMaxWidth);
} else { // The direction of contents is same as UI direction.
// Ideally the offset should be |contentsOffset_|. If the max total width
- // (|prefixWidth| + |maxMatchContentsWidth_|) from offset will exceed the
+ // (|prefixWidth| + |maxMatchContentsWidth|) from offset will exceed the
// |remainingWidth|, then we shift the offset to the left , so that all
// postfix suggestions are visible.
// We have to render the prefix, so offset has to be at least |prefixWidth|.
- offset = std::max(prefixWidth,
- std::min(remainingWidth - maxMatchContentsWidth_, contentsOffset_));
+ offset =
+ std::max(prefixWidth,
+ std::min(remainingWidth - [tableView maxMatchContentsWidth],
+ [cellData contentsOffset]));
prefixOffset = offset - prefixWidth;
}
*contentsMaxWidth = std::min((int)ceilf(remainingWidth - prefixWidth),
*contentsMaxWidth);
- [self drawMatchPart:prefix_
+ [self drawMatchPart:[cellData prefix]
withFrame:cellFrame
atOffset:prefixOffset + kTextStartOffset
- withMaxWidth:prefixWidth
- inView:controlView];
+ withMaxWidth:prefixWidth];
return offset;
}
- (CGFloat)drawMatchPart:(NSAttributedString*)attributedString
withFrame:(NSRect)cellFrame
atOffset:(CGFloat)offset
- withMaxWidth:(int)maxWidth
- inView:(NSView*)controlView {
+ withMaxWidth:(int)maxWidth {
if (offset > NSWidth(cellFrame))
return 0.0f;
NSRect renderRect = ShiftRect(cellFrame, offset);
renderRect.size.width =
std::min(NSWidth(renderRect), static_cast<CGFloat>(maxWidth));
- if (renderRect.size.width != 0) {
- [self drawTitle:attributedString
- withFrame:FlipIfRTL(renderRect, cellFrame)
- inView:controlView];
- }
+ if (NSWidth(renderRect) > 0.0)
+ [attributedString drawInRect:FlipIfRTL(renderRect, cellFrame)];
return NSWidth(renderRect);
}
-- (CGFloat)getMatchContentsWidth {
- NSAttributedString* contents = [self attributedTitle];
- return contents ? [contents size].width : 0;
-}
-
-
+ (CGFloat)computeContentsOffset:(const AutocompleteMatch&)match {
const base::string16& inputText = base::UTF8ToUTF16(
match.GetAdditionalInfo(kACMatchPropertyInputText));
@@ -584,4 +588,10 @@ NSAttributedString* CreateClassifiedAttributedString(
return base::i18n::IsRTL() ? (inputWidth - glyphOffset) : glyphOffset;
}
++ (NSAttributedString*)createSeparatorString {
+ base::string16 raw_separator =
+ l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR);
+ return CreateAttributedString(raw_separator, DimTextColor());
+}
+
@end
« no previous file with comments | « chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h ('k') | chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698