OLD | NEW |
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/system/tray/system_tray_delegate.h" | 9 #include "ash/system/tray/system_tray_delegate.h" |
10 #include "ash/system/tray/system_tray_item.h" | 10 #include "ash/system/tray/system_tray_item.h" |
11 #include "ash/system/user/login_status.h" | 11 #include "ash/system/user/login_status.h" |
12 #include "ash/wm/shadow_types.h" | 12 #include "ash/wm/shadow_types.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "third_party/skia/include/core/SkCanvas.h" |
15 #include "third_party/skia/include/core/SkColor.h" | 16 #include "third_party/skia/include/core/SkColor.h" |
| 17 #include "third_party/skia/include/core/SkPaint.h" |
| 18 #include "third_party/skia/include/core/SkPath.h" |
| 19 #include "ui/gfx/canvas.h" |
16 #include "ui/views/border.h" | 20 #include "ui/views/border.h" |
17 #include "ui/views/bubble/bubble_delegate.h" | 21 #include "ui/views/bubble/bubble_delegate.h" |
18 #include "ui/views/controls/label.h" | 22 #include "ui/views/controls/label.h" |
19 #include "ui/views/layout/box_layout.h" | 23 #include "ui/views/layout/box_layout.h" |
20 #include "ui/views/view.h" | 24 #include "ui/views/view.h" |
21 | 25 |
22 namespace { | 26 namespace { |
23 | 27 |
24 const int kTrayIconHeight = 50; | 28 const int kArrowHeight = 10; |
25 const int kPadding = 5; | 29 const int kArrowWidth = 20; |
| 30 const int kArrowPaddingFromRight = 20; |
| 31 |
| 32 const int kShadowOffset = 3; |
| 33 const int kShadowHeight = 3; |
| 34 |
| 35 const SkColor kDarkColor = SkColorSetRGB(120, 120, 120); |
| 36 const SkColor kLightColor = SkColorSetRGB(240, 240, 240); |
| 37 const SkColor kBackgroundColor = SK_ColorWHITE; |
| 38 const SkColor kShadowColor = SkColorSetARGB(25, 0, 0, 0); |
| 39 |
| 40 class SystemTrayBubbleBackground : public views::Background { |
| 41 public: |
| 42 explicit SystemTrayBubbleBackground(views::View* owner) |
| 43 : owner_(owner) { |
| 44 } |
| 45 |
| 46 virtual ~SystemTrayBubbleBackground() {} |
| 47 |
| 48 private: |
| 49 // Overridden from views::Background. |
| 50 virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { |
| 51 views::View* last_view = NULL; |
| 52 for (int i = 0; i < owner_->child_count(); i++) { |
| 53 views::View* v = owner_->child_at(i); |
| 54 |
| 55 if (!v->background()) { |
| 56 canvas->FillRect(v->bounds(), kBackgroundColor); |
| 57 } else if (last_view) { |
| 58 canvas->FillRect(gfx::Rect(v->x() + kShadowOffset, v->y(), |
| 59 v->width() - kShadowOffset, kShadowHeight), |
| 60 kShadowColor); |
| 61 } |
| 62 |
| 63 if (!v->border()) { |
| 64 canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1), |
| 65 gfx::Point(v->x() + v->width() + 1, v->y() - 1), |
| 66 !last_view || last_view->border() ? kDarkColor : kLightColor); |
| 67 canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1), |
| 68 gfx::Point(v->x() - 1, v->y() + v->height() + 1), |
| 69 kDarkColor); |
| 70 canvas->DrawLine(gfx::Point(v->x() + v->width(), v->y() - 1), |
| 71 gfx::Point(v->x() + v->width(), v->y() + v->height() + 1), |
| 72 kDarkColor); |
| 73 } else if (last_view && !last_view->border()) { |
| 74 canvas->DrawLine(gfx::Point(v->x() - 1, v->y() - 1), |
| 75 gfx::Point(v->x() + v->width() + 1, v->y() - 1), |
| 76 kDarkColor); |
| 77 } |
| 78 |
| 79 last_view = v; |
| 80 } |
| 81 } |
| 82 |
| 83 views::View* owner_; |
| 84 |
| 85 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBackground); |
| 86 }; |
| 87 |
| 88 class SystemTrayBubbleBorder : public views::Border { |
| 89 public: |
| 90 explicit SystemTrayBubbleBorder(views::View* owner) |
| 91 : owner_(owner) { |
| 92 } |
| 93 |
| 94 virtual ~SystemTrayBubbleBorder() {} |
| 95 |
| 96 private: |
| 97 // Overridden from views::Border. |
| 98 virtual void Paint(const views::View& view, |
| 99 gfx::Canvas* canvas) const OVERRIDE { |
| 100 // Draw a line first. |
| 101 int x = 4; |
| 102 int y = owner_->height() + 1; |
| 103 canvas->DrawLine(gfx::Point(x, y), |
| 104 gfx::Point(owner_->width() + x, y), |
| 105 kDarkColor); |
| 106 |
| 107 // Now, draw a shadow. |
| 108 canvas->FillRect(gfx::Rect(x + kShadowOffset, y, |
| 109 owner_->width() - kShadowOffset, kShadowHeight), |
| 110 kShadowColor); |
| 111 |
| 112 // Draw the arrow. |
| 113 int left_base_x = owner_->width() - kArrowPaddingFromRight - kArrowWidth; |
| 114 int left_base_y = y; |
| 115 int tip_x = left_base_x + kArrowWidth / 2; |
| 116 int tip_y = left_base_y + kArrowHeight; |
| 117 SkPath path; |
| 118 path.incReserve(4); |
| 119 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); |
| 120 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
| 121 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), |
| 122 SkIntToScalar(left_base_y)); |
| 123 |
| 124 SkPaint paint; |
| 125 paint.setStyle(SkPaint::kFill_Style); |
| 126 paint.setColor(kBackgroundColor); |
| 127 canvas->GetSkCanvas()->drawPath(path, paint); |
| 128 |
| 129 // Now the draw the outline. |
| 130 paint.setStyle(SkPaint::kStroke_Style); |
| 131 paint.setColor(kDarkColor); |
| 132 canvas->GetSkCanvas()->drawPath(path, paint); |
| 133 } |
| 134 |
| 135 virtual void GetInsets(gfx::Insets* insets) const OVERRIDE { |
| 136 insets->Set(0, 0, kArrowHeight, 0); |
| 137 } |
| 138 |
| 139 views::View* owner_; |
| 140 |
| 141 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBorder); |
| 142 }; |
26 | 143 |
27 class SystemTrayBubble : public views::BubbleDelegateView { | 144 class SystemTrayBubble : public views::BubbleDelegateView { |
28 public: | 145 public: |
29 SystemTrayBubble(ash::SystemTray* tray, | 146 SystemTrayBubble(ash::SystemTray* tray, |
30 std::vector<ash::SystemTrayItem*>& items, | 147 std::vector<ash::SystemTrayItem*>& items, |
31 bool detailed) | 148 bool detailed) |
32 : views::BubbleDelegateView(tray, views::BubbleBorder::BOTTOM_RIGHT), | 149 : views::BubbleDelegateView(tray, views::BubbleBorder::BOTTOM_RIGHT), |
33 tray_(tray), | 150 tray_(tray), |
34 items_(items), | 151 items_(items), |
35 detailed_(detailed) { | 152 detailed_(detailed) { |
36 set_margin(0); | 153 set_margin(0); |
37 } | 154 } |
38 | 155 |
39 virtual ~SystemTrayBubble() { | 156 virtual ~SystemTrayBubble() { |
40 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); | 157 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); |
41 it != items_.end(); | 158 it != items_.end(); |
42 ++it) { | 159 ++it) { |
43 if (detailed_) | 160 if (detailed_) |
44 (*it)->DestroyDetailedView(); | 161 (*it)->DestroyDetailedView(); |
45 else | 162 else |
46 (*it)->DestroyDefaultView(); | 163 (*it)->DestroyDefaultView(); |
47 } | 164 } |
48 } | 165 } |
49 | 166 |
50 private: | 167 private: |
51 // Overridden from views::BubbleDelegateView. | 168 // Overridden from views::BubbleDelegateView. |
52 virtual void Init() OVERRIDE { | 169 virtual void Init() OVERRIDE { |
53 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, | 170 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, |
54 0, 0, 1)); | 171 1, 1, 1)); |
| 172 set_background(new SystemTrayBubbleBackground(this)); |
55 | 173 |
56 ash::SystemTrayDelegate* delegate = | 174 ash::SystemTrayDelegate* delegate = |
57 ash::Shell::GetInstance()->tray_delegate(); | 175 ash::Shell::GetInstance()->tray_delegate(); |
58 ash::user::LoginStatus login_status = delegate->GetUserLoginStatus(); | 176 ash::user::LoginStatus login_status = delegate->GetUserLoginStatus(); |
59 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); | 177 for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin(); |
60 it != items_.end(); | 178 it != items_.end(); |
61 ++it) { | 179 ++it) { |
62 views::View* view = detailed_ ? (*it)->CreateDetailedView(login_status) : | 180 views::View* view = detailed_ ? (*it)->CreateDetailedView(login_status) : |
63 (*it)->CreateDefaultView(login_status); | 181 (*it)->CreateDefaultView(login_status); |
64 if (!view) | 182 if (view) |
65 continue; | 183 AddChildView(view); |
66 if (it != items_.begin()) | |
67 view->set_border(views::Border::CreateSolidSidedBorder( | |
68 1, 0, 0, 0, SkColorSetARGB(25, 0, 0, 0))); | |
69 AddChildView(view); | |
70 } | 184 } |
71 } | 185 } |
72 | 186 |
73 ash::SystemTray* tray_; | 187 ash::SystemTray* tray_; |
74 std::vector<ash::SystemTrayItem*> items_; | 188 std::vector<ash::SystemTrayItem*> items_; |
75 bool detailed_; | 189 bool detailed_; |
76 | 190 |
77 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble); | 191 DISALLOW_COPY_AND_ASSIGN(SystemTrayBubble); |
78 }; | 192 }; |
79 | 193 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 if (view) | 257 if (view) |
144 AddChildViewAt(view, 0); | 258 AddChildViewAt(view, 0); |
145 } | 259 } |
146 PreferredSizeChanged(); | 260 PreferredSizeChanged(); |
147 } | 261 } |
148 | 262 |
149 void SystemTray::ShowItems(std::vector<SystemTrayItem*>& items, bool detailed) { | 263 void SystemTray::ShowItems(std::vector<SystemTrayItem*>& items, bool detailed) { |
150 CHECK(!popup_); | 264 CHECK(!popup_); |
151 SystemTrayBubble* bubble = new SystemTrayBubble(this, items, detailed); | 265 SystemTrayBubble* bubble = new SystemTrayBubble(this, items, detailed); |
152 popup_ = views::BubbleDelegateView::CreateBubble(bubble); | 266 popup_ = views::BubbleDelegateView::CreateBubble(bubble); |
| 267 popup_->non_client_view()->frame_view()->set_background(NULL); |
| 268 popup_->non_client_view()->frame_view()->set_border( |
| 269 new SystemTrayBubbleBorder(bubble)); |
153 popup_->AddObserver(this); | 270 popup_->AddObserver(this); |
154 bubble->Show(); | 271 bubble->Show(); |
155 } | 272 } |
156 | 273 |
157 bool SystemTray::OnMousePressed(const views::MouseEvent& event) { | 274 bool SystemTray::OnMousePressed(const views::MouseEvent& event) { |
158 if (popup_) | 275 if (popup_) |
159 popup_->Show(); | 276 popup_->Show(); |
160 else | 277 else |
161 ShowItems(items_, false); | 278 ShowItems(items_, false); |
162 return true; | 279 return true; |
163 } | 280 } |
164 | 281 |
165 void SystemTray::OnWidgetClosing(views::Widget* widget) { | 282 void SystemTray::OnWidgetClosing(views::Widget* widget) { |
166 CHECK_EQ(popup_, widget); | 283 CHECK_EQ(popup_, widget); |
167 popup_ = NULL; | 284 popup_ = NULL; |
168 } | 285 } |
169 | 286 |
170 } // namespace ash | 287 } // namespace ash |
OLD | NEW |