diff options
author | glotov@chromium.org <glotov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-16 17:26:54 +0000 |
---|---|---|
committer | glotov@chromium.org <glotov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-16 17:26:54 +0000 |
commit | 3de008828cff06c001d423cdfb3f69acf6a2555b (patch) | |
tree | 38523942ab31a548e105aca073fb0f25998cba13 | |
parent | f907d8758b255362d4b73e92bbeffc7bef709779 (diff) | |
download | chromium_src-3de008828cff06c001d423cdfb3f69acf6a2555b.zip chromium_src-3de008828cff06c001d423cdfb3f69acf6a2555b.tar.gz chromium_src-3de008828cff06c001d423cdfb3f69acf6a2555b.tar.bz2 |
Volume bubble added for ChromeOS.
BUG=crosbug.com/525
TEST=none
Review URL: http://codereview.chromium.org/2790012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49970 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/system_key_event_listener.cc | 10 | ||||
-rw-r--r-- | chrome/browser/chromeos/volume_bubble.cc | 111 | ||||
-rw-r--r-- | chrome/browser/chromeos/volume_bubble.h | 61 | ||||
-rw-r--r-- | chrome/browser/chromeos/volume_bubble_view.cc | 66 | ||||
-rw-r--r-- | chrome/browser/chromeos/volume_bubble_view.h | 42 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 4 |
6 files changed, 291 insertions, 3 deletions
diff --git a/chrome/browser/chromeos/system_key_event_listener.cc b/chrome/browser/chromeos/system_key_event_listener.cc index c4ecb52..710207a 100644 --- a/chrome/browser/chromeos/system_key_event_listener.cc +++ b/chrome/browser/chromeos/system_key_event_listener.cc @@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/system_key_event_listener.h" #include "chrome/browser/chromeos/audio_handler.h" +#include "chrome/browser/chromeos/volume_bubble.h" #include "third_party/cros/chromeos_wm_ipc_enums.h" namespace chromeos { @@ -17,8 +18,7 @@ const double kStepPercentage = 4.0; // static SystemKeyEventListener* SystemKeyEventListener::instance() { - SystemKeyEventListener* instance = Singleton<SystemKeyEventListener>::get(); - return instance; + return Singleton<SystemKeyEventListener>::get(); } SystemKeyEventListener::SystemKeyEventListener() @@ -44,14 +44,19 @@ void SystemKeyEventListener::ProcessWmMessage(const WmIpc::Message& message, // long as mute key was held. // Refer to http://crosbug.com/3754 and http://crosbug.com/3751 audio_handler_->SetMute(true); + VolumeBubble::instance()->ShowVolumeBubble(0); break; case WM_IPC_SYSTEM_KEY_VOLUME_DOWN: audio_handler_->AdjustVolumeByPercent(-kStepPercentage); audio_handler_->SetMute(false); + VolumeBubble::instance()->ShowVolumeBubble( + audio_handler_->GetVolumePercent()); break; case WM_IPC_SYSTEM_KEY_VOLUME_UP: audio_handler_->AdjustVolumeByPercent(kStepPercentage); audio_handler_->SetMute(false); + VolumeBubble::instance()->ShowVolumeBubble( + audio_handler_->GetVolumePercent()); break; default: DLOG(ERROR) << "SystemKeyEventListener: Unexpected message " @@ -61,4 +66,3 @@ void SystemKeyEventListener::ProcessWmMessage(const WmIpc::Message& message, } } // namespace chromeos - diff --git a/chrome/browser/chromeos/volume_bubble.cc b/chrome/browser/chromeos/volume_bubble.cc new file mode 100644 index 0000000..667f420 --- /dev/null +++ b/chrome/browser/chromeos/volume_bubble.cc @@ -0,0 +1,111 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/volume_bubble.h" + +#include <gdk/gdk.h> + +#include "base/timer.h" +#include "chrome/browser/chromeos/volume_bubble_view.h" +#include "chrome/browser/views/info_bubble.h" +#include "views/widget/root_view.h" + +namespace { +const int kBubbleShowTimeoutSec = 2; +const int kAnimationDurationMs = 200; +const int kVolumeBubbleX = 300, kVolumeBubbleY = 700; +} // namespace + +namespace chromeos { + +// Temporary helper routine. Returns currently shown Chrome widget or NULL. +// TODO(glotov): remove this in favor of enabling InfoBubble class act +// without |parent| specified. crosbug.com/4025 +static views::Widget* GetToplevelWidget() { + views::Widget* widget = NULL; + GList *window_list = gtk_window_list_toplevels(); + for (GList* iter = window_list; iter; iter = g_list_next(iter)) { + GtkWindow* const window = GTK_WINDOW(iter->data); + if (window && GTK_WIDGET(window)->window == + gdk_screen_get_active_window(gdk_screen_get_default())) { + views::RootView* root = views::Widget::FindRootView(window); + if (root) + widget = root->GetWidget(); + break; + } + } + g_list_free(window_list); + return widget; +} + +VolumeBubble::VolumeBubble() + : previous_percent_(-1), + current_percent_(-1), + bubble_(NULL), + view_(NULL), + animation_(this) { + animation_.SetSlideDuration(kAnimationDurationMs); + animation_.SetTweenType(Tween::LINEAR); +} + +void VolumeBubble::ShowVolumeBubble(int percent) { + if (percent < 0) + percent = 0; + if (percent > 100) + percent = 100; + if (previous_percent_ == -1) + previous_percent_ = percent; + current_percent_ = percent; + if (!bubble_) { + views::Widget* widget = GetToplevelWidget(); + if (widget == NULL) + return; + DCHECK(view_ == NULL); + view_ = new VolumeBubbleView; + view_->Init(previous_percent_); + // TODO(glotov): Place volume bubble over the keys initiated the + // volume change. This metric must be specific to the given + // architecture. crosbug.com/4028 + bubble_ = InfoBubble::Show(widget, + gfx::Rect(kVolumeBubbleX, kVolumeBubbleY, 0, 0), + BubbleBorder::FLOAT, view_, this); + } else { + DCHECK(view_); + timeout_timer_.Stop(); + } + if (animation_.is_animating()) + animation_.End(); + animation_.Reset(); + animation_.Show(); + timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec), + this, &VolumeBubble::OnTimeout); +} + +void VolumeBubble::OnTimeout() { + if (bubble_) + bubble_->Close(); +} + +void VolumeBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool) { + DCHECK(info_bubble == bubble_); + timeout_timer_.Stop(); + animation_.Stop(); + bubble_ = NULL; + view_ = NULL; +} + +void VolumeBubble::AnimationEnded(const Animation* animation) { + previous_percent_ = current_percent_; +} + +void VolumeBubble::AnimationProgressed(const Animation* animation) { + if (view_) { + view_->Update( + Tween::ValueBetween(animation->GetCurrentValue(), + previous_percent_, + current_percent_)); + } +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/volume_bubble.h b/chrome/browser/chromeos/volume_bubble.h new file mode 100644 index 0000000..90bb034 --- /dev/null +++ b/chrome/browser/chromeos/volume_bubble.h @@ -0,0 +1,61 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_VOLUME_BUBBLE_H_ +#define CHROME_BROWSER_CHROMEOS_VOLUME_BUBBLE_H_ + +#include "app/active_window_watcher_x.h" +#include "app/slide_animation.h" +#include "base/singleton.h" +#include "chrome/browser/views/info_bubble.h" + +namespace chromeos { + +class VolumeBubbleView; + +// Singleton class controlling volume bubble. +class VolumeBubble : public InfoBubbleDelegate, + public AnimationDelegate { + public: + static VolumeBubble* instance() { + return Singleton<VolumeBubble>::get(); + } + + void ShowVolumeBubble(int percent); + + private: + friend struct DefaultSingletonTraits<VolumeBubble>; + + VolumeBubble(); + void OnTimeout(); + + // Overridden from InfoBubbleDelegate. + virtual void InfoBubbleClosing(InfoBubble* info_bubble, + bool closed_by_escape); + virtual bool CloseOnEscape() { return true; } + virtual bool FadeInOnShow() { return false; } + + // Overridden from AnimationDelegate. + virtual void AnimationEnded(const Animation* animation); + virtual void AnimationProgressed(const Animation* animation); + + // Previous and current volume percentages, -1 if not yet shown. + int previous_percent_; + int current_percent_; + + // Currently shown bubble or NULL. + InfoBubble* bubble_; + + // Its contents view, owned by InfoBubble. + VolumeBubbleView* view_; + + SlideAnimation animation_; + base::OneShotTimer<VolumeBubble> timeout_timer_; + + DISALLOW_COPY_AND_ASSIGN(VolumeBubble); +}; + +} // namespace + +#endif // CHROME_BROWSER_CHROMEOS_VOLUME_BUBBLE_H_ diff --git a/chrome/browser/chromeos/volume_bubble_view.cc b/chrome/browser/chromeos/volume_bubble_view.cc new file mode 100644 index 0000000..5aa99c1 --- /dev/null +++ b/chrome/browser/chromeos/volume_bubble_view.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/volume_bubble_view.h" + +#include <string> + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "gfx/canvas.h" +#include "grit/theme_resources.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "views/controls/progress_bar.h" + +using views::Background; +using views::View; +using views::Widget; + +namespace { + +// Volume bubble metrics. +const int kWidth = 300, kHeight = 75; +const int kMargin = 25; +const int kProgressBarHeight = 20; + +} // namespace + +namespace chromeos { + +VolumeBubbleView::VolumeBubbleView() : progress_bar_(NULL) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + volume_icon_ = rb.GetBitmapNamed(IDR_VOLUMEBUBBLE_ICON); +} + +void VolumeBubbleView::Init(int volume_level_percent) { + DCHECK(volume_level_percent >= 0 && volume_level_percent <= 100); + progress_bar_ = new views::ProgressBar(); + AddChildView(progress_bar_); + Update(volume_level_percent); +} + +void VolumeBubbleView::Update(int volume_level_percent) { + DCHECK(volume_level_percent >= 0 && volume_level_percent <= 100); + progress_bar_->SetProgress(volume_level_percent); +} + +void VolumeBubbleView::Paint(gfx::Canvas* canvas) { + views::View::Paint(canvas); + canvas->DrawBitmapInt(*volume_icon_, + volume_icon_->width(), + (height() - volume_icon_->height()) / 2); +} + +void VolumeBubbleView::Layout() { + progress_bar_->SetBounds(volume_icon_->width() + kMargin * 2, + (height() - kProgressBarHeight) / 2, + width() - volume_icon_->width() - kMargin * 3, + kProgressBarHeight); +} + +gfx::Size VolumeBubbleView::GetPreferredSize() { + return gfx::Size(kWidth, kHeight); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/volume_bubble_view.h b/chrome/browser/chromeos/volume_bubble_view.h new file mode 100644 index 0000000..ee5a3f2 --- /dev/null +++ b/chrome/browser/chromeos/volume_bubble_view.h @@ -0,0 +1,42 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_VOLUME_BUBBLE_VIEW_H_ +#define CHROME_BROWSER_CHROMEOS_VOLUME_BUBBLE_VIEW_H_ + +#include "views/view.h" + +namespace views { +class ProgressBar; +} // namespace views + +class SkBitmap; + +namespace chromeos { + +class VolumeBubbleView : public views::View { + public: + VolumeBubbleView(); + + // Initialize the view. Set the volume progress bar to the specified position. + void Init(int volume_level_percent); + + // Set the volume progress bar to the specified position and redraw it. + void Update(int volume_level_percent); + + private: + // views::View implementation: + virtual void Paint(gfx::Canvas* canvas); + virtual void Layout(); + virtual gfx::Size GetPreferredSize(); + + views::ProgressBar* progress_bar_; + SkBitmap* volume_icon_; + + DISALLOW_COPY_AND_ASSIGN(VolumeBubbleView); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_VOLUME_BUBBLE_VIEW_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 6b08062..467557f 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -548,6 +548,10 @@ 'browser/chromeos/version_loader.cc', 'browser/chromeos/version_loader.h', 'browser/chromeos/view_ids.h', + 'browser/chromeos/volume_bubble.cc', + 'browser/chromeos/volume_bubble.h', + 'browser/chromeos/volume_bubble_view.cc', + 'browser/chromeos/volume_bubble_view.h', 'browser/chromeos/wm_ipc.cc', 'browser/chromeos/wm_ipc.h', 'browser/chromeos/wm_message_listener.cc', |