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

Side by Side Diff: chrome/browser/cocoa/location_bar/bubble_decoration.mm

Issue 3046029: [Mac] First pass at final sizing of toolbar items. (Closed) Base URL: git://codf21.jail/chromium.git
Patch Set: Don't disable unit tests for realz, sorry. Created 10 years, 4 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #include <cmath>
6
5 #import "chrome/browser/cocoa/location_bar/bubble_decoration.h" 7 #import "chrome/browser/cocoa/location_bar/bubble_decoration.h"
6 8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #import "chrome/browser/cocoa/image_utils.h" 10 #import "chrome/browser/cocoa/image_utils.h"
9 11
10 namespace { 12 namespace {
11 13
12 // Padding between the icon/label and bubble edges. 14 // Padding between the icon/label and bubble edges.
13 const CGFloat kBubblePadding = 7.0; 15 const CGFloat kBubblePadding = 3.0;
14 16
15 // How far to inset the keywork token from sides. 17 // The image needs to be in the same position as for the location
16 const NSInteger kKeywordYInset = 4; 18 // icon, which implies that the bubble's padding in the Omnibox needs
19 // to differ from the location icon's. Indeed, that's how the views
20 // implementation handles the problem. This draws the bubble edge a
21 // little bit further left, which is easier but no less hacky.
22 const CGFloat kLeftSideOverdraw = 1.0;
23
24 // Omnibox corner radius is |4.0|, this needs to look tight WRT that.
25 const CGFloat kBubbleCornerRadius = 2.0;
26
27 // How far to inset the bubble from the top and bottom of the drawing
28 // frame.
29 // TODO(shess): Would be nicer to have the drawing code factor out the
30 // space outside the border, and perhaps the border. Then this could
31 // reflect the single pixel space w/in that.
32 const CGFloat kBubbleYInset = 4.0;
33
34 // How far to inset the text from the edge of the bubble.
35 const CGFloat kTextYInset = 1.0;
17 36
18 } // namespace 37 } // namespace
19 38
20 BubbleDecoration::BubbleDecoration(NSFont* font) { 39 BubbleDecoration::BubbleDecoration(NSFont* font) {
21 DCHECK(font); 40 DCHECK(font);
22 if (font) { 41 if (font) {
23 NSDictionary* attributes = 42 NSDictionary* attributes =
24 [NSDictionary dictionaryWithObject:font 43 [NSDictionary dictionaryWithObject:font
25 forKey:NSFontAttributeName]; 44 forKey:NSFontAttributeName];
26 attributes_.reset([attributes retain]); 45 attributes_.reset([attributes retain]);
27 } 46 }
28 } 47 }
29 48
30 BubbleDecoration::~BubbleDecoration() { 49 BubbleDecoration::~BubbleDecoration() {
31 } 50 }
32 51
33 CGFloat BubbleDecoration::GetWidthForImageAndLabel(NSImage* image, 52 CGFloat BubbleDecoration::GetWidthForImageAndLabel(NSImage* image,
34 NSString* label) { 53 NSString* label) {
35 if (!image && !label) 54 if (!image && !label)
36 return kOmittedWidth; 55 return kOmittedWidth;
37 56
38 const CGFloat image_width = image ? [image size].width : 0.0; 57 const CGFloat image_width = image ? [image size].width : 0.0;
39 if (!label) 58 if (!label)
40 return kBubblePadding + image_width; 59 return kBubblePadding + image_width;
41 60
42 const CGFloat label_width = [label sizeWithAttributes:attributes_].width; 61 // The bubble needs to take up an integral number of pixels.
62 // Generally -sizeWithAttributes: seems to overestimate rather than
63 // underestimate, so floor() seems to work better.
64 const CGFloat label_width =
65 std::floor([label sizeWithAttributes:attributes_].width);
43 return kBubblePadding + image_width + label_width; 66 return kBubblePadding + image_width + label_width;
44 } 67 }
45 68
46 NSRect BubbleDecoration::GetImageRectInFrame(NSRect frame) { 69 NSRect BubbleDecoration::GetImageRectInFrame(NSRect frame) {
47 NSRect imageRect = NSInsetRect(frame, 0.0, kKeywordYInset); 70 NSRect imageRect = NSInsetRect(frame, 0.0, kBubbleYInset);
48 if (image_) 71 if (image_) {
49 imageRect.size = [image_ size]; 72 // Center the image vertically.
73 const NSSize imageSize = [image_ size];
74 imageRect.origin.y +=
75 std::floor((NSHeight(frame) - imageSize.height) / 2.0);
76 imageRect.size = imageSize;
77 }
50 return imageRect; 78 return imageRect;
51 } 79 }
52 80
53 CGFloat BubbleDecoration::GetWidthForSpace(CGFloat width) { 81 CGFloat BubbleDecoration::GetWidthForSpace(CGFloat width) {
54 const CGFloat all_width = GetWidthForImageAndLabel(image_, label_); 82 const CGFloat all_width = GetWidthForImageAndLabel(image_, label_);
55 if (all_width <= width) 83 if (all_width <= width)
56 return all_width; 84 return all_width;
57 85
58 const CGFloat image_width = GetWidthForImageAndLabel(image_, nil); 86 const CGFloat image_width = GetWidthForImageAndLabel(image_, nil);
59 if (image_width <= width) 87 if (image_width <= width)
60 return image_width; 88 return image_width;
61 89
62 return kOmittedWidth; 90 return kOmittedWidth;
63 } 91 }
64 92
65 void BubbleDecoration::DrawInFrame(NSRect frame, NSView* control_view) { 93 void BubbleDecoration::DrawInFrame(NSRect frame, NSView* control_view) {
66 const NSRect decorationFrame = NSInsetRect(frame, 0.0, kKeywordYInset); 94 const NSRect decorationFrame = NSInsetRect(frame, 0.0, kBubbleYInset);
67 95
68 const NSRect bubbleFrame = NSInsetRect(decorationFrame, 0.5, 0.5); 96 // The inset is to put the border down the middle of the pixel.
97 NSRect bubbleFrame = NSInsetRect(decorationFrame, 0.5, 0.5);
98 bubbleFrame.origin.x -= kLeftSideOverdraw;
99 bubbleFrame.size.width += kLeftSideOverdraw;
69 NSBezierPath* path = 100 NSBezierPath* path =
70 [NSBezierPath bezierPathWithRoundedRect:bubbleFrame 101 [NSBezierPath bezierPathWithRoundedRect:bubbleFrame
71 xRadius:4.0 102 xRadius:kBubbleCornerRadius
72 yRadius:4.0]; 103 yRadius:kBubbleCornerRadius];
73 104
74 [background_color_ setFill]; 105 [background_color_ setFill];
75 [path fill]; 106 [path fill];
76 107
77 [border_color_ setStroke]; 108 [border_color_ setStroke];
78 [path setLineWidth:1.0]; 109 [path setLineWidth:1.0];
79 [path stroke]; 110 [path stroke];
80 111
81 NSRect imageRect = decorationFrame; 112 NSRect imageRect = decorationFrame;
82 if (image_) { 113 if (image_) {
83 imageRect.size = [image_ size]; 114 // Center the image vertically.
115 const NSSize imageSize = [image_ size];
116 imageRect.origin.y +=
117 std::floor((NSHeight(decorationFrame) - imageSize.height) / 2.0);
118 imageRect.size = imageSize;
84 [image_ drawInRect:imageRect 119 [image_ drawInRect:imageRect
85 fromRect:NSZeroRect // Entire image 120 fromRect:NSZeroRect // Entire image
86 operation:NSCompositeSourceOver 121 operation:NSCompositeSourceOver
87 fraction:1.0 122 fraction:1.0
88 neverFlipped:YES]; 123 neverFlipped:YES];
89 } else { 124 } else {
90 imageRect.size = NSZeroSize; 125 imageRect.size = NSZeroSize;
91 } 126 }
92 127
93 if (label_) { 128 if (label_) {
94 NSRect textRect = decorationFrame; 129 NSRect textRect = decorationFrame;
95 textRect.origin.x = NSMaxX(imageRect); 130 textRect.origin.x = NSMaxX(imageRect);
96 textRect.size.width = NSMaxX(decorationFrame) - NSMinX(textRect); 131 textRect.size.width = NSMaxX(decorationFrame) - NSMinX(textRect);
97 [text_color_ set]; 132 textRect.origin.y += kTextYInset;
98 [label_ drawInRect:textRect withAttributes:attributes_]; 133 [label_ drawInRect:textRect withAttributes:attributes_];
99 } 134 }
100 } 135 }
101 136
102 NSImage* BubbleDecoration::GetImage() { 137 NSImage* BubbleDecoration::GetImage() {
103 return image_; 138 return image_;
104 } 139 }
105 140
106 void BubbleDecoration::SetImage(NSImage* image) { 141 void BubbleDecoration::SetImage(NSImage* image) {
107 image_.reset([image retain]); 142 image_.reset([image retain]);
108 } 143 }
109 144
110 void BubbleDecoration::SetLabel(NSString* label) { 145 void BubbleDecoration::SetLabel(NSString* label) {
111 // If the initializer was called with |nil|, then the code cannot 146 // If the initializer was called with |nil|, then the code cannot
112 // process a label. 147 // process a label.
113 DCHECK(attributes_); 148 DCHECK(attributes_);
114 if (attributes_) 149 if (attributes_)
115 label_.reset([label copy]); 150 label_.reset([label copy]);
116 } 151 }
117 152
118 void BubbleDecoration::SetColors(NSColor* border_color, 153 void BubbleDecoration::SetColors(NSColor* border_color,
119 NSColor* background_color, 154 NSColor* background_color,
120 NSColor* text_color) { 155 NSColor* text_color) {
121 border_color_.reset([border_color retain]); 156 border_color_.reset([border_color retain]);
122 background_color_.reset([background_color retain]); 157 background_color_.reset([background_color retain]);
123 text_color_.reset([text_color retain]); 158
159 scoped_nsobject<NSMutableDictionary> attributes([attributes_ mutableCopy]);
160 [attributes setObject:text_color forKey:NSForegroundColorAttributeName];
161 attributes_.reset([attributes copy]);
124 } 162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698