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

Side by Side Diff: ash/system/tray/tray_bubble_view.cc

Issue 10808066: Fix position of web notification bubble and arrow (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: . Created 8 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
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 "ash/system/tray/tray_bubble_view.h" 5 #include "ash/system/tray/tray_bubble_view.h"
6 6
7 #include "ash/shell.h" 7 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h" 8 #include "ash/shell_window_ids.h"
9 #include "ash/system/tray/tray_constants.h" 9 #include "ash/system/tray/tray_constants.h"
10 #include "ash/wm/shelf_layout_manager.h" 10 #include "ash/wm/shelf_layout_manager.h"
11 #include "ash/wm/window_animations.h"
11 #include "grit/ash_strings.h" 12 #include "grit/ash_strings.h"
12 #include "third_party/skia/include/core/SkCanvas.h" 13 #include "third_party/skia/include/core/SkCanvas.h"
13 #include "third_party/skia/include/core/SkColor.h" 14 #include "third_party/skia/include/core/SkColor.h"
14 #include "third_party/skia/include/core/SkPaint.h" 15 #include "third_party/skia/include/core/SkPaint.h"
15 #include "third_party/skia/include/core/SkPath.h" 16 #include "third_party/skia/include/core/SkPath.h"
16 #include "third_party/skia/include/effects/SkBlurImageFilter.h" 17 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
17 #include "ui/aura/event.h" 18 #include "ui/aura/event.h"
18 #include "ui/aura/window.h" 19 #include "ui/aura/window.h"
19 #include "ui/base/accessibility/accessible_view_state.h" 20 #include "ui/base/accessibility/accessible_view_state.h"
20 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/gfx/canvas.h" 22 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/insets.h" 23 #include "ui/gfx/insets.h"
23 #include "ui/gfx/screen.h" 24 #include "ui/gfx/screen.h"
24 #include "ui/views/bubble/bubble_frame_view.h" 25 #include "ui/views/bubble/bubble_frame_view.h"
25 #include "ui/views/layout/box_layout.h" 26 #include "ui/views/layout/box_layout.h"
26 27
27 namespace ash { 28 namespace ash {
28 29
29 namespace { 30 namespace {
30 31
31 const int kShadowThickness = 4; 32 const int kShadowThickness = 4;
32 const int kBottomLineHeight = 1; 33 const int kBottomLineHeight = 1;
33 const int kSystemTrayBubbleHorizontalInset = 1; 34 const int kSystemTrayBubbleHorizontalInset = 1;
34 const int kSystemTrayBubbleVerticalInset = 1; 35 const int kSystemTrayBubbleVerticalInset = 1;
35 36
36 const int kArrowHeight = 10; 37 const int kArrowHeight = 10;
37 const int kArrowWidth = 20; 38 const int kArrowWidth = 20;
38 39
39 // Inset the arrow a bit from the edge. 40 // Inset the arrow a bit from the edge.
40 const int kArrowMinOffset = kArrowWidth / 2 + 4; 41 const int kArrowEdgeMargin = 12;
42 const int kArrowMinOffset = kArrowWidth / 2 + kArrowEdgeMargin;
41 43
42 const SkColor kShadowColor = SkColorSetARGB(0xff, 0, 0, 0); 44 const SkColor kShadowColor = SkColorSetARGB(0xff, 0, 0, 0);
43 45
46 const int kAnimationDurationForPopupMS = 200;
47
44 void DrawBlurredShadowAroundView(gfx::Canvas* canvas, 48 void DrawBlurredShadowAroundView(gfx::Canvas* canvas,
45 int top, 49 int top,
46 int bottom, 50 int bottom,
47 int width, 51 int width,
48 const gfx::Insets& inset) { 52 const gfx::Insets& inset) {
49 SkPath path; 53 SkPath path;
50 path.incReserve(4); 54 path.incReserve(4);
51 path.moveTo(SkIntToScalar(inset.left() + kShadowThickness), 55 path.moveTo(SkIntToScalar(inset.left() + kShadowThickness),
52 SkIntToScalar(top + kShadowThickness + 1)); 56 SkIntToScalar(top + kShadowThickness + 1));
53 path.lineTo(SkIntToScalar(inset.left() + kShadowThickness), 57 path.lineTo(SkIntToScalar(inset.left() + kShadowThickness),
(...skipping 18 matching lines...) Expand all
72 TrayBubbleBorder(views::View* owner, 76 TrayBubbleBorder(views::View* owner,
73 views::View* anchor, 77 views::View* anchor,
74 views::BubbleBorder::ArrowLocation arrow_location, 78 views::BubbleBorder::ArrowLocation arrow_location,
75 int arrow_offset) 79 int arrow_offset)
76 : views::BubbleBorder(arrow_location, 80 : views::BubbleBorder(arrow_location,
77 views::BubbleBorder::NO_SHADOW), 81 views::BubbleBorder::NO_SHADOW),
78 owner_(owner), 82 owner_(owner),
79 anchor_(anchor), 83 anchor_(anchor),
80 tray_arrow_offset_(arrow_offset) { 84 tray_arrow_offset_(arrow_offset) {
81 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); 85 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
86 // Normally all rendering is mirrored for RTL. This doesn't work correctly
87 // with status area bubbles, and would make Paint much more complex.
88 // Instead, set rtl_mirrored_ to false so that GetInsets() returns
89 // the unmirrored insets.
90 set_rtl_mirrored(false);
82 } 91 }
83 92
84 virtual ~TrayBubbleBorder() {} 93 virtual ~TrayBubbleBorder() {}
85 94
86 private:
87 views::Background* FindAppropriateBackground(views::View* view,
88 const gfx::Point& point) const {
89 views::Background* background = NULL;
90 views::View* target = view->GetEventHandlerForPoint(point);
91 for (; target && !background; target = target->parent())
92 background = target->background();
93 return background;
94 }
95
96 // Overridden from views::BubbleBorder. 95 // Overridden from views::BubbleBorder.
97 // Override views::BubbleBorder to set the bubble on top of the anchor when 96 // Override views::BubbleBorder to set the bubble on top of the anchor when
98 // it has no arrow. 97 // it has no arrow.
99 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, 98 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
100 const gfx::Size& contents_size) const OVERRIDE { 99 const gfx::Size& contents_size) const OVERRIDE {
101 if (arrow_location() != NONE) { 100 if (arrow_location() != NONE) {
102 return views::BubbleBorder::GetBounds(position_relative_to, 101 return views::BubbleBorder::GetBounds(position_relative_to,
103 contents_size); 102 contents_size);
104 } 103 }
105 104
106 gfx::Size border_size(contents_size); 105 gfx::Size border_size(contents_size);
107 gfx::Insets insets; 106 gfx::Insets insets;
108 GetInsets(&insets); 107 GetInsets(&insets);
109 border_size.Enlarge(insets.width(), insets.height()); 108 border_size.Enlarge(insets.width(), insets.height());
110 109
111 const int kArrowOverlap = 3; 110 const int kArrowOverlap = 3;
112 int x = position_relative_to.x() + 111 int x = position_relative_to.x() +
113 position_relative_to.width() / 2 - border_size.width() / 2; 112 position_relative_to.width() / 2 - border_size.width() / 2;
114 // Position the bubble on top of the anchor. 113 // Position the bubble on top of the anchor.
115 int y = position_relative_to.y() + 114 int y = position_relative_to.y() +
116 kArrowOverlap - border_size.height(); 115 kArrowOverlap - border_size.height();
117 return gfx::Rect(x, y, border_size.width(), border_size.height()); 116 return gfx::Rect(x, y, border_size.width(), border_size.height());
118 } 117 }
119 118
120 // Overridden from views::Border. 119 // Overridden from views::Border.
121 virtual void Paint(const views::View& view, 120 virtual void Paint(const views::View& view,
122 gfx::Canvas* canvas) const OVERRIDE { 121 gfx::Canvas* canvas) const OVERRIDE {
123 gfx::Insets inset; 122 gfx::Insets inset;
124 GetInsets(&inset); 123 // Get the unmirrored insets for the arrow location.
124 GetInsetsForArrowLocation(&inset, arrow_location());
125 DrawBlurredShadowAroundView( 125 DrawBlurredShadowAroundView(
126 canvas, 0, owner_->height(), owner_->width(), inset); 126 canvas, 0, owner_->height(), owner_->width(), inset);
127 127
128 // Draw the bottom line. 128 // Draw the bottom line.
129 int y = owner_->height() + inset.top(); 129 int y = owner_->height() + inset.top();
130 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), 130 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(),
131 kBottomLineHeight), kBorderDarkColor); 131 kBottomLineHeight), kBorderDarkColor);
132 132
133 if (!Shell::GetInstance()->shelf()->IsVisible() || 133 if (!Shell::GetInstance()->shelf()->IsVisible() ||
134 arrow_location() == views::BubbleBorder::NONE) 134 arrow_location() == views::BubbleBorder::NONE)
135 return; 135 return;
136 136
137 gfx::Point arrow_reference; 137 gfx::Point arrow_reference;
138 138
139 // Draw the arrow after drawing child borders, so that the arrow can cover 139 // Draw the arrow after drawing child borders, so that the arrow can cover
msw 2012/07/24 00:32:43 This should be calling the default implementation
140 // the its overlap section with child border. 140 // the its overlap section with child border.
msw 2012/07/24 00:32:44 grammar nit: "the its"
stevenjb 2012/07/26 23:48:30 Done.
141 SkPath path; 141 SkPath path;
142 path.incReserve(4); 142 path.incReserve(4);
143 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT || 143 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT ||
144 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) { 144 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) {
145 // Do not let the arrow too close to the edge of the bubble and 145 // Note: tray_arrow_offset_ is relative to the anchor widget.
146 // and the edge of the anchor. 146 int tip_x;
147 int tip_x = base::i18n::IsRTL() ? 147 if (tray_arrow_offset_ ==
148 std::min(std::max(tray_arrow_offset_, kArrowMinOffset), 148 internal::TrayBubbleView::InitParams::kArrowDefaultOffset) {
149 std::min(owner_->width(), anchor_->width()) 149 if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT)
150 - kArrowMinOffset) : 150 tip_x = kArrowMinOffset;
151 std::min(std::max(owner_->width() - tray_arrow_offset_, 151 else
152 owner_->width() - 152 tip_x = owner_->width() - kArrowMinOffset;
153 std::min(owner_->width(), anchor_->width()) + 153 } else {
154 kArrowMinOffset), 154 gfx::Point pt(tray_arrow_offset_, 0);
155 owner_->width() - kArrowMinOffset); 155 views::View::ConvertPointToScreen(
156 anchor_->GetWidget()->GetRootView(), &pt);
157 views::View::ConvertPointFromScreen(
158 owner_->GetWidget()->GetRootView(), &pt);
159 tip_x = std::min(pt.x(), owner_->width() - kArrowMinOffset);
160 tip_x = std::max(tip_x, kArrowMinOffset);
161 }
156 int left_base_x = tip_x - kArrowWidth / 2; 162 int left_base_x = tip_x - kArrowWidth / 2;
157 int left_base_y = y; 163 int left_base_y = y;
158 int tip_y = left_base_y + kArrowHeight; 164 int tip_y = left_base_y + kArrowHeight;
159 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); 165 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y));
160 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); 166 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
161 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), 167 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth),
162 SkIntToScalar(left_base_y)); 168 SkIntToScalar(left_base_y));
163 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight); 169 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight);
164 } else { 170 } else {
165 int tip_y = y - tray_arrow_offset_; 171 int tip_y;
166 tip_y = std::min(std::max(kArrowMinOffset, tip_y), 172 if (tray_arrow_offset_ ==
167 owner_->height() - kArrowMinOffset); 173 internal::TrayBubbleView::InitParams::kArrowDefaultOffset) {
174 tip_y = owner_->height() - kArrowMinOffset;
175 } else {
176 int pty = y - tray_arrow_offset_;
177 gfx::Point pt(0, pty);
178 views::View::ConvertPointToScreen(
179 anchor_->GetWidget()->GetRootView(), &pt);
180 views::View::ConvertPointFromScreen(
181 owner_->GetWidget()->GetRootView(), &pt);
182 tip_y = std::min(pt.y(), owner_->height() - kArrowMinOffset);
183 tip_y = std::max(tip_y, kArrowMinOffset);
184 }
168 int top_base_y = tip_y - kArrowWidth / 2; 185 int top_base_y = tip_y - kArrowWidth / 2;
169 int top_base_x, tip_x; 186 int top_base_x, tip_x;
170 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { 187 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) {
171 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; 188 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset;
172 tip_x = top_base_x - kArrowHeight; 189 tip_x = top_base_x - kArrowHeight;
173 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y); 190 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y);
174 } else { 191 } else {
175 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM); 192 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM);
176 top_base_x = inset.left() + owner_->width() - 193 top_base_x = inset.left() + owner_->width() -
177 kSystemTrayBubbleHorizontalInset; 194 kSystemTrayBubbleHorizontalInset;
(...skipping 14 matching lines...) Expand all
192 paint.setColor(background ? background->get_color() : kBackgroundColor); 209 paint.setColor(background ? background->get_color() : kBackgroundColor);
193 canvas->DrawPath(path, paint); 210 canvas->DrawPath(path, paint);
194 211
195 // Now draw the arrow border. 212 // Now draw the arrow border.
196 paint.setStyle(SkPaint::kStroke_Style); 213 paint.setStyle(SkPaint::kStroke_Style);
197 paint.setColor(kBorderDarkColor); 214 paint.setColor(kBorderDarkColor);
198 canvas->DrawPath(path, paint); 215 canvas->DrawPath(path, paint);
199 216
200 } 217 }
201 218
219 private:
220 views::Background* FindAppropriateBackground(views::View* view,
221 const gfx::Point& point) const {
222 views::Background* background = NULL;
223 views::View* target = view->GetEventHandlerForPoint(point);
224 for (; target && !background; target = target->parent())
225 background = target->background();
226 return background;
227 }
228
202 views::View* owner_; 229 views::View* owner_;
203 views::View* anchor_; 230 views::View* anchor_;
204 const int tray_arrow_offset_; 231 const int tray_arrow_offset_;
205 232
206 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); 233 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder);
207 }; 234 };
208 235
209 } // namespace 236 } // namespace
210 237
211 namespace internal { 238 namespace internal {
212 239
240 // static
241 const int TrayBubbleView::InitParams::kArrowDefaultOffset = -1;
242
243 TrayBubbleView::InitParams::InitParams(AnchorType anchor_type,
244 ShelfAlignment shelf_alignment)
245 : anchor_type(anchor_type),
246 shelf_alignment(shelf_alignment),
247 bubble_width(kTrayPopupWidth),
248 max_height(0),
249 can_activate(false),
250 arrow_offset(kArrowDefaultOffset) {
251 }
252
253 TrayBubbleView* TrayBubbleView::Create(views::View* anchor,
254 Host* host,
255 const InitParams& init_params) {
256 // Set arrow_location here so that it can be passed correctly to the
257 // BubbleView constructor.
258 views::BubbleBorder::ArrowLocation arrow_location;
259 if (init_params.anchor_type == ANCHOR_TYPE_TRAY) {
260 if (init_params.shelf_alignment == SHELF_ALIGNMENT_BOTTOM) {
261 arrow_location = base::i18n::IsRTL() ?
262 views::BubbleBorder::BOTTOM_LEFT : views::BubbleBorder::BOTTOM_RIGHT;
263 } else if (init_params.shelf_alignment == SHELF_ALIGNMENT_LEFT) {
264 arrow_location = views::BubbleBorder::LEFT_BOTTOM;
265 } else {
266 arrow_location = views::BubbleBorder::RIGHT_BOTTOM;
267 }
268 } else {
269 arrow_location = views::BubbleBorder::NONE;
270 }
271
272 return new TrayBubbleView(init_params, arrow_location, anchor, host);
273 }
274
213 TrayBubbleView::TrayBubbleView( 275 TrayBubbleView::TrayBubbleView(
276 const InitParams& init_params,
277 views::BubbleBorder::ArrowLocation arrow_location,
214 views::View* anchor, 278 views::View* anchor,
215 views::BubbleBorder::ArrowLocation arrow_location, 279 Host* host)
216 Host* host,
217 bool can_activate,
218 int bubble_width)
219 : views::BubbleDelegateView(anchor, arrow_location), 280 : views::BubbleDelegateView(anchor, arrow_location),
220 host_(host), 281 params_(init_params),
221 can_activate_(can_activate), 282 host_(host) {
222 max_height_(0),
223 bubble_width_(bubble_width) {
224 set_margins(gfx::Insets()); 283 set_margins(gfx::Insets());
225 set_parent_window(Shell::GetContainer( 284 set_parent_window(Shell::GetContainer(
226 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), 285 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
227 internal::kShellWindowId_SettingBubbleContainer)); 286 internal::kShellWindowId_SettingBubbleContainer));
228 set_notify_enter_exit_on_child(true); 287 set_notify_enter_exit_on_child(true);
229 SetPaintToLayer(true); 288 SetPaintToLayer(true);
230 SetFillsBoundsOpaquely(true); 289 SetFillsBoundsOpaquely(true);
231 } 290 }
232 291
233 TrayBubbleView::~TrayBubbleView() { 292 TrayBubbleView::~TrayBubbleView() {
234 // Inform host items (models) that their views are being destroyed. 293 // Inform host items (models) that their views are being destroyed.
235 if (host_) 294 if (host_)
236 host_->BubbleViewDestroyed(); 295 host_->BubbleViewDestroyed();
237 } 296 }
238 297
239 void TrayBubbleView::SetBubbleBorder(int arrow_offset) {
240 DCHECK(GetWidget());
241 TrayBubbleBorder* bubble_border = new TrayBubbleBorder(
242 this, anchor_view(), arrow_location(), arrow_offset);
243 GetBubbleFrameView()->SetBubbleBorder(bubble_border);
244 // Recalculate size with new border.
245 SizeToContents();
246 }
247
248 void TrayBubbleView::UpdateAnchor() { 298 void TrayBubbleView::UpdateAnchor() {
249 SizeToContents(); 299 SizeToContents();
250 GetWidget()->GetRootView()->SchedulePaint(); 300 GetWidget()->GetRootView()->SchedulePaint();
251 } 301 }
252 302
253 void TrayBubbleView::SetMaxHeight(int height) { 303 void TrayBubbleView::SetMaxHeight(int height) {
254 max_height_ = height; 304 params_.max_height = height;
255 if (GetWidget()) 305 if (GetWidget())
256 SizeToContents(); 306 SizeToContents();
257 } 307 }
258 308
259 void TrayBubbleView::Init() { 309 void TrayBubbleView::Init() {
260 views::BoxLayout* layout = 310 views::BoxLayout* layout =
261 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); 311 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
262 layout->set_spread_blank_space(true); 312 layout->set_spread_blank_space(true);
263 SetLayoutManager(layout); 313 SetLayoutManager(layout);
264 set_background(NULL); 314 set_background(NULL);
265 } 315 }
266 316
267 gfx::Rect TrayBubbleView::GetAnchorRect() { 317 gfx::Rect TrayBubbleView::GetAnchorRect() {
268 gfx::Rect rect; 318 gfx::Rect rect;
269 if (host_) 319
270 rect = host_->GetAnchorRect(); 320 if (anchor_widget()->IsVisible()) {
321 rect = anchor_widget()->GetWindowBoundsInScreen();
322 if (params_.anchor_type == ANCHOR_TYPE_TRAY) {
323 if (params_.shelf_alignment == SHELF_ALIGNMENT_BOTTOM) {
324 bool rtl = base::i18n::IsRTL();
325 rect.Inset(
326 rtl ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0,
327 0,
328 rtl ? 0 : kPaddingFromRightEdgeOfScreenBottomAlignment,
329 kPaddingFromBottomOfScreenBottomAlignment);
330 } else if (params_.shelf_alignment == SHELF_ALIGNMENT_LEFT) {
331 rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
332 kPaddingFromBottomOfScreenVerticalAlignment);
333 } else {
334 rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
335 0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
336 }
337 } else if (params_.anchor_type == ANCHOR_TYPE_BUBBLE) {
338 // Invert the offsets to align with the bubble below.
339 if (params_.shelf_alignment == SHELF_ALIGNMENT_LEFT) {
340 rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
341 0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
342 } else if (params_.shelf_alignment == SHELF_ALIGNMENT_RIGHT) {
343 rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
344 kPaddingFromBottomOfScreenVerticalAlignment);
345 }
346 }
347 }
348
271 // TODO(jennyz): May need to add left/right alignment in the following code. 349 // TODO(jennyz): May need to add left/right alignment in the following code.
272 if (rect.IsEmpty()) { 350 if (rect.IsEmpty()) {
273 rect = gfx::Screen::GetPrimaryDisplay().bounds(); 351 rect = gfx::Screen::GetPrimaryDisplay().bounds();
274 rect = gfx::Rect( 352 rect = gfx::Rect(
275 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment : 353 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment :
276 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, 354 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
277 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, 355 rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
278 0, 0); 356 0, 0);
279 } 357 }
280 return rect; 358 return rect;
281 } 359 }
282 360
283 gfx::Rect TrayBubbleView::GetBubbleBounds() { 361 gfx::Rect TrayBubbleView::GetBubbleBounds() {
284 // Same as BubbleDelegateView implementation, but don't try mirroring. 362 // Same as BubbleDelegateView implementation, but don't try mirroring.
285 return GetBubbleFrameView()->GetUpdatedWindowBounds( 363 return GetBubbleFrameView()->GetUpdatedWindowBounds(
286 GetAnchorRect(), GetPreferredSize(), false /*try_mirroring_arrow*/); 364 GetAnchorRect(), GetPreferredSize(), false /*try_mirroring_arrow*/);
287 } 365 }
288 366
289 bool TrayBubbleView::CanActivate() const { 367 bool TrayBubbleView::CanActivate() const {
290 return can_activate_; 368 return params_.can_activate;
369 }
370
371 // Overridden to create BubbleFrameView and set the border to TrayBubbleBorder
372 // (instead of creating a default BubbleBorder and replacing it).
373 views::NonClientFrameView* TrayBubbleView::CreateNonClientFrameView(
374 views::Widget* widget) {
375 views::BubbleFrameView* bubble_frame_view =
msw 2012/07/23 22:20:49 Instead of changing the BubbleFrameView constructi
stevenjb 2012/07/23 23:32:06 The problem was that first a BubbleBorder() was ge
msw 2012/07/24 00:32:44 Ah, that's fair. Consider passing a BubbleBorder i
stevenjb 2012/07/26 23:48:30 Done.
376 new views::BubbleFrameView(margins());
377 TrayBubbleBorder* bubble_border = new TrayBubbleBorder(
378 this, anchor_view(), arrow_location(), params_.arrow_offset);
379 bubble_frame_view->SetBubbleBorder(bubble_border);
380 return bubble_frame_view;
291 } 381 }
292 382
293 gfx::Size TrayBubbleView::GetPreferredSize() { 383 gfx::Size TrayBubbleView::GetPreferredSize() {
294 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 384 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
295 int height = size.height(); 385 int height = size.height();
296 if (max_height_ != 0 && height > max_height_) 386 if (params_.max_height != 0 && height > params_.max_height)
297 height = max_height_; 387 height = params_.max_height;
298 return gfx::Size(bubble_width_, height); 388 return gfx::Size(params_.bubble_width, height);
299 } 389 }
300 390
301 void TrayBubbleView::OnMouseEntered(const views::MouseEvent& event) { 391 void TrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
302 if (host_) 392 if (host_)
303 host_->OnMouseEnteredView(); 393 host_->OnMouseEnteredView();
304 } 394 }
305 395
306 void TrayBubbleView::OnMouseExited(const views::MouseEvent& event) { 396 void TrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
307 if (host_) 397 if (host_)
308 host_->OnMouseExitedView(); 398 host_->OnMouseExitedView();
309 } 399 }
310 400
311 void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { 401 void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
312 if (can_activate_) { 402 if (params_.can_activate) {
313 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 403 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
314 state->name = l10n_util::GetStringUTF16( 404 state->name = l10n_util::GetStringUTF16(
315 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 405 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
316 } 406 }
317 } 407 }
318 408
319 void TrayBubbleView::ChildPreferredSizeChanged(View* child) { 409 void TrayBubbleView::ChildPreferredSizeChanged(View* child) {
320 SizeToContents(); 410 SizeToContents();
321 } 411 }
322 412
(...skipping 10 matching lines...) Expand all
333 TrayBubbleView::Host::Host() 423 TrayBubbleView::Host::Host()
334 : widget_(NULL), 424 : widget_(NULL),
335 tray_view_(NULL) { 425 tray_view_(NULL) {
336 Shell::GetInstance()->AddEnvEventFilter(this); 426 Shell::GetInstance()->AddEnvEventFilter(this);
337 } 427 }
338 428
339 TrayBubbleView::Host::~Host() { 429 TrayBubbleView::Host::~Host() {
340 Shell::GetInstance()->RemoveEnvEventFilter(this); 430 Shell::GetInstance()->RemoveEnvEventFilter(this);
341 } 431 }
342 432
343 void TrayBubbleView::Host::InitializeHost(views::Widget* widget, 433 void TrayBubbleView::Host::PostCreateBubble(views::Widget* widget,
344 views::View* tray_view) { 434 TrayBubbleView* bubble_view,
435 views::View* tray_view) {
345 widget_ = widget; 436 widget_ = widget;
346 tray_view_ = tray_view; 437 tray_view_ = tray_view;
438
439 // Must occur after call to BubbleDelegateView::CreateBubble().
440 bubble_view->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
441
442 // Setup animation.
443 ash::SetWindowVisibilityAnimationType(
444 widget->GetNativeWindow(),
445 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
446 ash::SetWindowVisibilityAnimationTransition(
447 widget->GetNativeWindow(),
448 ash::ANIMATE_BOTH);
449 ash::SetWindowVisibilityAnimationDuration(
450 widget->GetNativeWindow(),
451 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
347 } 452 }
348 453
349 bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target, 454 bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target,
350 aura::KeyEvent* event) { 455 aura::KeyEvent* event) {
351 return false; 456 return false;
352 } 457 }
353 458
354 bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target, 459 bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target,
355 aura::MouseEvent* event) { 460 aura::MouseEvent* event) {
356 if (event->type() == ui::ET_MOUSE_PRESSED) 461 if (event->type() == ui::ET_MOUSE_PRESSED)
(...skipping 30 matching lines...) Expand all
387 return; 492 return;
388 } 493 }
389 // Handle clicking outside the bubble and tray. We don't block the event, so 494 // Handle clicking outside the bubble and tray. We don't block the event, so
390 // it will also be handled by whatever widget was clicked on. 495 // it will also be handled by whatever widget was clicked on.
391 OnClickedOutsideView(); 496 OnClickedOutsideView();
392 } 497 }
393 498
394 499
395 } // namespace internal 500 } // namespace internal
396 } // namespace ash 501 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698