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

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

Issue 17774002: OmniboxPopupViewMac refactoring Part 3 (truncation) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 NSSize size = [title size];
23 NSColor* HoveredBackgroundColor() { 30
24 return [NSColor controlHighlightColor]; 31 // Empirically, Cocoa will draw an extra 2 pixels past NSWidth(titleRect)
32 // before it clips the text.
33 const CGFloat kOverflowBeforeClip = 2;
Scott Hess - ex-Googler 2013/06/28 01:02:48 2.0
sail 2013/06/28 18:41:16 Done.
34 BOOL clipping =
35 std::floor(size.width) > NSWidth(titleRect) + kOverflowBeforeClip;
36
37 // Gradient is about twice our line height long.
38 CGFloat gradientWidth = MIN(size.height * 2, NSWidth(titleRect) / 4);
Scott Hess - ex-Googler 2013/06/28 01:02:48 std::min().
sail 2013/06/28 18:41:16 Done.
39
40 NSRect solidPart, gradientPart;
41 NSDivideRect(titleRect, &gradientPart, &solidPart, gradientWidth, NSMaxXEdge);
42
43 NSPoint textOffset;
44 textOffset.x = NSMinX(titleRect);
45 textOffset.y =
46 NSMinY(titleRect) + roundf((NSHeight(titleRect) - size.height) / 2.0) - 1;
Scott Hess - ex-Googler 2013/06/28 01:02:48 Sigh. No std::round until c++11.
47
48 // Draw non-gradient part without transparency layer, as light text on a dark
49 // background looks bad with a gradient layer.
50 {
51 gfx::ScopedNSGraphicsContextSaveGState scopedGState;
52 if (clipping)
53 [NSBezierPath clipRect:solidPart];
54 [title drawAtPoint:textOffset];
55 }
56
57 if (!clipping)
Scott Hess - ex-Googler 2013/06/28 01:02:48 Couldn't this result in incorrect drawing if the t
sail 2013/06/28 18:41:16 Done. This part is not relevant anymore now that I
58 return;
59
60 // Draw the gradient part with a transparency layer. This makes the text look
61 // suboptimal, but since it fades out, that's ok.
Scott Hess - ex-Googler 2013/06/28 01:02:48 This seems complicated. Something like this using
sail 2013/06/28 18:41:16 Done. Yep, I just draw the full string and then dr
62 gfx::ScopedNSGraphicsContextSaveGState scopedGState;
63 [NSBezierPath clipRect:gradientPart];
64 CGContextRef context = static_cast<CGContextRef>(
65 [[NSGraphicsContext currentContext] graphicsPort]);
66 CGContextBeginTransparencyLayerWithRect(context,
67 NSRectToCGRect(gradientPart), 0);
68 [title drawAtPoint:textOffset];
69
70 NSColor *color = [NSColor textColor];
71 NSColor *alphaColor = [color colorWithAlphaComponent:0.0];
72 NSGradient *mask = [[NSGradient alloc] initWithStartingColor:color
73 endingColor:alphaColor];
74
75 // Draw the gradient mask
76 CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
77 [mask drawFromPoint:NSMakePoint(NSMaxX(titleRect) - gradientWidth,
78 NSMinY(titleRect))
79 toPoint:NSMakePoint(NSMaxX(titleRect),
80 NSMinY(titleRect))
81 options:NSGradientDrawsBeforeStartingLocation];
82 [mask release];
Scott Hess - ex-Googler 2013/06/28 01:02:48 Why not scoped_ptr<>? Does the mask require speci
sail 2013/06/28 18:41:16 Done.
83 CGContextEndTransparencyLayer(context);
25 } 84 }
26 85
27 } // namespace 86 } // namespace
28 87
29 @implementation OmniboxPopupCell 88 @implementation OmniboxPopupCell
30 89
31 - (id)init { 90 - (id)init {
32 self = [super init]; 91 if ((self = [super init])) {
33 if (self) {
34 [self setImagePosition:NSImageLeft]; 92 [self setImagePosition:NSImageLeft];
35 [self setBordered:NO]; 93 [self setBordered:NO];
36 [self setButtonType:NSRadioButton]; 94 [self setButtonType:NSRadioButton];
37 95
38 // Without this highlighting messes up white areas of images. 96 // Without this highlighting messes up white areas of images.
39 [self setHighlightsBy:NSNoCellMask]; 97 [self setHighlightsBy:NSNoCellMask];
40 } 98 }
41 return self; 99 return self;
42 } 100 }
43 101
44 // The default NSButtonCell drawing leaves the image flush left and 102 - (NSAttributedString*)contentText {
45 // the title next to the image. This spaces things out to line up 103 return contentText_;
46 // with the star button and autocomplete field. 104 }
105
106 - (void)setContentText:(NSAttributedString*)contentText {
107 contentText_.reset([contentText retain]);
108 }
109
110 - (NSAttributedString*)descriptionText {
111 return descriptionText_;
112 }
113
114 - (void)setDescriptionText:(NSAttributedString*)descriptionText {
115 descriptionText_.reset([descriptionText retain]);
116 }
117
47 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { 118 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
48 if ([self state] == NSOnState || [self isHighlighted]) { 119 if ([self state] == NSOnState || [self isHighlighted]) {
49 if ([self state] == NSOnState) 120 if ([self state] == NSOnState)
50 [SelectedBackgroundColor() set]; 121 [[NSColor selectedControlColor] set];
51 else 122 else
52 [HoveredBackgroundColor() set]; 123 [[NSColor controlHighlightColor] set];
53 NSBezierPath* path = 124 NSBezierPath* path =
54 [NSBezierPath bezierPathWithRoundedRect:cellFrame 125 [NSBezierPath bezierPathWithRoundedRect:cellFrame
55 xRadius:kCellRoundingRadius 126 xRadius:kCellRoundingRadius
56 yRadius:kCellRoundingRadius]; 127 yRadius:kCellRoundingRadius];
57 [path fill]; 128 [path fill];
58 } 129 }
59 130
60 // Put the image centered vertically but in a fixed column. 131 // Put the image centered vertically but in a fixed column.
61 NSImage* image = [self image]; 132 NSImage* image = [self image];
62 if (image) { 133 if (image) {
63 NSRect imageRect = cellFrame; 134 NSRect imageRect = cellFrame;
64 imageRect.size = [image size]; 135 imageRect.size = [image size];
65 imageRect.origin.y += 136 imageRect.origin.y +=
66 std::floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2.0); 137 std::floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2.0);
67 imageRect.origin.x += kImageXOffset; 138 imageRect.origin.x += kImageXOffset;
68 [image drawInRect:imageRect 139 [image drawInRect:imageRect
69 fromRect:NSZeroRect // Entire image 140 fromRect:NSZeroRect // Entire image
70 operation:NSCompositeSourceOver 141 operation:NSCompositeSourceOver
71 fraction:1.0 142 fraction:1.0
72 respectFlipped:YES 143 respectFlipped:YES
73 hints:nil]; 144 hints:nil];
74 } 145 }
75 146
76 // Adjust the title position to be lined up under the field's text. 147 // Adjust the title position to be lined up under the field's text.
77 NSAttributedString* title = [self attributedTitle]; 148 if ([contentText_ length]) {
78 if (title && [title length]) { 149 CGFloat availableWidth = NSWidth(cellFrame) - kTextXOffset;
79 NSRect titleRect = cellFrame; 150 CGFloat contentWidth = [contentText_ size].width;
80 titleRect.size.width -= kTextXOffset; 151 CGFloat descriptionWidth = 0;
81 titleRect.origin.x += kTextXOffset; 152 if ([descriptionText_ length])
82 [self drawTitle:title withFrame:titleRect inView:controlView]; 153 descriptionWidth = [descriptionText_ size].width;
154
155 if (contentWidth + descriptionWidth > availableWidth) {
156 if (contentWidth > kMaxContentsFraction * availableWidth) {
157 if (descriptionWidth > (1.0 - kMaxContentsFraction) * availableWidth)
158 descriptionWidth = (1.0 - kMaxContentsFraction) * availableWidth;
Scott Hess - ex-Googler 2013/06/28 01:02:48 std::min?
sail 2013/06/28 18:41:16 Done.
159 contentWidth =
160 std::min(contentWidth, availableWidth - descriptionWidth);
161 } else {
162 descriptionWidth = availableWidth - contentWidth;
163 }
164 }
Scott Hess - ex-Googler 2013/06/28 01:02:48 I think this entire if() can be replaced with some
sail 2013/06/28 18:41:16 Done.
165
166 NSRect contentRect = cellFrame;
167 contentRect.origin.x = kTextXOffset;
168 contentRect.size.width = contentWidth;
169 DrawFadeTruncatingTitle(contentText_, contentRect);
170
171 NSRect descriptionRect = cellFrame;
Scott Hess - ex-Googler 2013/06/28 01:02:48 if ([descriptionText_ length]){...} around this?
sail 2013/06/28 18:41:16 Done.
172 descriptionRect.origin.x = NSMaxX(contentRect);
173 descriptionRect.size.width = descriptionWidth;
174 DrawFadeTruncatingTitle(descriptionText_, descriptionRect);
83 } 175 }
84 } 176 }
85 177
86 @end 178 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698