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

Side by Side Diff: chrome/browser/views/bubble_border.cc

Issue 195099: Convert InfoBubble to using BubbleBorder. This also replaces the border grap... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 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
« no previous file with comments | « chrome/browser/views/bubble_border.h ('k') | chrome/browser/views/info_bubble.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "chrome/browser/views/bubble_border.h" 5 #include "chrome/browser/views/bubble_border.h"
6 6
7 #include "app/gfx/canvas.h" 7 #include "app/gfx/canvas.h"
8 #include "app/gfx/path.h" 8 #include "app/gfx/path.h"
9 #include "app/resource_bundle.h" 9 #include "app/resource_bundle.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "grit/theme_resources.h" 11 #include "grit/theme_resources.h"
12 #include "third_party/skia/include/core/SkBitmap.h" 12 #include "third_party/skia/include/core/SkBitmap.h"
13 13
14 // static 14 // static
15 SkBitmap* BubbleBorder::left_ = NULL; 15 SkBitmap* BubbleBorder::left_ = NULL;
16 SkBitmap* BubbleBorder::top_left_ = NULL; 16 SkBitmap* BubbleBorder::top_left_ = NULL;
17 SkBitmap* BubbleBorder::top_ = NULL; 17 SkBitmap* BubbleBorder::top_ = NULL;
18 SkBitmap* BubbleBorder::top_right_ = NULL; 18 SkBitmap* BubbleBorder::top_right_ = NULL;
19 SkBitmap* BubbleBorder::right_ = NULL; 19 SkBitmap* BubbleBorder::right_ = NULL;
20 SkBitmap* BubbleBorder::bottom_right_ = NULL; 20 SkBitmap* BubbleBorder::bottom_right_ = NULL;
21 SkBitmap* BubbleBorder::bottom_ = NULL; 21 SkBitmap* BubbleBorder::bottom_ = NULL;
22 SkBitmap* BubbleBorder::bottom_left_ = NULL; 22 SkBitmap* BubbleBorder::bottom_left_ = NULL;
23 SkBitmap* BubbleBorder::top_arrow_ = NULL;
24 SkBitmap* BubbleBorder::bottom_arrow_ = NULL;
25
26 //static
27 int BubbleBorder::arrow_x_offset_;
28
29 // The height inside the arrow image, in pixels.
30 static const int kArrowInteriorHeight = 7;
23 31
24 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, 32 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to,
25 const gfx::Size& contents_size) const { 33 const gfx::Size& contents_size) const {
26 // The spacing (in pixels) between |position_relative_to| and the bubble 34 // The spacing (in pixels) between |position_relative_to| and the bubble
27 // content. 35 // content.
28 const int kBubbleSpacing = 2; 36 const int kBubbleSpacing = 2;
29 37
30 // Desired size is size of contents enlarged by the size of the border images. 38 // Desired size is size of contents enlarged by the size of the border images.
31 gfx::Size border_size(contents_size); 39 gfx::Size border_size(contents_size);
32 gfx::Insets insets; 40 gfx::Insets insets;
33 GetInsets(&insets); 41 GetInsets(&insets);
34 border_size.Enlarge(insets.left() + insets.right(), 42 border_size.Enlarge(insets.left() + insets.right(),
35 insets.top() + insets.bottom()); 43 insets.top() + insets.bottom());
36 44
37 int x = position_relative_to.x() + (position_relative_to.width() / 2) - 45 // Screen position depends on the arrow location.
38 (contents_size.width() / 2) - insets.left(); 46 int x = position_relative_to.x() + (position_relative_to.width() / 2);
39 int y = position_relative_to.bottom() - (top_->height() - kBubbleSpacing); 47 if (arrow_is_left())
48 x -= arrow_x_offset_;
49 else if (arrow_location_ == NONE)
50 x -= ((contents_size.width() / 2) + insets.left());
51 else
52 x += (arrow_x_offset_ - border_size.width() + 1);
53 int y = position_relative_to.y();
54 if (arrow_is_top()) {
55 y += (position_relative_to.height() -
56 (top_arrow_->height() - kBubbleSpacing));
57 } else if (arrow_location_ == NONE) {
58 y += (position_relative_to.height() - (top_->height() - kBubbleSpacing));
59 } else {
60 y += ((bottom_arrow_->height() - kBubbleSpacing) - border_size.height());
61 }
40 62
41 return gfx::Rect(x, y, border_size.width(), border_size.height()); 63 return gfx::Rect(x, y, border_size.width(), border_size.height());
42 } 64 }
43 65
44 void BubbleBorder::GetInsets(gfx::Insets* insets) const { 66 void BubbleBorder::GetInsets(gfx::Insets* insets) const {
45 insets->Set(top_->height(), left_->width(), bottom_->height(), 67 int top = top_->height();
46 right_->width()); 68 int bottom = bottom_->height();
69 if (arrow_is_top())
70 top = std::max(top, top_arrow_->height());
71 else if (arrow_location_ != NONE)
72 bottom = std::max(bottom, bottom_arrow_->height());
73 insets->Set(top, left_->width(), bottom, right_->width());
47 } 74 }
48 75
49 // static 76 // static
50 void BubbleBorder::InitClass() { 77 void BubbleBorder::InitClass() {
51 static bool initialized = false; 78 static bool initialized = false;
52 if (!initialized) { 79 if (!initialized) {
53 // Load images. 80 // Load images.
54 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 81 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
55 left_ = rb.GetBitmapNamed(IDR_BUBBLE_L); 82 left_ = rb.GetBitmapNamed(IDR_BUBBLE_L);
56 top_left_ = rb.GetBitmapNamed(IDR_BUBBLE_TL); 83 top_left_ = rb.GetBitmapNamed(IDR_BUBBLE_TL);
57 top_ = rb.GetBitmapNamed(IDR_BUBBLE_T); 84 top_ = rb.GetBitmapNamed(IDR_BUBBLE_T);
58 top_right_ = rb.GetBitmapNamed(IDR_BUBBLE_TR); 85 top_right_ = rb.GetBitmapNamed(IDR_BUBBLE_TR);
59 right_ = rb.GetBitmapNamed(IDR_BUBBLE_R); 86 right_ = rb.GetBitmapNamed(IDR_BUBBLE_R);
60 bottom_right_ = rb.GetBitmapNamed(IDR_BUBBLE_BR); 87 bottom_right_ = rb.GetBitmapNamed(IDR_BUBBLE_BR);
61 bottom_ = rb.GetBitmapNamed(IDR_BUBBLE_B); 88 bottom_ = rb.GetBitmapNamed(IDR_BUBBLE_B);
62 bottom_left_ = rb.GetBitmapNamed(IDR_BUBBLE_BL); 89 bottom_left_ = rb.GetBitmapNamed(IDR_BUBBLE_BL);
90 top_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_T_ARROW);
91 bottom_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_B_ARROW);
92
93 // Calculate horizontal inset for arrow by ensuring that the widest arrow
94 // and corner images will have enough room to avoid overlap.
95 arrow_x_offset_ =
96 (std::max(top_arrow_->width(), bottom_arrow_->width()) / 2) +
97 std::max(std::max(top_left_->width(), top_right_->width()),
98 std::max(bottom_left_->width(), bottom_right_->width()));
63 99
64 initialized = true; 100 initialized = true;
65 } 101 }
66 } 102 }
67 103
68 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { 104 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const {
69 // Convenience shorthand variables 105 // Convenience shorthand variables
70 int width = view.width(); 106 int width = view.width();
71 int tl_width = top_left_->width(); 107 int tl_width = top_left_->width();
72 int tl_height = top_left_->height(); 108 int tl_height = top_left_->height();
73 int t_height = top_->height(); 109 int t_height = top_->height();
74 int tr_width = top_right_->width(); 110 int tr_width = top_right_->width();
75 int tr_height = top_right_->height(); 111 int tr_height = top_right_->height();
76 int r_width = right_->width(); 112 int r_width = right_->width();
77 int br_width = bottom_right_->width(); 113 int br_width = bottom_right_->width();
78 int br_height = bottom_right_->height(); 114 int br_height = bottom_right_->height();
79 int b_height = bottom_->height(); 115 int b_height = bottom_->height();
80 int bl_width = bottom_left_->width(); 116 int bl_width = bottom_left_->width();
81 int bl_height = bottom_left_->height(); 117 int bl_height = bottom_left_->height();
82 118
83 /* The variables below can be confusing; here's what they mean: 119 /* The variables below can be confusing; here's what they mean:
84 * 120 *
85 * border_top∙∙∙∙∙∙∙┌────┬────────┬────┐ 121 * 0∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙┌───┐ ┌───┐
86 * │ / │--------│ \ │ 122 * border_top∙∙∙∙∙∙∙┌────┬─┤ ▲ ├──────┤ ▲ ├─┬────┐
87 * top∙∙∙∙∙∙∙∙∙∙∙∙∙∙│ / ├────────┤ \ │ 123 * │ / │-│∙ ∙│------│∙ ∙│-│ \ │
88 * tl_bottom∙∙∙∙∙∙├───┬┘ └┬───┤∙∙∙∙∙∙tr_bottom 124 * top∙∙∙∙∙∙∙∙∙∙∙∙∙∙│ / ├─┴───┴──────┴───┴─┤ \ │
89 * │ | │ │ | │ 125 * tl_bottom∙∙∙∙∙∙├───┬┘ └┬───┤∙∙∙∙∙∙tr_bottom
90 * │ | │ │ | │ 126 * │ | │ │ | │
91 * │ | │ │ | │ 127 * │ | │ │ | │
92 * bl_y∙∙∙∙∙∙∙∙∙∙∙├───┴┐ ┌┴───┤∙∙∙∙∙∙br_y 128 * │ | │ │ | │
93 * bottom∙∙∙∙∙∙∙∙∙∙∙│ \ ├────────┤ / │ 129 * bl_y∙∙∙∙∙∙∙∙∙∙∙├───┴┐ ┌┴───┤∙∙∙∙∙∙br_y
94 * │ \ │--------│ / │ 130 * bottom∙∙∙∙∙∙∙∙∙∙∙│ \ ├─┬───┬──────┬───┬─┤ / │
95 * border_bottom∙∙∙∙└────┴────────┴────┘ 131 * │ \ │-│. .│------│. .│-│ / │
132 * border_bottom∙∙∙∙└────┴─┤ ▼ ├──────┤ ▼ ├─┴────┘
133 * view.height()∙∙∙∙∙∙∙∙∙∙∙└───┘ └───┘
134 *
135 * (At most one of the arrows will be drawn)
96 */ 136 */
97 137
98 gfx::Insets insets; 138 gfx::Insets insets;
99 GetInsets(&insets); 139 GetInsets(&insets);
100 int top = insets.top(); 140 int top = insets.top();
101 int border_top = top - t_height; 141 int border_top = top - t_height;
102 int tl_bottom = border_top + tl_height; 142 int tl_bottom = border_top + tl_height;
103 int tr_bottom = border_top + tr_height; 143 int tr_bottom = border_top + tr_height;
104 int bottom = view.height() - insets.bottom(); 144 int bottom = view.height() - insets.bottom();
105 int border_bottom = bottom + b_height; 145 int border_bottom = bottom + b_height;
106 int bl_y = border_bottom - bl_height; 146 int bl_y = border_bottom - bl_height;
107 int br_y = border_bottom - br_height; 147 int br_y = border_bottom - br_height;
108 148
109 // Top left corner 149 // Top left corner
110 canvas->DrawBitmapInt(*top_left_, 0, border_top); 150 canvas->DrawBitmapInt(*top_left_, 0, border_top);
111 151
112 // Top edge
113 canvas->TileImageInt(*top_, tl_width, border_top, width - tl_width - tr_width,
114 t_height);
115
116 // Top right corner 152 // Top right corner
117 canvas->DrawBitmapInt(*top_right_, width - tr_width, border_top); 153 canvas->DrawBitmapInt(*top_right_, width - tr_width, border_top);
118 154
119 // Right edge 155 // Right edge
120 canvas->TileImageInt(*right_, width - r_width, tr_bottom, r_width, 156 canvas->TileImageInt(*right_, width - r_width, tr_bottom, r_width,
121 br_y - tr_bottom); 157 br_y - tr_bottom);
122 158
123 // Bottom right corner 159 // Bottom right corner
124 canvas->DrawBitmapInt(*bottom_right_, width - br_width, br_y); 160 canvas->DrawBitmapInt(*bottom_right_, width - br_width, br_y);
125 161
126 // Bottom edge
127 canvas->TileImageInt(*bottom_, bl_width, bottom, width - bl_width - br_width,
128 b_height);
129 162
130 // Bottom left corner 163 // Bottom left corner
131 canvas->DrawBitmapInt(*bottom_left_, 0, bl_y); 164 canvas->DrawBitmapInt(*bottom_left_, 0, bl_y);
132 165
133 // Left edge 166 // Left edge
134 canvas->TileImageInt(*left_, 0, tl_bottom, left_->width(), bl_y - tl_bottom); 167 canvas->TileImageInt(*left_, 0, tl_bottom, left_->width(), bl_y - tl_bottom);
168
169 // Arrow edge, if necessary
170 bool should_draw_top_edge = true;
171 bool should_draw_bottom_edge = true;
172 if (arrow_location_ != NONE) {
173 /* Here's what the variables below mean (without loss of generality):
174 *
175 * arrow_center
176 * arrow_x │ arrow_r
177 * │ │ │
178 * left_of_edge─┬────┐ │ │ │ ┌────┬─right_of_edge
179 * arrow_y∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙┌───┐
180 * edge_y∙∙∙∙∙∙∙┌────┬───┤ ▲ ├───────┬────┐ ┐
181 * │ / │---│∙ ∙│-------│ \ │ ├─e_height
182 * │ / ├───┴───┴───────┤ \ │ ┘
183 * ├───┬┘ └┬───┤
184 * | | └─┬─┘ | |
185 * ∙ ∙└─┬─┘ │ └───┬───┘∙ ∙
186 * left_of_arrow─┘ │ └─right_of_arrow
187 * arrow_width
188 *
189 * Not shown: border_y and tip_y contain the base and tip coordinates inside
190 * the arrow for use filling the arrow interior with the background color.
191 */
192
193 SkBitmap* edge;
194 SkBitmap* arrow;
195 int left_of_edge, right_of_edge, edge_y, arrow_y;
196 SkScalar border_y, tip_y;
197 if (arrow_is_top()) {
198 should_draw_top_edge = false;
199 edge = top_;
200 arrow = top_arrow_;
201 left_of_edge = tl_width;
202 right_of_edge = tr_width;
203 edge_y = border_top;
204 arrow_y = top - top_arrow_->height();
205 border_y = SkIntToScalar(top);
206 tip_y = SkIntToScalar(top - kArrowInteriorHeight);
207 } else {
208 should_draw_bottom_edge = false;
209 edge = bottom_;
210 arrow = bottom_arrow_;
211 left_of_edge = bl_width;
212 right_of_edge = br_width;
213 edge_y = arrow_y = bottom;
214 border_y = SkIntToScalar(bottom);
215 tip_y = SkIntToScalar(bottom + kArrowInteriorHeight);
216 }
217 int arrow_width = (arrow_is_top() ? top_arrow_ : bottom_arrow_)->width();
218 int arrow_center = arrow_is_left() ?
219 arrow_x_offset_ : width - arrow_x_offset_ - 1;
220 int arrow_x = arrow_center - (arrow_width / 2);
221 SkScalar arrow_interior_x =
222 SkIntToScalar(arrow_center - kArrowInteriorHeight);
223 SkScalar arrow_interior_r =
224 SkIntToScalar(arrow_center + kArrowInteriorHeight);
225 int arrow_r = arrow_x + arrow_width;
226 int e_height = edge->height();
227
228 // Edge to the left of the arrow
229 int left_of_arrow = arrow_x - left_of_edge;
230 if (left_of_arrow) {
231 canvas->TileImageInt(*edge, left_of_edge, edge_y, left_of_arrow,
232 e_height);
233 }
234
235 // Interior of the arrow (filled with background color)
236 SkPaint paint;
237 paint.setStyle(SkPaint::kFill_Style);
238 paint.setColor(background_color_);
239 gfx::Path path;
240 path.incReserve(4);
241 path.moveTo(arrow_interior_x, border_y);
242 path.lineTo(SkIntToScalar(arrow_center), tip_y);
243 path.lineTo(arrow_interior_r, border_y);
244 path.close();
245 canvas->drawPath(path, paint);
246
247 // Arrow border
248 canvas->DrawBitmapInt(*arrow, arrow_x, arrow_y);
249
250 // Edge to the right of the arrow
251 int right_of_arrow = width - arrow_r - right_of_edge;
252 if (right_of_arrow)
253 canvas->TileImageInt(*edge, arrow_r, edge_y, right_of_arrow, e_height);
254 }
255
256 // Top edge, if not already drawn
257 if (should_draw_top_edge) {
258 canvas->TileImageInt(*top_, tl_width, border_top,
259 width - tl_width - tr_width, t_height);
260 }
261
262 // Bottom edge, if not already drawn
263 if (should_draw_bottom_edge) {
264 canvas->TileImageInt(*bottom_, bl_width, bottom,
265 width - bl_width - br_width, b_height);
266 }
135 } 267 }
OLDNEW
« no previous file with comments | « chrome/browser/views/bubble_border.h ('k') | chrome/browser/views/info_bubble.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698