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

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

Issue 10378070: ash: Separate out SystemTrayBubble and related classes into a new file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years, 7 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 | « ash/ash.gyp ('k') | ash/system/tray/system_tray_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) 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/system_tray.h" 5 #include "ash/system/tray/system_tray.h"
6 6
7 #include "ash/shell.h" 7 #include "ash/shell.h"
8 #include "ash/shell/panel_window.h" 8 #include "ash/shell/panel_window.h"
9 #include "ash/shell_window_ids.h" 9 #include "ash/shell_window_ids.h"
10 #include "ash/system/audio/tray_volume.h" 10 #include "ash/system/audio/tray_volume.h"
11 #include "ash/system/bluetooth/tray_bluetooth.h" 11 #include "ash/system/bluetooth/tray_bluetooth.h"
12 #include "ash/system/brightness/tray_brightness.h" 12 #include "ash/system/brightness/tray_brightness.h"
13 #include "ash/system/date/tray_date.h" 13 #include "ash/system/date/tray_date.h"
14 #include "ash/system/drive/tray_drive.h" 14 #include "ash/system/drive/tray_drive.h"
15 #include "ash/system/ime/tray_ime.h" 15 #include "ash/system/ime/tray_ime.h"
16 #include "ash/system/network/tray_network.h" 16 #include "ash/system/network/tray_network.h"
17 #include "ash/system/power/power_status_observer.h" 17 #include "ash/system/power/power_status_observer.h"
18 #include "ash/system/power/power_supply_status.h" 18 #include "ash/system/power/power_supply_status.h"
19 #include "ash/system/power/tray_power.h" 19 #include "ash/system/power/tray_power.h"
20 #include "ash/system/settings/tray_settings.h" 20 #include "ash/system/settings/tray_settings.h"
21 #include "ash/system/tray/system_tray_bubble.h"
21 #include "ash/system/tray/system_tray_delegate.h" 22 #include "ash/system/tray/system_tray_delegate.h"
22 #include "ash/system/tray/system_tray_item.h" 23 #include "ash/system/tray/system_tray_item.h"
23 #include "ash/system/tray/system_tray_widget_delegate.h" 24 #include "ash/system/tray/system_tray_widget_delegate.h"
24 #include "ash/system/tray/tray_constants.h" 25 #include "ash/system/tray/tray_constants.h"
25 #include "ash/system/tray/tray_empty.h" 26 #include "ash/system/tray/tray_empty.h"
26 #include "ash/system/tray_accessibility.h" 27 #include "ash/system/tray_accessibility.h"
27 #include "ash/system/tray_caps_lock.h" 28 #include "ash/system/tray_caps_lock.h"
28 #include "ash/system/tray_update.h" 29 #include "ash/system/tray_update.h"
29 #include "ash/system/user/login_status.h" 30 #include "ash/system/user/login_status.h"
30 #include "ash/system/user/tray_user.h" 31 #include "ash/system/user/tray_user.h"
31 #include "ash/wm/shadow_types.h"
32 #include "ash/wm/shelf_layout_manager.h" 32 #include "ash/wm/shelf_layout_manager.h"
33 #include "ash/wm/window_animations.h"
34 #include "base/i18n/rtl.h" 33 #include "base/i18n/rtl.h"
35 #include "base/logging.h" 34 #include "base/logging.h"
36 #include "base/message_loop.h"
37 #include "base/message_pump_observer.h"
38 #include "base/timer.h" 35 #include "base/timer.h"
39 #include "base/utf_string_conversions.h" 36 #include "base/utf_string_conversions.h"
40 #include "grit/ash_strings.h" 37 #include "grit/ash_strings.h"
41 #include "third_party/skia/include/core/SkCanvas.h"
42 #include "third_party/skia/include/core/SkColor.h"
43 #include "third_party/skia/include/core/SkPaint.h"
44 #include "third_party/skia/include/core/SkPath.h"
45 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
46 #include "ui/aura/root_window.h" 38 #include "ui/aura/root_window.h"
47 #include "ui/base/accessibility/accessible_view_state.h" 39 #include "ui/base/accessibility/accessible_view_state.h"
48 #include "ui/base/events.h" 40 #include "ui/base/events.h"
49 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/l10n/l10n_util.h"
50 #include "ui/compositor/layer.h"
51 #include "ui/gfx/canvas.h" 42 #include "ui/gfx/canvas.h"
52 #include "ui/gfx/screen.h"
53 #include "ui/gfx/skia_util.h" 43 #include "ui/gfx/skia_util.h"
54 #include "ui/views/border.h" 44 #include "ui/views/border.h"
55 #include "ui/views/bubble/bubble_border.h"
56 #include "ui/views/bubble/bubble_delegate.h"
57 #include "ui/views/bubble/bubble_frame_view.h"
58 #include "ui/views/controls/label.h" 45 #include "ui/views/controls/label.h"
59 #include "ui/views/layout/box_layout.h" 46 #include "ui/views/layout/box_layout.h"
60 #include "ui/views/layout/fill_layout.h" 47 #include "ui/views/layout/fill_layout.h"
61 #include "ui/views/view.h" 48 #include "ui/views/view.h"
62 #include "ui/views/widget/widget.h" 49 #include "ui/views/widget/widget.h"
63 50
64 namespace ash { 51 namespace ash {
65 52
66 namespace { 53 namespace {
67 54
68 const int kPaddingFromRightEdgeOfScreen = 15;
69 const int kPaddingFromBottomOfScreen = 10;
70
71 const int kAnimationDurationForPopupMS = 200;
72
73 const int kArrowHeight = 10;
74 const int kArrowWidth = 20;
75 const int kArrowPaddingFromRight = 20;
76
77 const int kShadowThickness = 4;
78
79 const int kLeftPadding = 4;
80 const int kBottomLineHeight = 1;
81
82 const SkColor kShadowColor = SkColorSetARGB(0xff, 0, 0, 0);
83
84 const SkColor kTrayBackgroundAlpha = 100; 55 const SkColor kTrayBackgroundAlpha = 100;
85 const SkColor kTrayBackgroundHoverAlpha = 150; 56 const SkColor kTrayBackgroundHoverAlpha = 150;
86 57
87 void DrawBlurredShadowAroundView(gfx::Canvas* canvas,
88 int top,
89 int bottom,
90 int width,
91 const gfx::Insets& inset) {
92 SkPath path;
93 path.incReserve(4);
94 path.moveTo(SkIntToScalar(inset.left() + kShadowThickness),
95 SkIntToScalar(top + kShadowThickness + 1));
96 path.lineTo(SkIntToScalar(inset.left() + kShadowThickness),
97 SkIntToScalar(bottom));
98 path.lineTo(SkIntToScalar(width),
99 SkIntToScalar(bottom));
100 path.lineTo(SkIntToScalar(width),
101 SkIntToScalar(top + kShadowThickness + 1));
102
103 SkPaint paint;
104 paint.setColor(kShadowColor);
105 paint.setStyle(SkPaint::kStroke_Style);
106 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
107 paint.setStrokeWidth(SkIntToScalar(3));
108 paint.setImageFilter(new SkBlurImageFilter(
109 SkIntToScalar(3), SkIntToScalar(3)))->unref();
110 canvas->sk_canvas()->drawPath(path, paint);
111 }
112
113 // A view with some special behaviour for tray items in the popup:
114 // - changes background color on hover.
115 class TrayPopupItemContainer : public views::View {
116 public:
117 explicit TrayPopupItemContainer(views::View* view) : hover_(false) {
118 set_notify_enter_exit_on_child(true);
119 set_border(view->border() ? views::Border::CreateEmptyBorder(0, 0, 0, 0) :
120 NULL);
121 SetLayoutManager(new views::FillLayout);
122 SetPaintToLayer(view->layer() != NULL);
123 if (view->layer())
124 SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely());
125 AddChildView(view);
126 SetVisible(view->visible());
127 }
128
129 virtual ~TrayPopupItemContainer() {}
130
131 private:
132 // Overridden from views::View.
133 virtual void ChildVisibilityChanged(View* child) OVERRIDE {
134 if (visible() == child->visible())
135 return;
136 SetVisible(child->visible());
137 PreferredSizeChanged();
138 }
139
140 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE {
141 PreferredSizeChanged();
142 }
143
144 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE {
145 hover_ = true;
146 SchedulePaint();
147 }
148
149 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE {
150 hover_ = false;
151 SchedulePaint();
152 }
153
154 virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE {
155 if (child_count() == 0)
156 return;
157
158 views::View* view = child_at(0);
159 if (!view->background()) {
160 canvas->FillRect(gfx::Rect(size()),
161 hover_ ? kHoverBackgroundColor : kBackgroundColor);
162 }
163 }
164
165 bool hover_;
166
167 DISALLOW_COPY_AND_ASSIGN(TrayPopupItemContainer);
168 };
169
170 class SystemTrayBubbleBackground : public views::Background {
171 public:
172 explicit SystemTrayBubbleBackground(views::View* owner)
173 : owner_(owner) {
174 }
175
176 virtual ~SystemTrayBubbleBackground() {}
177
178 private:
179 // Overridden from views::Background.
180 virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE {
181 views::View* last_view = NULL;
182 for (int i = 0; i < owner_->child_count(); i++) {
183 views::View* v = owner_->child_at(i);
184
185 if (!v->border()) {
186 canvas->DrawLine(gfx::Point(v->x(), v->y() - 1),
187 gfx::Point(v->x() + v->width(), v->y() - 1),
188 !last_view || last_view->border() ? kBorderDarkColor :
189 kBorderLightColor);
190 canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1),
191 gfx::Point(v->x() - 1, v->y() + v->height() + 1),
192 kBorderDarkColor);
193 canvas->DrawLine(gfx::Point(v->x() + v->width(), v->y() - 1),
194 gfx::Point(v->x() + v->width(), v->y() + v->height() + 1),
195 kBorderDarkColor);
196 } else if (last_view && !last_view->border()) {
197 canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1),
198 gfx::Point(v->x() + v->width() + 1, v->y() - 1),
199 kBorderDarkColor);
200 }
201
202 last_view = v;
203 }
204 }
205
206 views::View* owner_;
207
208 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBackground);
209 };
210
211 class SystemTrayBubbleBorder : public views::BubbleBorder {
212 public:
213 enum ArrowType {
214 ARROW_TYPE_NONE,
215 ARROW_TYPE_BOTTOM,
216 };
217
218 SystemTrayBubbleBorder(views::View* owner, ArrowType arrow_type)
219 : views::BubbleBorder(views::BubbleBorder::BOTTOM_RIGHT,
220 views::BubbleBorder::NO_SHADOW),
221 owner_(owner),
222 arrow_type_(arrow_type) {
223 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
224 }
225
226 virtual ~SystemTrayBubbleBorder() {}
227
228 private:
229 // Overridden from views::Border.
230 virtual void Paint(const views::View& view,
231 gfx::Canvas* canvas) const OVERRIDE {
232 views::View* first = NULL, *last = NULL;
233 gfx::Insets inset;
234 GetInsets(&inset);
235 for (int i = 0; i < owner_->child_count(); i++) {
236 views::View* v = owner_->child_at(i);
237 if (v->border()) {
238 if (first) {
239 DrawBlurredShadowAroundView(canvas, first->y(),
240 last->y() + last->height(), owner_->width(), inset);
241 first = NULL;
242 last = NULL;
243 }
244 continue;
245 }
246
247 if (!first)
248 first = v;
249 last = v;
250 }
251 if (first) {
252 DrawBlurredShadowAroundView(canvas, first->y(),
253 last->y() + last->height(), owner_->width(), inset);
254 }
255
256 // Draw the bottom line.
257 int y = owner_->height() + 1;
258 canvas->FillRect(gfx::Rect(kLeftPadding, y, owner_->width(),
259 kBottomLineHeight), kBorderDarkColor);
260
261 if (!Shell::GetInstance()->shelf()->IsVisible())
262 return;
263
264 // Draw the arrow.
265 if (arrow_type_ == ARROW_TYPE_BOTTOM) {
266 int left_base_x = base::i18n::IsRTL() ? kArrowWidth :
267 owner_->width() - kArrowPaddingFromRight - kArrowWidth;
268 int left_base_y = y;
269 int tip_x = left_base_x + kArrowWidth / 2;
270 int tip_y = left_base_y + kArrowHeight;
271 SkPath path;
272 path.incReserve(4);
273 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y));
274 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
275 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth),
276 SkIntToScalar(left_base_y));
277
278 SkPaint paint;
279 paint.setStyle(SkPaint::kFill_Style);
280 paint.setColor(kBackgroundColor);
281 canvas->DrawPath(path, paint);
282
283 // Now draw the arrow border.
284 paint.setStyle(SkPaint::kStroke_Style);
285 paint.setColor(kBorderDarkColor);
286 canvas->DrawPath(path, paint);
287 }
288 }
289
290 views::View* owner_;
291 ArrowType arrow_type_;
292
293 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBorder);
294 };
295
296 } // namespace 58 } // namespace
297 59
298 namespace internal { 60 namespace internal {
299 61
300 class SystemTrayBackground : public views::Background { 62 class SystemTrayBackground : public views::Background {
301 public: 63 public:
302 SystemTrayBackground() : alpha_(kTrayBackgroundAlpha) {} 64 SystemTrayBackground() : alpha_(kTrayBackgroundAlpha) {}
303 virtual ~SystemTrayBackground() {} 65 virtual ~SystemTrayBackground() {}
304 66
305 void set_alpha(int alpha) { alpha_ = alpha; } 67 void set_alpha(int alpha) { alpha_ = alpha; }
(...skipping 10 matching lines...) Expand all
316 SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius); 78 SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius);
317 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); 79 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius);
318 canvas->DrawPath(path, paint); 80 canvas->DrawPath(path, paint);
319 } 81 }
320 82
321 int alpha_; 83 int alpha_;
322 84
323 DISALLOW_COPY_AND_ASSIGN(SystemTrayBackground); 85 DISALLOW_COPY_AND_ASSIGN(SystemTrayBackground);
324 }; 86 };
325 87
326 class SystemTrayBubble;
327
328 class SystemTrayBubbleView : public views::BubbleDelegateView {
329 public:
330 SystemTrayBubbleView(views::View* anchor,
331 SystemTrayBubble* host,
332 bool can_activate);
333 virtual ~SystemTrayBubbleView();
334
335 void SetBubbleBorder(views::BubbleBorder* border) {
336 GetBubbleFrameView()->SetBubbleBorder(border);
337 }
338
339 void UpdateAnchor() {
340 SizeToContents();
341 GetWidget()->GetRootView()->SchedulePaint();
342 }
343
344 // Called when the host is destroyed.
345 void reset_host() { host_ = NULL; }
346
347 private:
348 // Overridden from views::BubbleDelegateView.
349 virtual void Init() OVERRIDE;
350 virtual gfx::Rect GetAnchorRect() OVERRIDE;
351 // Overridden from views::View.
352 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
353 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
354 virtual bool CanActivate() const OVERRIDE;
355 virtual gfx::Size GetPreferredSize() OVERRIDE;
356 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
357 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
358
359 SystemTrayBubble* host_;
360 bool can_activate_;
361
362 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleView);
363 };
364
365 class SystemTrayBubble : public base::MessagePumpObserver,
366 public views::Widget::Observer {
367 public:
368 enum BubbleType {
369 BUBBLE_TYPE_DEFAULT,
370 BUBBLE_TYPE_DETAILED,
371 BUBBLE_TYPE_NOTIFICATION
372 };
373
374 enum AnchorType {
375 ANCHOR_TYPE_TRAY,
376 ANCHOR_TYPE_BUBBLE
377 };
378
379 SystemTrayBubble(ash::SystemTray* tray,
380 const std::vector<ash::SystemTrayItem*>& items,
381 BubbleType bubble_type);
382 virtual ~SystemTrayBubble();
383
384 // Creates |bubble_view_| and a child views for each member of |items_|.
385 // Also creates |bubble_widget_| and sets up animations.
386 void InitView(views::View* anchor,
387 AnchorType anchor_type,
388 bool can_activate,
389 ash::user::LoginStatus login_status);
390
391 gfx::Rect GetAnchorRect() const;
392
393 BubbleType bubble_type() const { return bubble_type_; }
394 SystemTrayBubbleView* bubble_view() const { return bubble_view_; }
395
396 void DestroyItemViews();
397 void StartAutoCloseTimer(int seconds);
398 void StopAutoCloseTimer();
399 void RestartAutoCloseTimer();
400 void Close();
401
402 private:
403 // Overridden from base::MessagePumpObserver.
404 virtual base::EventStatus WillProcessEvent(
405 const base::NativeEvent& event) OVERRIDE;
406 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
407 // Overridden from views::Widget::Observer.
408 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
409 virtual void OnWidgetVisibilityChanged(views::Widget* widget,
410 bool visible) OVERRIDE;
411
412 ash::SystemTray* tray_;
413 SystemTrayBubbleView* bubble_view_;
414 views::Widget* bubble_widget_;
415 std::vector<ash::SystemTrayItem*> items_;
416 BubbleType bubble_type_;
417 AnchorType anchor_type_;
418
419 int autoclose_delay_;
420 base::OneShotTimer<SystemTrayBubble> autoclose_;
421
422 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble);
423 };
424
425 // SystemTrayBubbleView
426
427 SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor,
428 SystemTrayBubble* host,
429 bool can_activate)
430 : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT),
431 host_(host),
432 can_activate_(can_activate) {
433 set_margin(0);
434 set_parent_window(ash::Shell::GetInstance()->GetContainer(
435 ash::internal::kShellWindowId_SettingBubbleContainer));
436 set_notify_enter_exit_on_child(true);
437 }
438
439 SystemTrayBubbleView::~SystemTrayBubbleView() {
440 // Inform host items (models) that their views are being destroyed.
441 if (host_)
442 host_->DestroyItemViews();
443 }
444
445 void SystemTrayBubbleView::Init() {
446 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1));
447 set_background(new SystemTrayBubbleBackground(this));
448 }
449
450 gfx::Rect SystemTrayBubbleView::GetAnchorRect() {
451 gfx::Rect rect;
452 if (host_)
453 rect = host_->GetAnchorRect();
454 if (rect.IsEmpty()) {
455 rect = gfx::Screen::GetPrimaryMonitor().bounds();
456 rect = gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen :
457 rect.width() - kPaddingFromRightEdgeOfScreen,
458 rect.height() - kPaddingFromBottomOfScreen,
459 0, 0);
460 }
461 return rect;
462 }
463
464 void SystemTrayBubbleView::ChildPreferredSizeChanged(View* child) {
465 SizeToContents();
466 }
467
468 void SystemTrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
469 if (can_activate_) {
470 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
471 state->name = l10n_util::GetStringUTF16(
472 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
473 }
474 }
475
476 bool SystemTrayBubbleView::CanActivate() const {
477 return can_activate_;
478 }
479
480 gfx::Size SystemTrayBubbleView::GetPreferredSize() {
481 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
482 return gfx::Size(kTrayPopupWidth, size.height());
483 }
484
485 void SystemTrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
486 if (host_)
487 host_->StopAutoCloseTimer();
488 }
489
490 void SystemTrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
491 if (host_)
492 host_->RestartAutoCloseTimer();
493 }
494
495 // SystemTrayBubble
496
497 SystemTrayBubble::SystemTrayBubble(
498 ash::SystemTray* tray,
499 const std::vector<ash::SystemTrayItem*>& items,
500 BubbleType bubble_type)
501 : tray_(tray),
502 bubble_view_(NULL),
503 bubble_widget_(NULL),
504 items_(items),
505 bubble_type_(bubble_type),
506 anchor_type_(ANCHOR_TYPE_TRAY),
507 autoclose_delay_(0) {
508 }
509
510 SystemTrayBubble::~SystemTrayBubble() {
511 // The bubble may be closing without having been hidden first. So it may still
512 // be in the message-loop's observer list.
513 MessageLoopForUI::current()->RemoveObserver(this);
514
515 DestroyItemViews();
516 // Reset the host pointer in bubble_view_ in case its destruction is deferred.
517 if (bubble_view_)
518 bubble_view_->reset_host();
519 if (bubble_widget_) {
520 bubble_widget_->RemoveObserver(this);
521 // This triggers the destruction of bubble_view_.
522 bubble_widget_->Close();
523 }
524 }
525
526 void SystemTrayBubble::InitView(views::View* anchor,
527 AnchorType anchor_type,
528 bool can_activate,
529 ash::user::LoginStatus login_status) {
530 DCHECK(bubble_view_ == NULL);
531 anchor_type_ = anchor_type;
532 bubble_view_ = new SystemTrayBubbleView(anchor, this, can_activate);
533
534 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
535 it != items_.end();
536 ++it) {
537 views::View* view = NULL;
538 switch (bubble_type_) {
539 case BUBBLE_TYPE_DEFAULT:
540 view = (*it)->CreateDefaultView(login_status);
541 break;
542 case BUBBLE_TYPE_DETAILED:
543 view = (*it)->CreateDetailedView(login_status);
544 break;
545 case BUBBLE_TYPE_NOTIFICATION:
546 view = (*it)->CreateNotificationView(login_status);
547 break;
548 }
549 if (view)
550 bubble_view_->AddChildView(new TrayPopupItemContainer(view));
551 }
552
553 DCHECK(bubble_widget_ == NULL);
554 bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
555
556 // Must occur after call to CreateBubble()
557 bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
558 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
559 SystemTrayBubbleBorder::ArrowType arrow_type;
560 if (anchor_type_ == ANCHOR_TYPE_TRAY)
561 arrow_type = SystemTrayBubbleBorder::ARROW_TYPE_BOTTOM;
562 else
563 arrow_type = SystemTrayBubbleBorder::ARROW_TYPE_NONE;
564 bubble_view_->SetBubbleBorder(
565 new SystemTrayBubbleBorder(bubble_view_, arrow_type));
566
567 bubble_widget_->AddObserver(this);
568
569 // Setup animation.
570 ash::SetWindowVisibilityAnimationType(
571 bubble_widget_->GetNativeWindow(),
572 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
573 ash::SetWindowVisibilityAnimationTransition(
574 bubble_widget_->GetNativeWindow(),
575 ash::ANIMATE_BOTH);
576 ash::SetWindowVisibilityAnimationDuration(
577 bubble_widget_->GetNativeWindow(),
578 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
579
580 bubble_view_->Show();
581 }
582
583 gfx::Rect SystemTrayBubble::GetAnchorRect() const {
584 gfx::Rect rect;
585 views::Widget* widget = bubble_view()->anchor_widget();
586 if (widget->IsVisible()) {
587 rect = widget->GetWindowScreenBounds();
588 if (anchor_type_ == ANCHOR_TYPE_TRAY) {
589 rect.Inset(
590 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0,
591 0,
592 base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen,
593 kPaddingFromBottomOfScreen);
594 } else if (anchor_type_ == ANCHOR_TYPE_BUBBLE) {
595 rect.Inset(
596 base::i18n::IsRTL() ? kShadowThickness - 1 : 0,
597 0,
598 base::i18n::IsRTL() ? 0 : kShadowThickness - 1,
599 0);
600 }
601 }
602 return rect;
603 }
604
605 void SystemTrayBubble::DestroyItemViews() {
606 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
607 it != items_.end();
608 ++it) {
609 switch (bubble_type_) {
610 case BUBBLE_TYPE_DEFAULT:
611 (*it)->DestroyDefaultView();
612 break;
613 case BUBBLE_TYPE_DETAILED:
614 (*it)->DestroyDetailedView();
615 break;
616 case BUBBLE_TYPE_NOTIFICATION:
617 (*it)->DestroyNotificationView();
618 break;
619 }
620 }
621 }
622
623 void SystemTrayBubble::StartAutoCloseTimer(int seconds) {
624 autoclose_.Stop();
625 autoclose_delay_ = seconds;
626 if (autoclose_delay_) {
627 autoclose_.Start(FROM_HERE,
628 base::TimeDelta::FromSeconds(autoclose_delay_),
629 this, &SystemTrayBubble::Close);
630 }
631 }
632
633 void SystemTrayBubble::StopAutoCloseTimer() {
634 autoclose_.Stop();
635 }
636
637 void SystemTrayBubble::RestartAutoCloseTimer() {
638 if (autoclose_delay_)
639 StartAutoCloseTimer(autoclose_delay_);
640 }
641
642 void SystemTrayBubble::Close() {
643 if (bubble_widget_)
644 bubble_widget_->Close();
645 }
646
647 base::EventStatus SystemTrayBubble::WillProcessEvent(
648 const base::NativeEvent& event) {
649 // Check if the user clicked outside of the bubble and close it if they did.
650 if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION &&
651 ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) {
652 gfx::Point cursor_in_view = ui::EventLocationFromNative(event);
653 views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view);
654 if (!bubble_view_->HitTest(cursor_in_view)) {
655 bubble_widget_->Close();
656 }
657 }
658 return base::EVENT_CONTINUE;
659 }
660
661 void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) {
662 }
663
664 void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) {
665 CHECK_EQ(bubble_widget_, widget);
666 MessageLoopForUI::current()->RemoveObserver(this);
667 bubble_widget_ = NULL;
668 tray_->RemoveBubble(this);
669 }
670
671 void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget,
672 bool visible) {
673 if (!visible)
674 MessageLoopForUI::current()->RemoveObserver(this);
675 else
676 MessageLoopForUI::current()->AddObserver(this);
677 }
678
679 // Observe the tray layer animation and update the anchor when it changes. 88 // Observe the tray layer animation and update the anchor when it changes.
680 // TODO(stevenjb): Observe or mirror the actual animation, not just the start 89 // TODO(stevenjb): Observe or mirror the actual animation, not just the start
681 // and end points. 90 // and end points.
682 class SystemTrayLayerAnimationObserver : public ui::LayerAnimationObserver { 91 class SystemTrayLayerAnimationObserver : public ui::LayerAnimationObserver {
683 public: 92 public:
684 explicit SystemTrayLayerAnimationObserver(SystemTray* host) : host_(host) {} 93 explicit SystemTrayLayerAnimationObserver(SystemTray* host) : host_(host) {}
685 94
686 virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) { 95 virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) {
687 host_->UpdateNotificationAnchor(); 96 host_->UpdateNotificationAnchor();
688 } 97 }
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 canvas->DrawFocusRect(tray_container_->bounds()); 436 canvas->DrawFocusRect(tray_container_->bounds());
1028 } 437 }
1029 438
1030 void SystemTray::UpdateBackground(int alpha) { 439 void SystemTray::UpdateBackground(int alpha) {
1031 background_->set_alpha(hide_background_animator_.alpha() + 440 background_->set_alpha(hide_background_animator_.alpha() +
1032 hover_background_animator_.alpha()); 441 hover_background_animator_.alpha());
1033 SchedulePaint(); 442 SchedulePaint();
1034 } 443 }
1035 444
1036 } // namespace ash 445 } // namespace ash
OLDNEW
« no previous file with comments | « ash/ash.gyp ('k') | ash/system/tray/system_tray_bubble.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698