Chromium Code Reviews| 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 db647f8f6cf83e360090cc8347955909ec406ba6..16e3b4e20c4ba63905df5ea0bf156a52f697c71d 100644 |
| --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm |
| +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm |
| @@ -4,8 +4,11 @@ |
| #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h" |
| +#include <algorithm> |
| #include <cmath> |
| +#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| + |
| namespace { |
| // How far to offset image column from the left. |
| @@ -14,14 +17,46 @@ const CGFloat kImageXOffset = 5.0; |
| // How far to offset the text column from the left. |
| const CGFloat kTextXOffset = 28.0; |
| +// Maximum fraction of the popup width that can be used to display match |
| +// contents. |
| +const CGFloat kMinDescriptionFraction = 0.7; |
| + |
| // Rounding radius of selection and hover background on popup items. |
| const CGFloat kCellRoundingRadius = 2.0; |
| -NSColor* SelectedBackgroundColor() { |
| - return [NSColor selectedControlColor]; |
| -} |
| -NSColor* HoveredBackgroundColor() { |
| - return [NSColor controlHighlightColor]; |
| +void DrawFadeTruncatingTitle(NSAttributedString* title, |
| + NSRect titleRect, |
| + NSColor* backgroundColor) { |
| + gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
| + NSRectClip(titleRect); |
| + |
| + // Draw the entire text. |
| + NSSize textSize = [title size]; |
| + NSPoint textOrigin = titleRect.origin; |
| + textOrigin.y += roundf((NSHeight(titleRect) - textSize.height) / 2.0) - 1.0; |
| + [title drawAtPoint:textOrigin]; |
| + |
| + // Empirically, Cocoa will draw an extra 2 pixels past NSWidth(titleRect) |
| + // before it clips the text. |
| + const CGFloat kOverflowBeforeClip = 2.0; |
| + BOOL clipping = |
| + std::floor(textSize.width) > NSWidth(titleRect) + kOverflowBeforeClip; |
| + if (!clipping) |
|
Scott Hess - ex-Googler
2013/07/08 20:53:11
You don't use |clipping| again, but the initializa
sail
2013/08/12 17:39:30
Done.
Removed the floor.
|
| + return; |
| + |
| + // Gradient is about twice our line height long. |
| + CGFloat gradientWidth = std::min(textSize.height * 2, NSWidth(titleRect) / 4); |
| + |
| + // Draw the gradient part. |
| + NSColor *alphaColor = [backgroundColor colorWithAlphaComponent:0.0]; |
| + base::scoped_nsobject<NSGradient> mask( |
| + [[NSGradient alloc] initWithStartingColor:alphaColor |
| + endingColor:backgroundColor]); |
| + [mask drawFromPoint:NSMakePoint(NSMaxX(titleRect) - gradientWidth, |
| + NSMinY(titleRect)) |
| + toPoint:NSMakePoint(NSMaxX(titleRect), |
| + NSMinY(titleRect)) |
| + options:NSGradientDrawsBeforeStartingLocation]; |
| } |
| } // namespace |
| @@ -29,8 +64,7 @@ NSColor* HoveredBackgroundColor() { |
| @implementation OmniboxPopupCell |
| - (id)init { |
| - self = [super init]; |
| - if (self) { |
| + if ((self = [super init])) { |
| [self setImagePosition:NSImageLeft]; |
| [self setBordered:NO]; |
| [self setButtonType:NSRadioButton]; |
| @@ -41,15 +75,28 @@ NSColor* HoveredBackgroundColor() { |
| return self; |
| } |
| -// 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)setContentText:(NSAttributedString*)contentText { |
| + contentText_.reset([contentText retain]); |
| +} |
| + |
| +- (void)setDescriptionText:(NSAttributedString*)descriptionText { |
| + base::scoped_nsobject<NSMutableAttributedString> dashDescriptionText( |
| + [[NSMutableAttributedString alloc] |
| + initWithAttributedString:descriptionText]); |
| + NSString* raw_en_dash = @" \u2013 "; |
|
Scott Hess - ex-Googler
2013/07/08 20:53:11
Should this be rawEnDash now that this isn't embed
sail
2013/08/12 17:39:30
Done.
|
| + [dashDescriptionText replaceCharactersInRange:NSMakeRange(0, 0) |
| + withString:raw_en_dash]; |
| + descriptionText_.reset(dashDescriptionText.release()); |
| +} |
| + |
| - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { |
| + NSColor* backgroundColor = [NSColor controlBackgroundColor]; |
| if ([self state] == NSOnState || [self isHighlighted]) { |
| if ([self state] == NSOnState) |
| - [SelectedBackgroundColor() set]; |
| + backgroundColor = [NSColor selectedControlColor]; |
| else |
| - [HoveredBackgroundColor() set]; |
| + backgroundColor = [NSColor controlHighlightColor]; |
| + [backgroundColor set]; |
| NSBezierPath* path = |
| [NSBezierPath bezierPathWithRoundedRect:cellFrame |
| xRadius:kCellRoundingRadius |
| @@ -74,12 +121,27 @@ NSColor* HoveredBackgroundColor() { |
| } |
| // Adjust the title position to be lined up under the field's text. |
| - NSAttributedString* title = [self attributedTitle]; |
| - if (title && [title length]) { |
| - NSRect titleRect = cellFrame; |
| - titleRect.size.width -= kTextXOffset; |
| - titleRect.origin.x += kTextXOffset; |
| - [self drawTitle:title withFrame:titleRect inView:controlView]; |
| + if ([contentText_ length]) { |
| + NSRect availRect = cellFrame; |
| + availRect.size.width = NSWidth(cellFrame) - kTextXOffset; |
| + availRect.origin.x += kTextXOffset; |
| + CGFloat availWidth = NSWidth(availRect); |
| + CGFloat contentWidth = [contentText_ size].width; |
| + CGFloat descWidth = |
| + [descriptionText_ length] ? [descriptionText_ size].width : 0; |
| + |
| + CGFloat tempDescWidth = |
| + std::min(descWidth, kMinDescriptionFraction * availWidth); |
| + contentWidth = std::min(contentWidth, availWidth - tempDescWidth); |
| + |
| + NSRect contentRect; |
| + NSRect descRect; |
| + NSDivideRect( |
| + availRect, &contentRect, &descRect, contentWidth, NSMinXEdge); |
| + |
| + DrawFadeTruncatingTitle(contentText_, contentRect, backgroundColor); |
| + if ([descriptionText_ length]) |
| + DrawFadeTruncatingTitle(descriptionText_, descRect, backgroundColor); |
| } |
| } |