summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglotov@chromium.org <glotov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-16 17:26:54 +0000
committerglotov@chromium.org <glotov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-16 17:26:54 +0000
commit3de008828cff06c001d423cdfb3f69acf6a2555b (patch)
tree38523942ab31a548e105aca073fb0f25998cba13
parentf907d8758b255362d4b73e92bbeffc7bef709779 (diff)
downloadchromium_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.cc10
-rw-r--r--chrome/browser/chromeos/volume_bubble.cc111
-rw-r--r--chrome/browser/chromeos/volume_bubble.h61
-rw-r--r--chrome/browser/chromeos/volume_bubble_view.cc66
-rw-r--r--chrome/browser/chromeos/volume_bubble_view.h42
-rwxr-xr-xchrome/chrome_browser.gypi4
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',