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/network/tray_network.h" | 5 #include "ash/system/network/tray_network.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/system/tray/system_tray.h" | |
9 #include "ash/system/tray/system_tray_delegate.h" | 8 #include "ash/system/tray/system_tray_delegate.h" |
10 #include "base/utf_string_conversions.h" | |
11 #include "grit/ash_strings.h" | |
12 #include "grit/ui_resources.h" | |
13 #include "ui/base/resource/resource_bundle.h" | |
14 #include "ui/gfx/font.h" | |
15 #include "ui/gfx/image/image.h" | |
16 #include "ui/views/controls/image_view.h" | 9 #include "ui/views/controls/image_view.h" |
17 #include "ui/views/controls/label.h" | 10 #include "ui/views/controls/label.h" |
18 #include "ui/views/controls/scroll_view.h" | |
19 #include "ui/views/layout/fill_layout.h" | 11 #include "ui/views/layout/fill_layout.h" |
20 #include "ui/views/layout/box_layout.h" | 12 #include "ui/views/layout/box_layout.h" |
21 #include "ui/views/view.h" | 13 #include "ui/views/view.h" |
22 #include "ui/views/widget/widget.h" | |
23 | |
24 namespace { | |
25 | |
26 // Width of the icon, and the padding on the right of the icon. These are used | |
27 // to make sure that all icons are of the same size so that they line up | |
28 // properly, including the items that don't have any icons. | |
29 const int kIconWidth = 27; | |
30 const int kIconPaddingLeft = 5; | |
31 | |
32 // Height of the list of networks in the popup. | |
33 const int kNetworkListHeight = 160; | |
34 | |
35 // An image view with that always has a fixed width (kIconWidth) so that | |
36 // all the items line up properly. | |
37 class FixedWidthImageView : public views::ImageView { | |
38 public: | |
39 FixedWidthImageView() { | |
40 SetHorizontalAlignment(views::ImageView::CENTER); | |
41 SetVerticalAlignment(views::ImageView::CENTER); | |
42 } | |
43 | |
44 virtual ~FixedWidthImageView() {} | |
45 | |
46 private: | |
47 virtual gfx::Size GetPreferredSize() OVERRIDE { | |
48 gfx::Size size = views::ImageView::GetPreferredSize(); | |
49 return gfx::Size(kIconWidth, size.height()); | |
50 } | |
51 | |
52 DISALLOW_COPY_AND_ASSIGN(FixedWidthImageView); | |
53 }; | |
54 | |
55 class ViewClickListener { | |
56 public: | |
57 virtual ~ViewClickListener() {} | |
58 virtual void ClickedOn(views::View* sender) = 0; | |
59 }; | |
60 | |
61 class HoverHighlightView : public views::View { | |
62 public: | |
63 explicit HoverHighlightView(ViewClickListener* listener) | |
64 : listener_(listener) { | |
65 set_notify_enter_exit_on_child(true); | |
66 } | |
67 | |
68 virtual ~HoverHighlightView() {} | |
69 | |
70 // Convenience function for adding an icon and a label. | |
71 void AddIconAndLabel(const SkBitmap& image, const string16& label) { | |
72 SetLayoutManager(new views::BoxLayout( | |
73 views::BoxLayout::kHorizontal, 0, 3, kIconPaddingLeft)); | |
74 views::ImageView* image_view = new FixedWidthImageView; | |
75 image_view->SetImage(image); | |
76 AddChildView(image_view); | |
77 AddChildView(new views::Label(label)); | |
78 } | |
79 | |
80 void AddLabel(const string16& text) { | |
81 SetLayoutManager(new views::FillLayout()); | |
82 views::Label* label = new views::Label(text); | |
83 label->set_border(views::Border::CreateEmptyBorder( | |
84 5, kIconWidth + kIconPaddingLeft, 5, 0)); | |
85 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
86 AddChildView(label); | |
87 } | |
88 | |
89 private: | |
90 // Overridden from views::View. | |
91 virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE { | |
92 if (!listener_) | |
93 return false; | |
94 listener_->ClickedOn(this); | |
95 return true; | |
96 } | |
97 | |
98 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE { | |
99 set_background(views::Background::CreateSolidBackground( | |
100 SkColorSetARGB(10, 0, 0, 0))); | |
101 SchedulePaint(); | |
102 } | |
103 | |
104 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE { | |
105 set_background(NULL); | |
106 SchedulePaint(); | |
107 } | |
108 | |
109 ViewClickListener* listener_; | |
110 | |
111 DISALLOW_COPY_AND_ASSIGN(HoverHighlightView); | |
112 }; | |
113 | |
114 // A custom scroll-view that has a specified dimension. | |
115 class FixedSizedScrollView : public views::ScrollView { | |
116 public: | |
117 FixedSizedScrollView() {} | |
118 virtual ~FixedSizedScrollView() {} | |
119 | |
120 void SetContentsView(View* view) { | |
121 SetContents(view); | |
122 view->SetBoundsRect(gfx::Rect(view->GetPreferredSize())); | |
123 } | |
124 | |
125 void set_fixed_size(gfx::Size size) { fixed_size_ = size; } | |
126 | |
127 private: | |
128 // Overridden from views::View. | |
129 virtual gfx::Size GetPreferredSize() OVERRIDE { | |
130 return fixed_size_; | |
131 } | |
132 | |
133 gfx::Size fixed_size_; | |
134 | |
135 DISALLOW_COPY_AND_ASSIGN(FixedSizedScrollView); | |
136 }; | |
137 | |
138 } | |
139 | 14 |
140 namespace ash { | 15 namespace ash { |
141 namespace internal { | 16 namespace internal { |
142 | 17 |
143 namespace tray { | 18 namespace tray { |
144 | 19 |
145 enum ResourceSize { | 20 enum ResourceSize { |
146 SMALL, | 21 SMALL, |
147 LARGE, | 22 LARGE, |
148 }; | 23 }; |
149 | 24 |
150 class NetworkTrayView : public views::View { | 25 class NetworkTrayView : public views::View { |
151 public: | 26 public: |
152 explicit NetworkTrayView(ResourceSize size) : resource_size_(size) { | 27 explicit NetworkTrayView(ResourceSize size) : resource_size_(size) { |
153 SetLayoutManager(new views::FillLayout()); | 28 SetLayoutManager(new views::FillLayout()); |
154 | 29 |
155 image_view_ = new views::ImageView; | 30 image_view_ = new views::ImageView; |
156 AddChildView(image_view_); | 31 AddChildView(image_view_); |
157 | 32 |
158 Update(Shell::GetInstance()->tray_delegate()-> | 33 Update(Shell::GetInstance()->tray_delegate()->GetMostRelevantNetworkIcon()); |
159 GetMostRelevantNetworkIcon(resource_size_ == LARGE)); | |
160 } | 34 } |
161 | 35 |
162 virtual ~NetworkTrayView() {} | 36 virtual ~NetworkTrayView() {} |
163 | 37 |
164 void Update(const NetworkIconInfo& info) { | 38 void Update(const NetworkIconInfo& info) { |
165 image_view_->SetImage(info.image); | 39 image_view_->SetImage(info.image); |
166 SchedulePaint(); | 40 SchedulePaint(); |
167 } | 41 } |
168 | 42 |
169 private: | 43 private: |
170 views::ImageView* image_view_; | 44 views::ImageView* image_view_; |
171 ResourceSize resource_size_; | 45 ResourceSize resource_size_; |
172 | 46 |
173 DISALLOW_COPY_AND_ASSIGN(NetworkTrayView); | 47 DISALLOW_COPY_AND_ASSIGN(NetworkTrayView); |
174 }; | 48 }; |
175 | 49 |
176 class NetworkDefaultView : public views::View { | 50 class NetworkDefaultView : public views::View { |
177 public: | 51 public: |
178 explicit NetworkDefaultView(SystemTrayItem* owner) : owner_(owner) { | 52 NetworkDefaultView() { |
179 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, | 53 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, |
180 0, 0, 5)); | 54 0, 0, 5)); |
181 | 55 |
182 icon_ = new NetworkTrayView(LARGE); | 56 icon_ = new NetworkTrayView(LARGE); |
183 AddChildView(icon_); | 57 AddChildView(icon_); |
184 | 58 |
185 label_ = new views::Label(); | 59 label_ = new views::Label(); |
186 AddChildView(label_); | 60 AddChildView(label_); |
187 | 61 |
188 views::ImageView* more = new views::ImageView; | 62 Update(Shell::GetInstance()->tray_delegate()->GetMostRelevantNetworkIcon()); |
189 more->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
190 IDR_AURA_UBER_TRAY_MORE).ToSkBitmap()); | |
191 AddChildView(more); | |
192 | |
193 Update(Shell::GetInstance()->tray_delegate()-> | |
194 GetMostRelevantNetworkIcon(true)); | |
195 } | 63 } |
196 | 64 |
197 virtual ~NetworkDefaultView() {} | 65 virtual ~NetworkDefaultView() {} |
198 | 66 |
199 void Update(const NetworkIconInfo& info) { | 67 void Update(const NetworkIconInfo& info) { |
200 icon_->Update(info); | 68 icon_->Update(info); |
201 label_->SetText(info.description); | 69 label_->SetText(info.description); |
202 } | 70 } |
203 | 71 |
204 private: | 72 private: |
205 // Overridden from views::View. | |
206 virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE { | |
207 owner_->PopupDetailedView(0, true); | |
208 return true; | |
209 } | |
210 | |
211 SystemTrayItem* owner_; | |
212 NetworkTrayView* icon_; | 73 NetworkTrayView* icon_; |
213 views::Label* label_; | 74 views::Label* label_; |
214 | 75 |
215 DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView); | 76 DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView); |
216 }; | 77 }; |
217 | 78 |
218 class NetworkDetailedView : public views::View, | |
219 public ViewClickListener { | |
220 public: | |
221 explicit NetworkDetailedView(user::LoginStatus login) | |
222 : login_(login), | |
223 header_(NULL), | |
224 airplane_(NULL), | |
225 settings_(NULL), | |
226 proxy_settings_(NULL) { | |
227 SetLayoutManager(new views::BoxLayout( | |
228 views::BoxLayout::kVertical, 1, 1, 1)); | |
229 Update(); | |
230 } | |
231 | |
232 virtual ~NetworkDetailedView() {} | |
233 | |
234 void Update() { | |
235 RemoveAllChildViews(true); | |
236 | |
237 AppendHeaderEntry(); | |
238 AppendNetworkEntries(); | |
239 AppendAirplaneModeEntry(); | |
240 AppendSettingsEntry(); | |
241 } | |
242 | |
243 private: | |
244 void AppendHeaderEntry() { | |
245 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
246 HoverHighlightView* container = new HoverHighlightView(this); | |
247 container->SetLayoutManager(new | |
248 views::BoxLayout(views::BoxLayout::kHorizontal, 0, 3, 5)); | |
249 views::ImageView* back = new FixedWidthImageView; | |
250 back->SetImage(rb.GetImageNamed(IDR_AURA_UBER_TRAY_LESS).ToSkBitmap()); | |
251 container->AddChildView(back); | |
252 views::Label* header = new views::Label(rb.GetLocalizedString( | |
253 IDS_ASH_STATUS_TRAY_NETWORK)); | |
254 header->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
255 header->SetFont(header->font().DeriveFont(4)); | |
256 container->AddChildView(header); | |
257 AddChildView(container); | |
258 header_ = container; | |
259 } | |
260 | |
261 void AppendNetworkEntries() { | |
262 std::vector<NetworkIconInfo> list; | |
263 Shell::GetInstance()->tray_delegate()->GetAvailableNetworks(&list); | |
264 FixedSizedScrollView* scroller = new FixedSizedScrollView; | |
265 views::View* networks = new views::View; | |
266 networks->SetLayoutManager(new views::BoxLayout( | |
267 views::BoxLayout::kVertical, 0, 0, 1)); | |
268 for (size_t i = 0; i < list.size(); i++) { | |
269 HoverHighlightView* container = new HoverHighlightView(this); | |
270 container->AddIconAndLabel(list[i].image, list[i].name); | |
271 networks->AddChildView(container); | |
272 network_map_[container] = list[i].unique_id; | |
273 } | |
274 scroller->set_border(views::Border::CreateSolidSidedBorder(1, 0, 1, 0, | |
275 SkColorSetARGB(25, 0, 0, 0))); | |
276 scroller->set_fixed_size( | |
277 gfx::Size(networks->GetPreferredSize().width() + | |
278 scroller->GetScrollBarWidth(), | |
279 kNetworkListHeight)); | |
280 scroller->SetContentsView(networks); | |
281 AddChildView(scroller); | |
282 } | |
283 | |
284 void AppendAirplaneModeEntry() { | |
285 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
286 HoverHighlightView* container = new HoverHighlightView(this); | |
287 container->AddIconAndLabel( | |
288 *rb.GetImageNamed(IDR_AURA_UBER_TRAY_NETWORK_AIRPLANE).ToSkBitmap(), | |
289 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_AIRPLANE_MODE)); | |
290 AddChildView(container); | |
291 airplane_ = container; | |
292 } | |
293 | |
294 // Adds a settings entry when logged in, and an entry for changing proxy | |
295 // settings otherwise. | |
296 void AppendSettingsEntry() { | |
297 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
298 if (login_ != user::LOGGED_IN_NONE) { | |
299 // Settings, only if logged in. | |
300 HoverHighlightView* container = new HoverHighlightView(this); | |
301 container->AddLabel(rb.GetLocalizedString( | |
302 IDS_ASH_STATUS_TRAY_NETWORK_SETTINGS)); | |
303 AddChildView(container); | |
304 settings_ = container; | |
305 } else { | |
306 // Allow changing proxy settings in the login screen. | |
307 HoverHighlightView* container = new HoverHighlightView(this); | |
308 container->AddLabel(rb.GetLocalizedString( | |
309 IDS_ASH_STATUS_TRAY_NETWORK_PROXY_SETTINGS)); | |
310 AddChildView(container); | |
311 proxy_settings_ = container; | |
312 } | |
313 } | |
314 | |
315 // Overridden from ViewClickListener. | |
316 virtual void ClickedOn(views::View* sender) OVERRIDE { | |
317 ash::SystemTrayDelegate* delegate = | |
318 ash::Shell::GetInstance()->tray_delegate(); | |
319 if (sender == header_) { | |
320 Shell::GetInstance()->tray()->ShowDefaultView(); | |
321 } else if (sender == settings_) { | |
322 delegate->ShowNetworkSettings(); | |
323 } else if (sender == proxy_settings_) { | |
324 delegate->ChangeProxySettings(); | |
325 } else if (sender == airplane_) { | |
326 delegate->ToggleAirplaneMode(); | |
327 } else { | |
328 std::map<views::View*, std::string>::iterator find; | |
329 find = network_map_.find(sender); | |
330 if (find != network_map_.end()) { | |
331 std::string network_id = find->second; | |
332 delegate->ConnectToNetwork(network_id); | |
333 } | |
334 } | |
335 } | |
336 | |
337 user::LoginStatus login_; | |
338 std::map<views::View*, std::string> network_map_; | |
339 views::View* header_; | |
340 views::View* airplane_; | |
341 views::View* settings_; | |
342 views::View* proxy_settings_; | |
343 DISALLOW_COPY_AND_ASSIGN(NetworkDetailedView); | |
344 }; | |
345 | |
346 } // namespace tray | 79 } // namespace tray |
347 | 80 |
348 TrayNetwork::TrayNetwork() { | 81 TrayNetwork::TrayNetwork() { |
349 } | 82 } |
350 | 83 |
351 TrayNetwork::~TrayNetwork() { | 84 TrayNetwork::~TrayNetwork() { |
352 } | 85 } |
353 | 86 |
354 views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { | 87 views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { |
355 tray_.reset(new tray::NetworkTrayView(tray::SMALL)); | 88 tray_.reset(new tray::NetworkTrayView(tray::SMALL)); |
356 return tray_.get(); | 89 return tray_.get(); |
357 } | 90 } |
358 | 91 |
359 views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { | 92 views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { |
360 default_.reset(new tray::NetworkDefaultView(this)); | 93 default_.reset(new tray::NetworkDefaultView); |
361 return default_.get(); | 94 return default_.get(); |
362 } | 95 } |
363 | 96 |
364 views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { | 97 views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { |
365 detailed_.reset(new tray::NetworkDetailedView(status)); | 98 return NULL; |
366 return detailed_.get(); | |
367 } | 99 } |
368 | 100 |
369 void TrayNetwork::DestroyTrayView() { | 101 void TrayNetwork::DestroyTrayView() { |
370 tray_.reset(); | 102 tray_.reset(); |
371 } | 103 } |
372 | 104 |
373 void TrayNetwork::DestroyDefaultView() { | 105 void TrayNetwork::DestroyDefaultView() { |
374 default_.reset(); | 106 default_.reset(); |
375 } | 107 } |
376 | 108 |
377 void TrayNetwork::DestroyDetailedView() { | 109 void TrayNetwork::DestroyDetailedView() { |
378 detailed_.reset(); | |
379 } | 110 } |
380 | 111 |
381 void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { | 112 void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { |
382 if (tray_.get()) | 113 if (tray_.get()) |
383 tray_->Update(info); | 114 tray_->Update(info); |
384 if (default_.get()) | 115 if (default_.get()) |
385 default_->Update(info); | 116 default_->Update(info); |
386 if (detailed_.get()) | |
387 detailed_->Update(); | |
388 } | 117 } |
389 | 118 |
390 } // namespace internal | 119 } // namespace internal |
391 } // namespace ash | 120 } // namespace ash |
OLD | NEW |