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

Side by Side Diff: ui/views/bubble/tray_bubble_view.cc

Issue 11293124: Remove top and bottom margins from TrayBubbleView (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed. Created 8 years, 1 month 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 | « ui/views/bubble/tray_bubble_view.h ('k') | ui/views/views.gyp » ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/views/bubble/tray_bubble_view.h" 5 #include "ui/views/bubble/tray_bubble_view.h"
6 6
7 #include "third_party/skia/include/core/SkCanvas.h" 7 #include "third_party/skia/include/core/SkCanvas.h"
8 #include "third_party/skia/include/core/SkColor.h" 8 #include "third_party/skia/include/core/SkColor.h"
9 #include "third_party/skia/include/core/SkPaint.h" 9 #include "third_party/skia/include/core/SkPaint.h"
10 #include "third_party/skia/include/core/SkPath.h" 10 #include "third_party/skia/include/core/SkPath.h"
11 #include "third_party/skia/include/effects/SkBlurImageFilter.h" 11 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
12 #include "ui/base/accessibility/accessible_view_state.h" 12 #include "ui/base/accessibility/accessible_view_state.h"
13 #include "ui/base/events/event.h" 13 #include "ui/base/events/event.h"
14 #include "ui/base/l10n/l10n_util.h" 14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/compositor/layer.h"
16 #include "ui/compositor/layer_delegate.h"
15 #include "ui/gfx/canvas.h" 17 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/insets.h" 18 #include "ui/gfx/insets.h"
17 #include "ui/gfx/path.h" 19 #include "ui/gfx/path.h"
20 #include "ui/gfx/rect.h"
18 #include "ui/gfx/skia_util.h" 21 #include "ui/gfx/skia_util.h"
19 #include "ui/views/bubble/bubble_frame_view.h" 22 #include "ui/views/bubble/bubble_frame_view.h"
20 #include "ui/views/layout/box_layout.h" 23 #include "ui/views/layout/box_layout.h"
21 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
22 25
23 namespace { 26 namespace {
24 27
25 // Inset the arrow a bit from the edge. 28 // Inset the arrow a bit from the edge.
26 const int kArrowMinOffset = 20; 29 const int kArrowMinOffset = 20;
27 const int kBubbleSpacing = 20; 30 const int kBubbleSpacing = 20;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } 113 }
111 114
112 private: 115 private:
113 views::View* owner_; 116 views::View* owner_;
114 views::View* anchor_; 117 views::View* anchor_;
115 const int tray_arrow_offset_; 118 const int tray_arrow_offset_;
116 119
117 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); 120 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder);
118 }; 121 };
119 122
120 // Custom background for TrayBubbleView. Fills in the top and bottom margins 123 // This mask layer clips the bubble's content so that it does not overwrite the
121 // with appropriate background colors without overwriting the rounded corners. 124 // rounded bubble corners.
122 class TrayBubbleBackground : public views::Background { 125 // TODO(miket): This does not work on Windows. Implement layer masking or
126 // alternate solutions if the TrayBubbleView is needed there in the future.
127 class TrayBubbleContentMask : public ui::LayerDelegate {
123 public: 128 public:
124 explicit TrayBubbleBackground(views::BubbleBorder* border, 129 TrayBubbleContentMask(int corner_radius);
msw 2012/11/13 20:28:04 nit: explicit
bartfab (slow) 2012/11/13 20:41:15 Done.
125 SkColor top_color, 130 virtual ~TrayBubbleContentMask();
126 SkColor bottom_color)
127 : border_(border),
128 top_color_(top_color),
129 bottom_color_(bottom_color),
130 radius_(SkIntToScalar(border->GetBorderCornerRadius() - 1)) {
131 }
132 131
133 SkScalar radius() const { return radius_; } 132 ui::Layer& layer() { return layer_; }
msw 2012/11/13 20:28:04 nit: const ref+function or non-const pointer.
bartfab (slow) 2012/11/13 20:41:15 Done.
134 133
135 // Overridden from Background: 134 // Overridden from LayerDelegate.
136 virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { 135 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
137 canvas->Save(); 136 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
138 137 virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
139 // Set a clip mask for the bubble's rounded corners.
140 gfx::Rect bounds(view->GetContentsBounds());
141 const int border_thickness(border_->GetBorderThickness());
142 bounds.Inset(-border_thickness, -border_thickness);
143 SkPath path;
144 path.addRoundRect(gfx::RectToSkRect(bounds), radius_, radius_);
145 canvas->ClipPath(path);
146
147 // Paint the header and footer (assumes the bubble contents fill in their
148 // own backgrounds).
149 SkPaint paint;
150 paint.setStyle(SkPaint::kFill_Style);
151
152 gfx::Rect top_rect(bounds);
153 top_rect.set_height(radius_);
154 paint.setColor(top_color_);
155 canvas->DrawRect(top_rect, paint);
156
157 gfx::Rect bottom_rect(bounds);
158 bottom_rect.set_y(bounds.y() + (bounds.height() - radius_));
159 bottom_rect.set_height(radius_);
160 paint.setColor(bottom_color_);
161 canvas->DrawRect(bottom_rect, paint);
162
163 canvas->Restore();
164 }
165 138
166 private: 139 private:
167 views::BubbleBorder* border_; 140 ui::Layer layer_;
168 SkColor top_color_; 141 SkScalar corner_radius_;
169 SkColor bottom_color_;
170 SkScalar radius_;
171 142
172 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBackground); 143 DISALLOW_COPY_AND_ASSIGN(TrayBubbleContentMask);
173 }; 144 };
174 145
146 TrayBubbleContentMask::TrayBubbleContentMask(int corner_radius)
147 : layer_(ui::LAYER_TEXTURED), corner_radius_(corner_radius) {
msw 2012/11/13 20:28:04 nit: one init per line (since they don't fit above
bartfab (slow) 2012/11/13 20:41:15 Done.
148 layer_.set_delegate(this);
149 }
150
151 TrayBubbleContentMask::~TrayBubbleContentMask() {
152 layer_.set_delegate(NULL);
153 }
154
155 void TrayBubbleContentMask::OnPaintLayer(gfx::Canvas* canvas) {
156 SkPath path;
157 path.addRoundRect(gfx::RectToSkRect(gfx::Rect(layer().bounds().size())),
158 corner_radius_, corner_radius_);
159 SkPaint paint;
160 paint.setAlpha(255);
161 paint.setStyle(SkPaint::kFill_Style);
162 canvas->DrawPath(path, paint);
163 }
164
165 void TrayBubbleContentMask::OnDeviceScaleFactorChanged(
166 float device_scale_factor) {
167 }
168
169 base::Closure TrayBubbleContentMask::PrepareForLayerBoundsChange() {
170 return base::Closure();
171 }
172
175 // Custom layout for the bubble-view. Does the default box-layout if there is 173 // Custom layout for the bubble-view. Does the default box-layout if there is
176 // enough height. Otherwise, makes sure the bottom rows are visible. 174 // enough height. Otherwise, makes sure the bottom rows are visible.
177 class BottomAlignedBoxLayout : public views::BoxLayout { 175 class BottomAlignedBoxLayout : public views::BoxLayout {
178 public: 176 public:
179 explicit BottomAlignedBoxLayout(TrayBubbleView* bubble_view) 177 explicit BottomAlignedBoxLayout(TrayBubbleView* bubble_view)
180 : views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0), 178 : views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0),
181 bubble_view_(bubble_view) { 179 bubble_view_(bubble_view) {
182 } 180 }
183 181
184 virtual ~BottomAlignedBoxLayout() {} 182 virtual ~BottomAlignedBoxLayout() {}
(...skipping 20 matching lines...) Expand all
205 } 203 }
206 204
207 TrayBubbleView* bubble_view_; 205 TrayBubbleView* bubble_view_;
208 206
209 DISALLOW_COPY_AND_ASSIGN(BottomAlignedBoxLayout); 207 DISALLOW_COPY_AND_ASSIGN(BottomAlignedBoxLayout);
210 }; 208 };
211 209
212 } // namespace internal 210 } // namespace internal
213 211
214 using internal::TrayBubbleBorder; 212 using internal::TrayBubbleBorder;
215 using internal::TrayBubbleBackground; 213 using internal::TrayBubbleContentMask;
216 using internal::BottomAlignedBoxLayout; 214 using internal::BottomAlignedBoxLayout;
217 215
218 // static 216 // static
219 const int TrayBubbleView::InitParams::kArrowDefaultOffset = -1; 217 const int TrayBubbleView::InitParams::kArrowDefaultOffset = -1;
220 218
221 TrayBubbleView::InitParams::InitParams(AnchorType anchor_type, 219 TrayBubbleView::InitParams::InitParams(AnchorType anchor_type,
222 AnchorAlignment anchor_alignment, 220 AnchorAlignment anchor_alignment,
223 int bubble_width) 221 int bubble_width)
224 : anchor_type(anchor_type), 222 : anchor_type(anchor_type),
225 anchor_alignment(anchor_alignment), 223 anchor_alignment(anchor_alignment),
226 bubble_width(bubble_width), 224 bubble_width(bubble_width),
227 max_height(0), 225 max_height(0),
228 can_activate(false), 226 can_activate(false),
229 close_on_deactivate(true), 227 close_on_deactivate(true),
230 top_color(SK_ColorBLACK),
231 arrow_color(SK_ColorBLACK), 228 arrow_color(SK_ColorBLACK),
232 arrow_location(views::BubbleBorder::NONE), 229 arrow_location(views::BubbleBorder::NONE),
233 arrow_offset(kArrowDefaultOffset), 230 arrow_offset(kArrowDefaultOffset),
234 shadow(views::BubbleBorder::BIG_SHADOW) { 231 shadow(views::BubbleBorder::BIG_SHADOW) {
235 } 232 }
236 233
237 // static 234 // static
238 TrayBubbleView* TrayBubbleView::Create(gfx::NativeView parent_window, 235 TrayBubbleView* TrayBubbleView::Create(gfx::NativeView parent_window,
239 views::View* anchor, 236 views::View* anchor,
240 Delegate* delegate, 237 Delegate* delegate,
(...skipping 17 matching lines...) Expand all
258 } 255 }
259 256
260 TrayBubbleView::TrayBubbleView(gfx::NativeView parent_window, 257 TrayBubbleView::TrayBubbleView(gfx::NativeView parent_window,
261 views::View* anchor, 258 views::View* anchor,
262 Delegate* delegate, 259 Delegate* delegate,
263 const InitParams& init_params) 260 const InitParams& init_params)
264 : views::BubbleDelegateView(anchor, init_params.arrow_location), 261 : views::BubbleDelegateView(anchor, init_params.arrow_location),
265 params_(init_params), 262 params_(init_params),
266 delegate_(delegate), 263 delegate_(delegate),
267 bubble_border_(NULL), 264 bubble_border_(NULL),
268 bubble_background_(NULL),
269 is_gesture_dragging_(false) { 265 is_gesture_dragging_(false) {
270 set_parent_window(parent_window); 266 set_parent_window(parent_window);
271 set_notify_enter_exit_on_child(true); 267 set_notify_enter_exit_on_child(true);
272 set_close_on_deactivate(init_params.close_on_deactivate); 268 set_close_on_deactivate(init_params.close_on_deactivate);
269 set_margins(gfx::Insets());
273 SetPaintToLayer(true); 270 SetPaintToLayer(true);
274 SetFillsBoundsOpaquely(true); 271 SetFillsBoundsOpaquely(true);
275 272
276 bubble_border_ = new TrayBubbleBorder(this, anchor_view(), params_); 273 bubble_border_ = new TrayBubbleBorder(this, anchor_view(), params_);
277 274
278 bubble_background_ = new TrayBubbleBackground( 275 bubble_content_mask_.reset(
279 bubble_border_, init_params.top_color, init_params.arrow_color); 276 new TrayBubbleContentMask(bubble_border_->GetBorderCornerRadius() - 1));
280
281 // Inset the view on the top and bottom by the corner radius to avoid drawing
282 // over the the bubble corners.
283 const int radius = bubble_background_->radius();
284 set_margins(gfx::Insets(radius, 0, radius, 0));
285 } 277 }
286 278
287 TrayBubbleView::~TrayBubbleView() { 279 TrayBubbleView::~TrayBubbleView() {
288 // Inform host items (models) that their views are being destroyed. 280 // Inform host items (models) that their views are being destroyed.
289 if (delegate_) 281 if (delegate_)
290 delegate_->BubbleViewDestroyed(); 282 delegate_->BubbleViewDestroyed();
291 } 283 }
292 284
293 void TrayBubbleView::InitializeAndShowBubble() { 285 void TrayBubbleView::InitializeAndShowBubble() {
294 // Must occur after call to BubbleDelegateView::CreateBubble(). 286 // Must occur after call to BubbleDelegateView::CreateBubble().
295 SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); 287 SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
296 bubble_border_->UpdateArrowOffset(); 288 bubble_border_->UpdateArrowOffset();
297 289
290 layer()->parent()->SetMaskLayer(&bubble_content_mask_->layer());
291
298 Show(); 292 Show();
299 UpdateBubble(); 293 UpdateBubble();
300 } 294 }
301 295
302 void TrayBubbleView::UpdateBubble() { 296 void TrayBubbleView::UpdateBubble() {
303 SizeToContents(); 297 SizeToContents();
298 bubble_content_mask_->layer().SetBounds(layer()->bounds());
304 GetWidget()->GetRootView()->SchedulePaint(); 299 GetWidget()->GetRootView()->SchedulePaint();
305 } 300 }
306 301
307 void TrayBubbleView::SetMaxHeight(int height) { 302 void TrayBubbleView::SetMaxHeight(int height) {
308 params_.max_height = height; 303 params_.max_height = height;
309 if (GetWidget()) 304 if (GetWidget())
310 SizeToContents(); 305 SizeToContents();
311 } 306 }
312 307
313 void TrayBubbleView::SetPaintArrow(bool paint_arrow) { 308 void TrayBubbleView::SetPaintArrow(bool paint_arrow) {
(...skipping 15 matching lines...) Expand all
329 return gfx::Rect(); 324 return gfx::Rect();
330 return delegate_->GetAnchorRect(anchor_widget(), 325 return delegate_->GetAnchorRect(anchor_widget(),
331 params_.anchor_type, 326 params_.anchor_type,
332 params_.anchor_alignment); 327 params_.anchor_alignment);
333 } 328 }
334 329
335 bool TrayBubbleView::CanActivate() const { 330 bool TrayBubbleView::CanActivate() const {
336 return params_.can_activate; 331 return params_.can_activate;
337 } 332 }
338 333
339 // Overridden to create BubbleFrameView and set a custom border and background. 334 // Overridden to create BubbleFrameView and set a custom border.
340 views::NonClientFrameView* TrayBubbleView::CreateNonClientFrameView( 335 views::NonClientFrameView* TrayBubbleView::CreateNonClientFrameView(
341 views::Widget* widget) { 336 views::Widget* widget) {
342 views::BubbleFrameView* bubble_frame_view = 337 views::BubbleFrameView* bubble_frame_view =
343 new views::BubbleFrameView(margins(), bubble_border_); 338 new views::BubbleFrameView(margins(), bubble_border_);
344 bubble_frame_view->set_background(bubble_background_);
345 return bubble_frame_view; 339 return bubble_frame_view;
346 } 340 }
347 341
348 bool TrayBubbleView::WidgetHasHitTestMask() const { 342 bool TrayBubbleView::WidgetHasHitTestMask() const {
349 return true; 343 return true;
350 } 344 }
351 345
352 void TrayBubbleView::GetWidgetHitTestMask(gfx::Path* mask) const { 346 void TrayBubbleView::GetWidgetHitTestMask(gfx::Path* mask) const {
353 DCHECK(mask); 347 DCHECK(mask);
354 mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds())); 348 mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds()));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 views::View* parent, 381 views::View* parent,
388 views::View* child) { 382 views::View* child) {
389 if (is_add && child == this) { 383 if (is_add && child == this) {
390 parent->SetPaintToLayer(true); 384 parent->SetPaintToLayer(true);
391 parent->SetFillsBoundsOpaquely(true); 385 parent->SetFillsBoundsOpaquely(true);
392 parent->layer()->SetMasksToBounds(true); 386 parent->layer()->SetMasksToBounds(true);
393 } 387 }
394 } 388 }
395 389
396 } // namespace views 390 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/bubble/tray_bubble_view.h ('k') | ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698