OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/chromeos/network_menu_button.h" | 5 #include "chrome/browser/chromeos/network_menu_button.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
| 9 #include "app/gfx/canvas.h" |
9 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
10 #include "app/resource_bundle.h" | 11 #include "app/resource_bundle.h" |
11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
12 #include "grit/generated_resources.h" | 13 #include "grit/generated_resources.h" |
13 #include "grit/theme_resources.h" | 14 #include "grit/theme_resources.h" |
14 #include "views/widget/widget.h" | 15 #include "views/widget/widget.h" |
15 #include "views/window/window.h" | 16 #include "views/window/window.h" |
16 | 17 |
17 //////////////////////////////////////////////////////////////////////////////// | 18 //////////////////////////////////////////////////////////////////////////////// |
18 // NetworkMenuButton | 19 // NetworkMenuButton |
19 | 20 |
20 // static | 21 // static |
21 const int NetworkMenuButton::kNumWifiImages = 8; | 22 const int NetworkMenuButton::kNumWifiImages = 3; |
| 23 const int NetworkMenuButton::kMinOpacity = 50; |
| 24 const int NetworkMenuButton::kMaxOpacity = 256; |
22 const int NetworkMenuButton::kThrobDuration = 1000; | 25 const int NetworkMenuButton::kThrobDuration = 1000; |
23 | 26 |
24 NetworkMenuButton::NetworkMenuButton(gfx::NativeWindow browser_window) | 27 NetworkMenuButton::NetworkMenuButton(gfx::NativeWindow browser_window) |
25 : StatusAreaButton(this), | 28 : StatusAreaButton(this), |
26 ALLOW_THIS_IN_INITIALIZER_LIST(network_menu_(this)), | 29 ALLOW_THIS_IN_INITIALIZER_LIST(network_menu_(this)), |
27 browser_window_(browser_window), | 30 browser_window_(browser_window), |
28 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) { | 31 ALLOW_THIS_IN_INITIALIZER_LIST(animation_connecting_(this)), |
29 animation_.SetThrobDuration(kThrobDuration); | 32 ALLOW_THIS_IN_INITIALIZER_LIST(animation_downloading_(this)), |
30 animation_.SetTweenType(SlideAnimation::NONE); | 33 ALLOW_THIS_IN_INITIALIZER_LIST(animation_uploading_(this)) { |
31 UpdateIcon(); | 34 animation_connecting_.SetThrobDuration(kThrobDuration); |
| 35 animation_connecting_.SetTweenType(SlideAnimation::NONE); |
| 36 animation_downloading_.SetThrobDuration(kThrobDuration); |
| 37 animation_downloading_.SetTweenType(SlideAnimation::NONE); |
| 38 animation_uploading_.SetThrobDuration(kThrobDuration); |
| 39 animation_uploading_.SetTweenType(SlideAnimation::NONE); |
| 40 NetworkChanged(CrosNetworkLibrary::Get()); |
32 CrosNetworkLibrary::Get()->AddObserver(this); | 41 CrosNetworkLibrary::Get()->AddObserver(this); |
33 } | 42 } |
34 | 43 |
35 NetworkMenuButton::~NetworkMenuButton() { | 44 NetworkMenuButton::~NetworkMenuButton() { |
36 CrosNetworkLibrary::Get()->RemoveObserver(this); | 45 CrosNetworkLibrary::Get()->RemoveObserver(this); |
37 } | 46 } |
38 | 47 |
39 //////////////////////////////////////////////////////////////////////////////// | 48 //////////////////////////////////////////////////////////////////////////////// |
40 // NetworkMenuButton, views::Menu2Model implementation: | 49 // NetworkMenuButton, views::Menu2Model implementation: |
41 | 50 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 const string16& password) { | 115 const string16& password) { |
107 CrosNetworkLibrary::Get()->ConnectToWifiNetwork(activated_wifi_network_, | 116 CrosNetworkLibrary::Get()->ConnectToWifiNetwork(activated_wifi_network_, |
108 password); | 117 password); |
109 return true; | 118 return true; |
110 } | 119 } |
111 | 120 |
112 //////////////////////////////////////////////////////////////////////////////// | 121 //////////////////////////////////////////////////////////////////////////////// |
113 // NetworkMenuButton, AnimationDelegate implementation: | 122 // NetworkMenuButton, AnimationDelegate implementation: |
114 | 123 |
115 void NetworkMenuButton::AnimationProgressed(const Animation* animation) { | 124 void NetworkMenuButton::AnimationProgressed(const Animation* animation) { |
116 if (animation == &animation_) | 125 if (animation == &animation_connecting_ || |
117 UpdateIcon(); | 126 animation == &animation_downloading_ || |
| 127 animation == &animation_uploading_) |
| 128 SchedulePaint(); |
118 else | 129 else |
119 MenuButton::AnimationProgressed(animation); | 130 MenuButton::AnimationProgressed(animation); |
120 } | 131 } |
121 | 132 |
122 //////////////////////////////////////////////////////////////////////////////// | 133 //////////////////////////////////////////////////////////////////////////////// |
| 134 // NetworkMenuButton, StatusAreaButton implementation: |
| 135 |
| 136 // Override the DrawIcon method to draw the wifi icon. |
| 137 // The wifi icon is composed of 1 or more alpha-blended icons to show the |
| 138 // network strength. We also draw an animation for when there's upload/download |
| 139 // traffic. |
| 140 void NetworkMenuButton::DrawIcon(gfx::Canvas* canvas) { |
| 141 // First draw the base icon. |
| 142 canvas->DrawBitmapInt(icon(), 0, 0); |
| 143 |
| 144 // If wifi, we draw the wifi signal bars. |
| 145 CrosNetworkLibrary* cros = CrosNetworkLibrary::Get(); |
| 146 if (cros->wifi_connecting() || |
| 147 (!cros->ethernet_connected() && !cros->wifi_ssid().empty())) { |
| 148 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 149 // We want a value between 0-1. |
| 150 // 0 reperesents no signal and 1 represents full signal strength. |
| 151 double value = cros->wifi_connecting() ? |
| 152 animation_connecting_.GetCurrentValue() : cros->wifi_strength() / 100.0; |
| 153 if (value < 0) |
| 154 value = 0; |
| 155 else if (value > 1) |
| 156 value = 1; |
| 157 |
| 158 // If we are animating network traffic and not connecting, then we need to |
| 159 // figure out if we are to also draw the extra image. |
| 160 int downloading_index = -1; |
| 161 int uploading_index = -1; |
| 162 if (!animation_connecting_.IsAnimating()) { |
| 163 // For network animation, we only show animation in one direction. |
| 164 // So when we are hiding, we just use 1 minus the value. |
| 165 // We have kNumWifiImages + 1 number of states. For the first state, where |
| 166 // we are not adding any images, we set the index to -1. |
| 167 if (animation_downloading_.IsAnimating()) { |
| 168 double value_downloading = animation_downloading_.IsShowing() ? |
| 169 animation_downloading_.GetCurrentValue() : |
| 170 1.0 - animation_downloading_.GetCurrentValue(); |
| 171 downloading_index = static_cast<int>(value_downloading * |
| 172 nextafter(static_cast<float>(kNumWifiImages + 1), 0)) - 1; |
| 173 } |
| 174 if (animation_uploading_.IsAnimating()) { |
| 175 double value_uploading = animation_uploading_.IsShowing() ? |
| 176 animation_uploading_.GetCurrentValue() : |
| 177 1.0 - animation_uploading_.GetCurrentValue(); |
| 178 uploading_index = static_cast<int>(value_uploading * |
| 179 nextafter(static_cast<float>(kNumWifiImages + 1), 0)) - 1; |
| 180 } |
| 181 } |
| 182 |
| 183 // We need to determine opacity for each of the kNumWifiImages images. |
| 184 // We split the range (0-1) into equal ranges per kNumWifiImages images. |
| 185 // For example if kNumWifiImages is 3, then [0-0.33) is the first image and |
| 186 // [0.33-0.66) is the second image and [0.66-1] is the last image. |
| 187 // For each of the image: |
| 188 // If value < the range of this image, draw at kMinOpacity opacity. |
| 189 // If value > the range of this image, draw at kMaxOpacity-1 opacity. |
| 190 // If value within the range of this image, draw at an opacity value |
| 191 // between kMinOpacity and kMaxOpacity-1 relative to where in the range |
| 192 // value is at. |
| 193 double value_per_image = 1.0 / kNumWifiImages; |
| 194 SkPaint paint; |
| 195 for (int i = 0; i < kNumWifiImages; i++) { |
| 196 if (value > value_per_image) { |
| 197 paint.setAlpha(kMaxOpacity - 1); |
| 198 value -= value_per_image; |
| 199 } else { |
| 200 // Map value between 0 and value_per_image to [kMinOpacity,kMaxOpacity). |
| 201 paint.setAlpha(kMinOpacity + static_cast<int>(value / value_per_image * |
| 202 nextafter(static_cast<float>(kMaxOpacity - kMinOpacity), 0))); |
| 203 // For following iterations, we want to draw at kMinOpacity. |
| 204 // So we set value to 0 here. |
| 205 value = 0; |
| 206 } |
| 207 canvas->DrawBitmapInt(*rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_UP1 + i), |
| 208 0, 0, paint); |
| 209 canvas->DrawBitmapInt(*rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_DOWN1 + i), |
| 210 0, 0, paint); |
| 211 |
| 212 // Draw network traffic downloading/uploading image if necessary. |
| 213 if (i == downloading_index) |
| 214 canvas->DrawBitmapInt(*rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_DOWN1P + i), |
| 215 0, 0, paint); |
| 216 if (i == uploading_index) |
| 217 canvas->DrawBitmapInt(*rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_UP1P + i), |
| 218 0, 0, paint); |
| 219 } |
| 220 } |
| 221 } |
| 222 |
| 223 //////////////////////////////////////////////////////////////////////////////// |
123 // NetworkMenuButton, views::ViewMenuDelegate implementation: | 224 // NetworkMenuButton, views::ViewMenuDelegate implementation: |
124 | 225 |
125 void NetworkMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { | 226 void NetworkMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { |
126 wifi_networks_ = CrosNetworkLibrary::Get()->wifi_networks(); | 227 wifi_networks_ = CrosNetworkLibrary::Get()->wifi_networks(); |
127 refreshing_menu_ = true; | 228 refreshing_menu_ = true; |
128 network_menu_.Rebuild(); | 229 network_menu_.Rebuild(); |
129 network_menu_.UpdateStates(); | 230 network_menu_.UpdateStates(); |
130 refreshing_menu_ = false; | 231 refreshing_menu_ = false; |
131 network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); | 232 network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); |
132 } | 233 } |
133 | 234 |
134 //////////////////////////////////////////////////////////////////////////////// | 235 //////////////////////////////////////////////////////////////////////////////// |
135 // NetworkMenuButton, CrosNetworkLibrary::Observer implementation: | 236 // NetworkMenuButton, CrosNetworkLibrary::Observer implementation: |
136 | 237 |
137 void NetworkMenuButton::NetworkChanged(CrosNetworkLibrary* obj) { | 238 void NetworkMenuButton::NetworkChanged(CrosNetworkLibrary* cros) { |
138 UpdateIcon(); | 239 int id = IDR_STATUSBAR_WARNING; |
139 } | 240 if (cros->loaded()) { |
| 241 id = IDR_STATUSBAR_NETWORK_DISCONNECTED; |
| 242 if (cros->wifi_connecting()) { |
| 243 // Start the connecting animation if not running. |
| 244 if (!animation_connecting_.IsAnimating()) { |
| 245 animation_connecting_.Reset(); |
| 246 animation_connecting_.StartThrobbing(std::numeric_limits<int>::max()); |
| 247 } |
| 248 // Stop network traffic animation when we are connecting. |
| 249 animation_downloading_.Stop(); |
| 250 animation_uploading_.Stop(); |
140 | 251 |
141 void NetworkMenuButton::UpdateIcon() { | 252 id = IDR_STATUSBAR_WIFI_DOT; |
142 CrosNetworkLibrary* cros = CrosNetworkLibrary::Get(); | 253 } else { |
143 int id = IDR_STATUSBAR_NETWORK_DISCONNECTED; | 254 // Stop connecting animation since we are not connecting. |
144 if (cros->wifi_connecting()) { | 255 animation_connecting_.Stop(); |
145 // Start the connecting animation if not running. | |
146 if (!animation_.IsAnimating()) | |
147 animation_.StartThrobbing(std::numeric_limits<int>::max()); | |
148 | 256 |
149 // We need to map the value of 0-1 in the animation to 0 - kNumWifiImages-1. | 257 // Always show the higher priority connection first. Ethernet then wifi. |
150 int index = static_cast<int>(animation_.GetCurrentValue() * | 258 if (cros->ethernet_connected()) { |
151 nextafter(static_cast<float>(kNumWifiImages), 0)); | 259 id = IDR_STATUSBAR_WIRED; |
152 id = IDR_STATUSBAR_WIFI_1 + index; | 260 } else if (!cros->wifi_ssid().empty()) { |
153 } else { | 261 id = IDR_STATUSBAR_WIFI_DOT; |
154 // Stop connecting animation since we are not connecting. | 262 } |
155 if (animation_.IsAnimating()) | |
156 animation_.Stop(); | |
157 | |
158 // Always show the higher priority connection first. So ethernet then wifi. | |
159 if (cros->ethernet_connected()) { | |
160 id = IDR_STATUSBAR_WIRED; | |
161 } else if (!cros->wifi_ssid().empty()) { | |
162 // Gets the wifi image of 1-8 bars depending on signal strength. Signal | |
163 // strength is from 0 to 100, so we need to convert that to 0 to 7. | |
164 int index = static_cast<int>(cros->wifi_strength() / 100.0 * | |
165 nextafter(static_cast<float>(kNumWifiImages), 0)); | |
166 // Make sure that index is between 0 and kNumWifiImages - 1 | |
167 if (index < 0) | |
168 index = 0; | |
169 if (index >= kNumWifiImages) | |
170 index = kNumWifiImages - 1; | |
171 id = IDR_STATUSBAR_WIFI_1 + index; | |
172 } | 263 } |
173 } | 264 } |
| 265 |
174 SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(id)); | 266 SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(id)); |
175 SchedulePaint(); | 267 SchedulePaint(); |
176 } | 268 } |
| 269 |
| 270 void NetworkMenuButton::NetworkTraffic(CrosNetworkLibrary* cros, |
| 271 int traffic_type) { |
| 272 if (!cros->ethernet_connected() && !cros->wifi_ssid().empty() && |
| 273 !cros->wifi_connecting()) { |
| 274 // For downloading/uploading animation, we want to force at least one cycle |
| 275 // so that it looks smooth. And if we keep downloading/uploading, we will |
| 276 // keep calling StartThrobbing which will update the cycle count back to 2. |
| 277 if (traffic_type & TRAFFIC_DOWNLOAD) |
| 278 animation_downloading_.StartThrobbing(2); |
| 279 if (traffic_type & TRAFFIC_UPLOAD) |
| 280 animation_uploading_.StartThrobbing(2); |
| 281 } |
| 282 } |
OLD | NEW |