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

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: Removed withView arg from highlightRowAt Created 5 years, 7 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 0a295320c06236866fae25cdaf9c62ee1dd5c5d6..cab3074bac0612543c20aaf7ff68c706e421a79e 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
@@ -23,6 +23,10 @@
namespace {
+// How much to adjust the cell sizing up from the default determined
+// by the font.
+const CGFloat kCellHeightAdjust = 6.0;
+
// How far to offset image column from the left.
const CGFloat kImageXOffset = 5.0;
@@ -155,54 +159,76 @@ NSAttributedString* CreateClassifiedAttributedString(
} // namespace
-@implementation OmniboxPopupCell
+@interface OmniboxPopupCell ()
+- (CGFloat)drawMatchPart:(NSAttributedString*)attributedString
+ withFrame:(NSRect)cellFrame
+ atOffset:(CGFloat)offset
+ withMaxWidth:(int)maxWidth
+ inView:(NSView*)controlView;
+@end
-- (id)init {
- self = [super init];
- if (self) {
- [self setImagePosition:NSImageLeft];
- [self setBordered:NO];
- [self setButtonType:NSRadioButton];
+@implementation OmniboxPopupCellData
- // Without this highlighting messes up white areas of images.
- [self setHighlightsBy:NSNoCellMask];
+- (id)initWithMatch:(const AutocompleteMatch&)match image:(NSImage*)image {
+ if ((self = [super init])) {
+ image_.reset([image retain]);
const base::string16& raw_separator =
l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR);
separator_.reset(
[CreateAttributedString(raw_separator, DimTextColor()) retain]);
+
+ 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.
Scott Hess - ex-Googler 2015/05/21 20:40:26 Reformat comment.
dschuyler 2015/05/26 18:40:20 Done.
+ NSTextAlignment textAlignment =
+ isContentsRTL_ ? NSRightTextAlignment : NSLeftTextAlignment;
+ prefix_.reset(
+ [CreateAttributedString(base::UTF8ToUTF16(match.GetAdditionalInfo(
+ kACMatchPropertyContentsPrefix)),
+ ContentTextColor(), textAlignment) retain]);
+
+ contents_.reset([CreateClassifiedAttributedString(
+ match.contents, ContentTextColor(), match.contents_class) retain]);
+
+ if (match.answer) {
+ base::string16 answerString;
+ DCHECK(!match.answer->second_line().text_fields().empty());
+ for (const SuggestionAnswer::TextField& textField :
+ match.answer->second_line().text_fields())
+ answerString.append(textField.text());
+ const base::string16 space(base::ASCIIToUTF16(" "));
+ const SuggestionAnswer::TextField* textField =
+ match.answer->second_line().additional_text();
+ if (textField)
+ answerString.append(space).append(textField->text());
+ textField = match.answer->second_line().status_text();
+ if (textField)
+ answerString.append(space).append(textField->text());
+ description_.reset([CreateClassifiedAttributedString(
+ answerString, DimTextColor(), match.description_class) retain]);
+ } else if (match.description.empty()) {
+ description_.reset();
+ } else {
+ description_.reset([CreateClassifiedAttributedString(
+ match.description, DimTextColor(), match.description_class) retain]);
+ }
}
return self;
}
-- (void)setMatch:(const AutocompleteMatch&)match {
- match_ = match;
- NSAttributedString *contents = CreateClassifiedAttributedString(
- match_.contents, ContentTextColor(), match_.contents_class);
- [self setAttributedTitle:contents];
-
- if (match_.answer) {
- base::string16 answerString;
- DCHECK(!match_.answer->second_line().text_fields().empty());
- for (const SuggestionAnswer::TextField& textField :
- match_.answer->second_line().text_fields())
- answerString += textField.text();
- const base::char16 space(' ');
- const SuggestionAnswer::TextField* textField =
- match_.answer->second_line().additional_text();
- if (textField)
- answerString += space + textField->text();
- textField = match_.answer->second_line().status_text();
- if (textField)
- answerString += space + textField->text();
- description_.reset([CreateClassifiedAttributedString(
- answerString, DimTextColor(), match_.description_class) retain]);
- } else if (match_.description.empty()) {
- description_.reset();
- } else {
- description_.reset([CreateClassifiedAttributedString(
- match_.description, DimTextColor(), match_.description_class) retain]);
- }
+- (void)setContents:(NSAttributedString*)contents {
+ contents_.reset([contents retain]);
+}
+
+- (void)setImage:(NSImage*)image {
+ image_.reset([image retain]);
}
- (void)setMaxMatchContentsWidth:(CGFloat)maxMatchContentsWidth {
@@ -213,79 +239,64 @@ NSAttributedString* CreateClassifiedAttributedString(
contentsOffset_ = contentsOffset;
}
-// 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 {
- if ([self state] == NSOnState || [self isHighlighted]) {
- if ([self state] == NSOnState)
- [SelectedBackgroundColor() set];
- else
- [HoveredBackgroundColor() set];
- NSBezierPath* path =
- [NSBezierPath bezierPathWithRoundedRect:cellFrame
- xRadius:kCellRoundingRadius
- yRadius:kCellRoundingRadius];
- [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];
+- (CGFloat)getMatchContentsWidth {
+ return [contents_ size].width;
}
-- (void)drawMatchWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
- NSAttributedString* contents = [self attributedTitle];
+- (CGFloat)rowHeight {
+ return [image_ size].height + kCellHeightAdjust;
Scott Hess - ex-Googler 2015/05/21 20:40:26 I realize that the current version doesn't have th
dschuyler 2015/05/26 18:40:20 Done.
+}
+- (void)drawMatchWithFrame:(NSRect)cellFrame
+ inCell:(OmniboxPopupCell*)cell
+ inView:(NSView*)controlView {
CGFloat remainingWidth = GetContentAreaWidth(cellFrame);
CGFloat contentsWidth = [self getMatchContentsWidth];
CGFloat separatorWidth = [separator_ size].width;
- CGFloat descriptionWidth = description_.get() ? [description_ size].width : 0;
+ CGFloat descriptionWidth = [description_ size].width;
int contentsMaxWidth, descriptionMaxWidth;
OmniboxPopupModel::ComputeMatchMaxWidths(
- ceilf(contentsWidth),
- ceilf(separatorWidth),
- ceilf(descriptionWidth),
- ceilf(remainingWidth),
- !AutocompleteMatch::IsSearchType(match_.type),
- &contentsMaxWidth,
- &descriptionMaxWidth);
+ ceilf(contentsWidth), ceilf(separatorWidth), ceilf(descriptionWidth),
+ ceilf(remainingWidth), !AutocompleteMatch::IsSearchType(matchType_),
+ &contentsMaxWidth, &descriptionMaxWidth);
+
+ // Put the image centered vertically but in a fixed column.
+ 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
+ operation:NSCompositeSourceOver
+ fraction:1.0
+ respectFlipped:YES
+ hints:nil];
+ }
CGFloat offset = kTextStartOffset;
- if (match_.type == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) {
+ if (matchType_ == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) {
// Infinite suggestions are rendered with a prefix (usually ellipsis), which
// appear vertically stacked.
offset += [self drawMatchPrefixWithFrame:cellFrame
+ inCell:cell
inView:controlView
withContentsMaxWidth:&contentsMaxWidth];
}
- offset += [self drawMatchPart:contents
+ offset += [cell drawMatchPart:contents_
withFrame:cellFrame
atOffset:offset
withMaxWidth:contentsMaxWidth
inView:controlView];
if (descriptionMaxWidth != 0) {
- offset += [self drawMatchPart:separator_
+ offset += [cell drawMatchPart:separator_
withFrame:cellFrame
atOffset:offset
withMaxWidth:separatorWidth
inView:controlView];
- offset += [self drawMatchPart:description_
+ offset += [cell drawMatchPart:description_
withFrame:cellFrame
atOffset:offset
withMaxWidth:descriptionMaxWidth
@@ -294,25 +305,15 @@ NSAttributedString* CreateClassifiedAttributedString(
}
- (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame
+ inCell:(OmniboxPopupCell*)cell
inView:(NSView*)controlView
withContentsMaxWidth:(int*)contentsMaxWidth {
CGFloat offset = 0.0f;
CGFloat remainingWidth = GetContentAreaWidth(cellFrame);
- bool isRTL = base::i18n::IsRTL();
- 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 prefixOffset = 0.0f;
- if (isRTL != isContentsRTL) {
+ if (base::i18n::IsRTL() != 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
@@ -329,13 +330,14 @@ NSAttributedString* CreateClassifiedAttributedString(
// |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,
+ offset = std::max(
+ prefixWidth,
std::min(remainingWidth - maxMatchContentsWidth_, contentsOffset_));
prefixOffset = offset - prefixWidth;
}
*contentsMaxWidth = std::min((int)ceilf(remainingWidth - prefixWidth),
*contentsMaxWidth);
- [self drawMatchPart:prefix_
+ [cell drawMatchPart:prefix_
withFrame:cellFrame
atOffset:prefixOffset + kTextStartOffset
withMaxWidth:prefixWidth
@@ -343,7 +345,39 @@ NSAttributedString* CreateClassifiedAttributedString(
return offset;
}
-- (CGFloat)drawMatchPart:(NSAttributedString*)as
+@end
+
+@implementation OmniboxPopupCell
+
+- (id)copyWithZone:(NSZone*)zone {
+ OmniboxPopupCell* copy = [super copyWithZone:zone];
+ // The representedObject is set to nil in the copy.
Scott Hess - ex-Googler 2015/05/21 20:40:27 What did they do, put _all_ of the special edge ca
groby-ooo-7-16 2015/05/22 05:03:07 Hey, at least this one is documented. (Under repre
dschuyler 2015/05/26 18:40:19 Acknowledged.
dschuyler 2015/05/26 18:40:19 I'm looking into the objectValue vs representedObj
+ [copy setRepresentedObject:[self representedObject]];
+ return copy;
+}
+
+// The default NSButtonCell drawing leaves the image flush left and
groby-ooo-7-16 2015/05/21 03:01:48 Comment doesn't apply any more - it's just an NSCe
dschuyler 2015/05/26 18:40:19 Done.
+// 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 {
+ if ([self state] == NSOnState || [self isHighlighted]) {
+ if ([self state] == NSOnState)
+ [SelectedBackgroundColor() set];
+ else
+ [HoveredBackgroundColor() set];
+ NSBezierPath* path =
+ [NSBezierPath bezierPathWithRoundedRect:cellFrame
+ xRadius:kCellRoundingRadius
+ yRadius:kCellRoundingRadius];
+ [path fill];
+ }
+
+ base::scoped_nsobject<OmniboxPopupCellData> cellData(
+ [self representedObject]);
groby-ooo-7-16 2015/05/21 03:01:48 No need to scope - representedObject (and objectVa
Scott Hess - ex-Googler 2015/05/21 20:40:26 Scoping is wrong, because -representedObject is no
dschuyler 2015/05/26 18:40:20 Done.
dschuyler 2015/05/26 18:40:20 Acknowledged.
+ [cellData drawMatchWithFrame:cellFrame inCell:self inView:controlView];
+}
+
+- (CGFloat)drawMatchPart:(NSAttributedString*)attributedString
withFrame:(NSRect)cellFrame
atOffset:(CGFloat)offset
withMaxWidth:(int)maxWidth
@@ -353,20 +387,15 @@ NSAttributedString* CreateClassifiedAttributedString(
NSRect renderRect = ShiftRect(cellFrame, offset);
renderRect.size.width =
std::min(NSWidth(renderRect), static_cast<CGFloat>(maxWidth));
- if (renderRect.size.width != 0) {
- [self drawTitle:as
- withFrame:FlipIfRTL(renderRect, cellFrame)
- inView:controlView];
- }
+ NSRect textRect =
+ [attributedString boundingRectWithSize:renderRect.size options:nil];
+ renderRect.origin.y +=
+ std::floor((NSHeight(cellFrame) - NSHeight(textRect)) / 2.0);
+ if (NSWidth(renderRect) != 0)
Scott Hess - ex-Googler 2015/05/21 20:40:26 I'd say > 0.0. Just because I'm that paranoid.
groby-ooo-7-16 2015/05/22 05:03:07 Let's be properly paranoid and say !NSIsEmptyRect(
dschuyler 2015/05/26 18:40:20 Done.
+ [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));
@@ -385,9 +414,10 @@ NSAttributedString* CreateClassifiedAttributedString(
base::i18n::GetFirstStrongCharacterDirection(match.contents));
// Color does not matter.
- NSAttributedString* as = CreateAttributedString(inputText, DimTextColor());
- base::scoped_nsobject<NSTextStorage> textStorage([[NSTextStorage alloc]
- initWithAttributedString:as]);
+ NSAttributedString* attributedString =
+ CreateAttributedString(inputText, DimTextColor());
+ base::scoped_nsobject<NSTextStorage> textStorage(
+ [[NSTextStorage alloc] initWithAttributedString:attributedString]);
base::scoped_nsobject<NSLayoutManager> layoutManager(
[[NSLayoutManager alloc] init]);
base::scoped_nsobject<NSTextContainer> textContainer(
@@ -403,7 +433,7 @@ NSAttributedString* CreateClassifiedAttributedString(
// left edge of the string, irrespective of the directionality of UI or text.
CGFloat glyphOffset = [layoutManager locationForGlyphAtIndex:glyphIndex].x;
- CGFloat inputWidth = [as size].width;
+ CGFloat inputWidth = [attributedString size].width;
// The offset obtained above may need to be corrected because the left-most
// glyph may not have 0 offset. So we find the offset of left-most glyph, and
@@ -417,7 +447,7 @@ NSAttributedString* CreateClassifiedAttributedString(
// we are looking for.
CGFloat glyphWidth = inputWidth;
- for (NSUInteger i = 0; i < [as length]; i++) {
+ for (NSUInteger i = 0; i < [attributedString length]; i++) {
if (i == charIndex) continue;
glyphIndex = [layoutManager glyphIndexForCharacterAtIndex:i];
CGFloat offset = [layoutManager locationForGlyphAtIndex:glyphIndex].x;

Powered by Google App Engine
This is Rietveld 408576698