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

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

Issue 11819048: Implement message center on Windows (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase on master @fa1d2262 and rearrange dependencies. Created 7 years, 11 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) 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 <algorithm> 7 #include <algorithm>
8 8
9 #include "third_party/skia/include/core/SkCanvas.h" 9 #include "third_party/skia/include/core/SkCanvas.h"
10 #include "third_party/skia/include/core/SkColor.h" 10 #include "third_party/skia/include/core/SkColor.h"
(...skipping 25 matching lines...) Expand all
36 namespace views { 36 namespace views {
37 37
38 namespace internal { 38 namespace internal {
39 39
40 // Custom border for TrayBubbleView. Contains special logic for GetBounds() 40 // Custom border for TrayBubbleView. Contains special logic for GetBounds()
41 // to stack bubbles with no arrows correctly. Also calculates the arrow offset. 41 // to stack bubbles with no arrows correctly. Also calculates the arrow offset.
42 class TrayBubbleBorder : public views::BubbleBorder { 42 class TrayBubbleBorder : public views::BubbleBorder {
43 public: 43 public:
44 TrayBubbleBorder(views::View* owner, 44 TrayBubbleBorder(views::View* owner,
45 views::View* anchor, 45 views::View* anchor,
46 gfx::Point anchor_point,
46 TrayBubbleView::InitParams params) 47 TrayBubbleView::InitParams params)
47 : views::BubbleBorder(params.arrow_location, params.shadow), 48 : views::BubbleBorder(params.arrow_location, params.shadow),
48 owner_(owner), 49 owner_(owner),
49 anchor_(anchor), 50 anchor_(anchor),
51 anchor_point_(anchor_point.x(), anchor_point.y()),
50 tray_arrow_offset_(params.arrow_offset) { 52 tray_arrow_offset_(params.arrow_offset) {
51 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); 53 set_alignment(params.arrow_alignment);
52 set_background_color(params.arrow_color); 54 set_background_color(params.arrow_color);
53 } 55 }
54 56
55 virtual ~TrayBubbleBorder() {} 57 virtual ~TrayBubbleBorder() {}
56 58
57 // Overridden from views::BubbleBorder. 59 // Overridden from views::BubbleBorder.
58 // Override views::BubbleBorder to set the bubble on top of the anchor when 60 // Override views::BubbleBorder to set the bubble on top of the anchor when
59 // it has no arrow. 61 // it has no arrow.
60 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, 62 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
61 const gfx::Size& contents_size) const OVERRIDE { 63 const gfx::Size& contents_size) const OVERRIDE {
62 if (arrow_location() != NONE) { 64 if (has_arrow(arrow_location())) {
63 return views::BubbleBorder::GetBounds(position_relative_to, 65 return views::BubbleBorder::GetBounds(position_relative_to,
64 contents_size); 66 contents_size);
65 } 67 }
66 68
67 gfx::Size border_size(contents_size); 69 gfx::Size border_size(contents_size);
68 gfx::Insets insets = GetInsets(); 70 gfx::Insets insets = GetInsets();
69 border_size.Enlarge(insets.width(), insets.height()); 71 border_size.Enlarge(insets.width(), insets.height());
70 72
71 const int x = position_relative_to.x() + 73 const int x = position_relative_to.x() +
72 position_relative_to.width() / 2 - border_size.width() / 2; 74 position_relative_to.width() / 2 - border_size.width() / 2;
73 // Position the bubble on top of the anchor. 75 // Position the bubble on top of the anchor.
74 const int y = position_relative_to.y() - border_size.height() 76 const int y = position_relative_to.y() - border_size.height()
75 + insets.height() - kBubbleSpacing; 77 + insets.height() - kBubbleSpacing;
76 return gfx::Rect(x, y, border_size.width(), border_size.height()); 78 return gfx::Rect(x, y, border_size.width(), border_size.height());
77 } 79 }
78 80
81 // Anchor point is in screen coordinates.
79 void UpdateArrowOffset() { 82 void UpdateArrowOffset() {
83 if (!has_arrow(arrow_location())) {
84 return;
85 }
86
80 int arrow_offset = 0; 87 int arrow_offset = 0;
81 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT || 88 gfx::Point pt(0, 0);
82 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) { 89 if (tray_arrow_offset_ == TrayBubbleView::InitParams::kArrowDefaultOffset) {
83 // Note: tray_arrow_offset_ is relative to the anchor widget. 90 set_arrow_offset(kArrowMinOffset);
84 if (tray_arrow_offset_ == 91 return;
85 TrayBubbleView::InitParams::kArrowDefaultOffset) { 92 }
86 arrow_offset = kArrowMinOffset; 93 // Note: tray_arrow_offset_ is relative to the anchor widget.
87 } else { 94 if (is_arrow_on_horizontal(arrow_location()))
88 const int width = owner_->GetWidget()->GetContentsView()->width(); 95 pt.set_x(tray_arrow_offset_);
89 gfx::Point pt(tray_arrow_offset_, 0); 96 else
90 views::View::ConvertPointToScreen( 97 pt.set_y(tray_arrow_offset_);
91 anchor_->GetWidget()->GetRootView(), &pt); 98
92 views::View::ConvertPointFromScreen( 99 if (anchor_) {
93 owner_->GetWidget()->GetRootView(), &pt); 100 views::View::ConvertPointToScreen(
94 arrow_offset = pt.x(); 101 anchor_->GetWidget()->GetRootView(), &pt);
95 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT)
96 arrow_offset = width - arrow_offset;
97 arrow_offset = std::max(arrow_offset, kArrowMinOffset);
98 }
99 } else { 102 } else {
100 if (tray_arrow_offset_ == 103 pt.Offset(anchor_point_.x(), anchor_point_.y());
101 TrayBubbleView::InitParams::kArrowDefaultOffset) {
102 arrow_offset = kArrowMinOffset;
103 } else {
104 gfx::Point pt(0, tray_arrow_offset_);
105 views::View::ConvertPointToScreen(
106 anchor_->GetWidget()->GetRootView(), &pt);
107 views::View::ConvertPointFromScreen(
108 owner_->GetWidget()->GetRootView(), &pt);
109 arrow_offset = pt.y();
110 arrow_offset = std::max(arrow_offset, kArrowMinOffset);
111 }
112 } 104 }
105
106 views::View::ConvertPointFromScreen(
107 owner_->GetWidget()->GetRootView(), &pt);
108 const int width = owner_->GetWidget()->GetContentsView()->width();
109
110 if (is_arrow_on_horizontal(arrow_location())) {
111 arrow_offset = pt.x();
112 if (!is_arrow_on_left(arrow_location()))
113 arrow_offset = width - arrow_offset;
114 } else {
115 arrow_offset = pt.y();
116 }
117
118 arrow_offset = std::max(arrow_offset, kArrowMinOffset);
113 set_arrow_offset(arrow_offset); 119 set_arrow_offset(arrow_offset);
114 } 120 }
115 121
116 private: 122 private:
117 views::View* owner_; 123 views::View* owner_;
118 views::View* anchor_; 124 views::View* anchor_;
125 gfx::Point anchor_point_;
119 const int tray_arrow_offset_; 126 const int tray_arrow_offset_;
120 127
121 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); 128 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder);
122 }; 129 };
123 130
124 // This mask layer clips the bubble's content so that it does not overwrite the 131 // This mask layer clips the bubble's content so that it does not overwrite the
125 // rounded bubble corners. 132 // rounded bubble corners.
126 // TODO(miket): This does not work on Windows. Implement layer masking or 133 // TODO(miket): This does not work on Windows. Implement layer masking or
127 // alternate solutions if the TrayBubbleView is needed there in the future. 134 // alternate solutions if the TrayBubbleView is needed there in the future.
128 class TrayBubbleContentMask : public ui::LayerDelegate { 135 class TrayBubbleContentMask : public ui::LayerDelegate {
(...skipping 11 matching lines...) Expand all
140 private: 147 private:
141 ui::Layer layer_; 148 ui::Layer layer_;
142 SkScalar corner_radius_; 149 SkScalar corner_radius_;
143 150
144 DISALLOW_COPY_AND_ASSIGN(TrayBubbleContentMask); 151 DISALLOW_COPY_AND_ASSIGN(TrayBubbleContentMask);
145 }; 152 };
146 153
147 TrayBubbleContentMask::TrayBubbleContentMask(int corner_radius) 154 TrayBubbleContentMask::TrayBubbleContentMask(int corner_radius)
148 : layer_(ui::LAYER_TEXTURED), 155 : layer_(ui::LAYER_TEXTURED),
149 corner_radius_(corner_radius) { 156 corner_radius_(corner_radius) {
157 #ifdef USE_AURA
150 layer_.set_delegate(this); 158 layer_.set_delegate(this);
159 #endif
151 } 160 }
152 161
153 TrayBubbleContentMask::~TrayBubbleContentMask() { 162 TrayBubbleContentMask::~TrayBubbleContentMask() {
163 #ifdef USE_AURA
154 layer_.set_delegate(NULL); 164 layer_.set_delegate(NULL);
165 #endif
155 } 166 }
156 167
157 void TrayBubbleContentMask::OnPaintLayer(gfx::Canvas* canvas) { 168 void TrayBubbleContentMask::OnPaintLayer(gfx::Canvas* canvas) {
158 SkPath path; 169 SkPath path;
159 path.addRoundRect(gfx::RectToSkRect(gfx::Rect(layer()->bounds().size())), 170 path.addRoundRect(gfx::RectToSkRect(gfx::Rect(layer()->bounds().size())),
160 corner_radius_, corner_radius_); 171 corner_radius_, corner_radius_);
161 SkPaint paint; 172 SkPaint paint;
162 paint.setAlpha(255); 173 paint.setAlpha(255);
163 paint.setStyle(SkPaint::kFill_Style); 174 paint.setStyle(SkPaint::kFill_Style);
164 canvas->DrawPath(path, paint); 175 canvas->DrawPath(path, paint);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 : anchor_type(anchor_type), 237 : anchor_type(anchor_type),
227 anchor_alignment(anchor_alignment), 238 anchor_alignment(anchor_alignment),
228 min_width(min_width), 239 min_width(min_width),
229 max_width(max_width), 240 max_width(max_width),
230 max_height(0), 241 max_height(0),
231 can_activate(false), 242 can_activate(false),
232 close_on_deactivate(true), 243 close_on_deactivate(true),
233 arrow_color(SK_ColorBLACK), 244 arrow_color(SK_ColorBLACK),
234 arrow_location(views::BubbleBorder::NONE), 245 arrow_location(views::BubbleBorder::NONE),
235 arrow_offset(kArrowDefaultOffset), 246 arrow_offset(kArrowDefaultOffset),
236 shadow(views::BubbleBorder::BIG_SHADOW) { 247 shadow(views::BubbleBorder::BIG_SHADOW),
248 arrow_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE) {
237 } 249 }
238 250
239 // static 251 // static
240 TrayBubbleView* TrayBubbleView::Create(gfx::NativeView parent_window, 252 TrayBubbleView* TrayBubbleView::Create(gfx::NativeView parent_window,
241 views::View* anchor, 253 views::View* anchor,
242 Delegate* delegate, 254 Delegate* delegate,
243 InitParams* init_params) { 255 InitParams* init_params) {
244 // Set arrow_location here so that it can be passed correctly to the 256 // Set arrow_location here so that it can be passed correctly to the
245 // BubbleView constructor. 257 // BubbleView constructor.
246 if (init_params->anchor_type == ANCHOR_TYPE_TRAY) { 258 if (init_params->anchor_type == ANCHOR_TYPE_TRAY) {
(...skipping 19 matching lines...) Expand all
266 : views::BubbleDelegateView(anchor, init_params.arrow_location), 278 : views::BubbleDelegateView(anchor, init_params.arrow_location),
267 params_(init_params), 279 params_(init_params),
268 delegate_(delegate), 280 delegate_(delegate),
269 preferred_width_(init_params.min_width), 281 preferred_width_(init_params.min_width),
270 bubble_border_(NULL), 282 bubble_border_(NULL),
271 is_gesture_dragging_(false) { 283 is_gesture_dragging_(false) {
272 set_parent_window(parent_window); 284 set_parent_window(parent_window);
273 set_notify_enter_exit_on_child(true); 285 set_notify_enter_exit_on_child(true);
274 set_close_on_deactivate(init_params.close_on_deactivate); 286 set_close_on_deactivate(init_params.close_on_deactivate);
275 set_margins(gfx::Insets()); 287 set_margins(gfx::Insets());
288 bubble_border_ = new TrayBubbleBorder(
289 this,
290 anchor_view(),
291 gfx::Point(init_params.anchor_point_x, init_params.anchor_point_y),
292 params_);
293
294 #ifdef USE_AURA
276 SetPaintToLayer(true); 295 SetPaintToLayer(true);
277 SetFillsBoundsOpaquely(true); 296 SetFillsBoundsOpaquely(true);
278 297
279 bubble_border_ = new TrayBubbleBorder(this, anchor_view(), params_);
280
281 bubble_content_mask_.reset( 298 bubble_content_mask_.reset(
282 new TrayBubbleContentMask(bubble_border_->GetBorderCornerRadius() - 1)); 299 new TrayBubbleContentMask(bubble_border_->GetBorderCornerRadius() - 1));
300 #endif //USE_AURA
283 } 301 }
284 302
285 TrayBubbleView::~TrayBubbleView() { 303 TrayBubbleView::~TrayBubbleView() {
286 // Inform host items (models) that their views are being destroyed. 304 // Inform host items (models) that their views are being destroyed.
287 if (delegate_) 305 if (delegate_)
288 delegate_->BubbleViewDestroyed(); 306 delegate_->BubbleViewDestroyed();
289 } 307 }
290 308
291 void TrayBubbleView::InitializeAndShowBubble() { 309 void TrayBubbleView::InitializeAndShowBubble() {
292 // Must occur after call to BubbleDelegateView::CreateBubble(). 310 // Must occur after call to BubbleDelegateView::CreateBubble().
293 SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); 311 SetAlignment(params_.arrow_alignment);
294 bubble_border_->UpdateArrowOffset(); 312 bubble_border_->UpdateArrowOffset();
295 313
314 #ifdef USE_AURA
296 layer()->parent()->SetMaskLayer(bubble_content_mask_->layer()); 315 layer()->parent()->SetMaskLayer(bubble_content_mask_->layer());
316 #endif // USE_AURA
297 317
298 Show(); 318 Show();
299 UpdateBubble(); 319 UpdateBubble();
300 } 320 }
301 321
302 void TrayBubbleView::UpdateBubble() { 322 void TrayBubbleView::UpdateBubble() {
303 SizeToContents(); 323 SizeToContents();
324 #ifdef USE_AURA
304 bubble_content_mask_->layer()->SetBounds(layer()->bounds()); 325 bubble_content_mask_->layer()->SetBounds(layer()->bounds());
326 #endif // USE_AURA
305 GetWidget()->GetRootView()->SchedulePaint(); 327 GetWidget()->GetRootView()->SchedulePaint();
306 } 328 }
307 329
308 void TrayBubbleView::SetMaxHeight(int height) { 330 void TrayBubbleView::SetMaxHeight(int height) {
309 params_.max_height = height; 331 params_.max_height = height;
310 if (GetWidget()) 332 if (GetWidget())
311 SizeToContents(); 333 SizeToContents();
312 } 334 }
313 335
314 void TrayBubbleView::SetWidth(int width) { 336 void TrayBubbleView::SetWidth(int width) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } 416 }
395 } 417 }
396 418
397 void TrayBubbleView::ChildPreferredSizeChanged(View* child) { 419 void TrayBubbleView::ChildPreferredSizeChanged(View* child) {
398 SizeToContents(); 420 SizeToContents();
399 } 421 }
400 422
401 void TrayBubbleView::ViewHierarchyChanged(bool is_add, 423 void TrayBubbleView::ViewHierarchyChanged(bool is_add,
402 views::View* parent, 424 views::View* parent,
403 views::View* child) { 425 views::View* child) {
426 #ifdef USE_AURA
404 if (is_add && child == this) { 427 if (is_add && child == this) {
405 parent->SetPaintToLayer(true); 428 parent->SetPaintToLayer(true);
406 parent->SetFillsBoundsOpaquely(true); 429 parent->SetFillsBoundsOpaquely(true);
407 parent->layer()->SetMasksToBounds(true); 430 parent->layer()->SetMasksToBounds(true);
408 } 431 }
432 #endif // USE_AURA
409 } 433 }
410 434
411 } // namespace views 435 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698