Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <algorithm> | |
| 7 #include <cmath> | 8 #include <cmath> |
| 8 | 9 |
| 10 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | |
| 11 | |
| 9 namespace { | 12 namespace { |
| 10 | 13 |
| 11 // How far to offset image column from the left. | 14 // How far to offset image column from the left. |
| 12 const CGFloat kImageXOffset = 5.0; | 15 const CGFloat kImageXOffset = 5.0; |
| 13 | 16 |
| 14 // How far to offset the text column from the left. | 17 // How far to offset the text column from the left. |
| 15 const CGFloat kTextXOffset = 28.0; | 18 const CGFloat kTextXOffset = 28.0; |
| 16 | 19 |
| 20 // Maximum fraction of the popup width that can be used to display match | |
| 21 // contents. | |
| 22 const CGFloat kMaxContentsFraction = 0.7; | |
| 23 | |
| 17 // Rounding radius of selection and hover background on popup items. | 24 // Rounding radius of selection and hover background on popup items. |
| 18 const CGFloat kCellRoundingRadius = 2.0; | 25 const CGFloat kCellRoundingRadius = 2.0; |
| 19 | 26 |
| 20 NSColor* SelectedBackgroundColor() { | 27 void DrawFadeTruncatingTitle(NSAttributedString* title, |
| 21 return [NSColor selectedControlColor]; | 28 NSRect titleRect, |
| 22 } | 29 NSColor* backgroundColor) { |
| 23 NSColor* HoveredBackgroundColor() { | 30 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
| 24 return [NSColor controlHighlightColor]; | 31 NSRectClip(titleRect); |
| 32 | |
| 33 // Draw the entire text. | |
| 34 NSSize textSize = [title size]; | |
| 35 NSPoint textOrigin = titleRect.origin; | |
| 36 textOrigin.y += roundf((NSHeight(titleRect) - textSize.height) / 2.0) - 1.0; | |
| 37 [title drawAtPoint:textOrigin]; | |
| 38 | |
| 39 // Empirically, Cocoa will draw an extra 2 pixels past NSWidth(titleRect) | |
| 40 // before it clips the text. | |
| 41 const CGFloat kOverflowBeforeClip = 2.0; | |
| 42 BOOL clipping = | |
| 43 std::floor(textSize.width) > NSWidth(titleRect) + kOverflowBeforeClip; | |
| 44 if (!clipping) | |
| 45 return; | |
| 46 | |
| 47 // Gradient is about twice our line height long. | |
| 48 CGFloat gradientWidth = std::min(textSize.height * 2, NSWidth(titleRect) / 4); | |
| 49 | |
| 50 // Draw the gradient part. | |
| 51 NSColor *alphaColor = [backgroundColor colorWithAlphaComponent:0.0]; | |
| 52 base::scoped_nsobject<NSGradient> mask( | |
| 53 [[NSGradient alloc] initWithStartingColor:alphaColor | |
| 54 endingColor:backgroundColor]); | |
| 55 [mask drawFromPoint:NSMakePoint(NSMaxX(titleRect) - gradientWidth, | |
| 56 NSMinY(titleRect)) | |
| 57 toPoint:NSMakePoint(NSMaxX(titleRect), | |
| 58 NSMinY(titleRect)) | |
| 59 options:NSGradientDrawsBeforeStartingLocation]; | |
| 25 } | 60 } |
| 26 | 61 |
| 27 } // namespace | 62 } // namespace |
| 28 | 63 |
| 29 @implementation OmniboxPopupCell | 64 @implementation OmniboxPopupCell |
| 30 | 65 |
| 31 - (id)init { | 66 - (id)init { |
| 32 self = [super init]; | 67 if ((self = [super init])) { |
| 33 if (self) { | |
| 34 [self setImagePosition:NSImageLeft]; | 68 [self setImagePosition:NSImageLeft]; |
| 35 [self setBordered:NO]; | 69 [self setBordered:NO]; |
| 36 [self setButtonType:NSRadioButton]; | 70 [self setButtonType:NSRadioButton]; |
| 37 | 71 |
| 38 // Without this highlighting messes up white areas of images. | 72 // Without this highlighting messes up white areas of images. |
| 39 [self setHighlightsBy:NSNoCellMask]; | 73 [self setHighlightsBy:NSNoCellMask]; |
| 40 } | 74 } |
| 41 return self; | 75 return self; |
| 42 } | 76 } |
| 43 | 77 |
| 44 // The default NSButtonCell drawing leaves the image flush left and | 78 - (NSAttributedString*)contentText { |
|
Scott Hess - ex-Googler
2013/06/28 20:11:34
Nobody even ever calls the getters. I'd be fine w
sail
2013/06/30 18:49:11
Done.
| |
| 45 // the title next to the image. This spaces things out to line up | 79 return contentText_; |
| 46 // with the star button and autocomplete field. | 80 } |
| 81 | |
| 82 - (void)setContentText:(NSAttributedString*)contentText { | |
| 83 contentText_.reset([contentText retain]); | |
| 84 } | |
| 85 | |
| 86 - (NSAttributedString*)descriptionText { | |
| 87 return descriptionText_; | |
| 88 } | |
| 89 | |
| 90 - (void)setDescriptionText:(NSAttributedString*)descriptionText { | |
| 91 descriptionText_.reset([descriptionText retain]); | |
| 92 } | |
| 93 | |
| 47 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { | 94 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { |
| 95 NSColor* backgroundColor = [NSColor controlBackgroundColor]; | |
| 48 if ([self state] == NSOnState || [self isHighlighted]) { | 96 if ([self state] == NSOnState || [self isHighlighted]) { |
| 49 if ([self state] == NSOnState) | 97 if ([self state] == NSOnState) |
| 50 [SelectedBackgroundColor() set]; | 98 backgroundColor = [NSColor selectedControlColor]; |
| 51 else | 99 else |
| 52 [HoveredBackgroundColor() set]; | 100 backgroundColor = [NSColor controlHighlightColor]; |
| 101 [backgroundColor set]; | |
| 53 NSBezierPath* path = | 102 NSBezierPath* path = |
| 54 [NSBezierPath bezierPathWithRoundedRect:cellFrame | 103 [NSBezierPath bezierPathWithRoundedRect:cellFrame |
| 55 xRadius:kCellRoundingRadius | 104 xRadius:kCellRoundingRadius |
| 56 yRadius:kCellRoundingRadius]; | 105 yRadius:kCellRoundingRadius]; |
| 57 [path fill]; | 106 [path fill]; |
| 58 } | 107 } |
| 59 | 108 |
| 60 // Put the image centered vertically but in a fixed column. | 109 // Put the image centered vertically but in a fixed column. |
| 61 NSImage* image = [self image]; | 110 NSImage* image = [self image]; |
| 62 if (image) { | 111 if (image) { |
| 63 NSRect imageRect = cellFrame; | 112 NSRect imageRect = cellFrame; |
| 64 imageRect.size = [image size]; | 113 imageRect.size = [image size]; |
| 65 imageRect.origin.y += | 114 imageRect.origin.y += |
| 66 std::floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2.0); | 115 std::floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2.0); |
| 67 imageRect.origin.x += kImageXOffset; | 116 imageRect.origin.x += kImageXOffset; |
| 68 [image drawInRect:imageRect | 117 [image drawInRect:imageRect |
| 69 fromRect:NSZeroRect // Entire image | 118 fromRect:NSZeroRect // Entire image |
| 70 operation:NSCompositeSourceOver | 119 operation:NSCompositeSourceOver |
| 71 fraction:1.0 | 120 fraction:1.0 |
| 72 respectFlipped:YES | 121 respectFlipped:YES |
| 73 hints:nil]; | 122 hints:nil]; |
| 74 } | 123 } |
| 75 | 124 |
| 76 // Adjust the title position to be lined up under the field's text. | 125 // Adjust the title position to be lined up under the field's text. |
| 77 NSAttributedString* title = [self attributedTitle]; | 126 if ([contentText_ length]) { |
| 78 if (title && [title length]) { | 127 CGFloat availableWidth = NSWidth(cellFrame) - kTextXOffset; |
| 79 NSRect titleRect = cellFrame; | 128 CGFloat contentWidth = [contentText_ size].width; |
| 80 titleRect.size.width -= kTextXOffset; | 129 CGFloat descriptionWidth = 0; |
|
Scott Hess - ex-Googler
2013/06/28 20:11:34
I think you should feel free to use abbreviations
sail
2013/06/30 18:49:11
Done.
| |
| 81 titleRect.origin.x += kTextXOffset; | 130 |
| 82 [self drawTitle:title withFrame:titleRect inView:controlView]; | 131 base::scoped_nsobject<NSMutableAttributedString> dashDescriptionText; |
| 132 if ([descriptionText_ length]) { | |
| 133 dashDescriptionText.reset([[NSMutableAttributedString alloc] | |
| 134 initWithAttributedString:descriptionText_]); | |
| 135 [dashDescriptionText replaceCharactersInRange:NSMakeRange(0, 0) | |
| 136 withString:@" \u2013 "]; | |
| 137 descriptionWidth = [dashDescriptionText size].width; | |
| 138 } | |
|
Scott Hess - ex-Googler
2013/06/28 20:11:34
That's not really what I meant, sorry. I meant dr
sail
2013/06/30 18:49:11
Done.
| |
| 139 | |
| 140 CGFloat tempDescWidth = std::min( | |
| 141 descriptionWidth, (1.0f - kMaxContentsFraction) * availableWidth); | |
|
Scott Hess - ex-Googler
2013/06/28 20:11:34
Now that there is only one ref to this, and it's 1
sail
2013/06/30 18:49:11
Done.
I changed the setter to prepend raw_en_dash
| |
| 142 contentWidth = std::min(contentWidth, availableWidth - tempDescWidth); | |
| 143 descriptionWidth = | |
| 144 std::min(descriptionWidth, availableWidth - contentWidth); | |
| 145 | |
| 146 // Draw content text. | |
| 147 NSRect contentRect = cellFrame; | |
| 148 contentRect.origin.x = kTextXOffset; | |
| 149 contentRect.size.width = contentWidth; | |
|
Scott Hess - ex-Googler
2013/06/28 20:11:34
contentRect and descRect could be generated by NSD
sail
2013/06/30 18:49:11
Done.
| |
| 150 DrawFadeTruncatingTitle(contentText_, contentRect, backgroundColor); | |
| 151 | |
| 152 // Draw dash and description. | |
| 153 if ([dashDescriptionText length]) { | |
| 154 NSRect descriptionRect = cellFrame; | |
| 155 descriptionRect.origin.x = NSMaxX(contentRect); | |
| 156 descriptionRect.size.width = descriptionWidth; | |
| 157 DrawFadeTruncatingTitle( | |
| 158 dashDescriptionText, descriptionRect, backgroundColor); | |
| 159 } | |
| 83 } | 160 } |
| 84 } | 161 } |
| 85 | 162 |
| 86 @end | 163 @end |
| OLD | NEW |