Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2028)

Unified Diff: chrome/browser/chromeos/setting_level_bubble_view_views.cc

Issue 8319008: aura: brightness and volume bubble. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/setting_level_bubble_view_views.cc
diff --git a/chrome/browser/chromeos/setting_level_bubble_view_views.cc b/chrome/browser/chromeos/setting_level_bubble_view_views.cc
new file mode 100644
index 0000000000000000000000000000000000000000..00c45eb9233a9fa43b34ccb094a6eca4def913a3
--- /dev/null
+++ b/chrome/browser/chromeos/setting_level_bubble_view_views.cc
@@ -0,0 +1,257 @@
+// Copyright (c) 2011 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/setting_level_bubble_view_views.h"
+
+#include <algorithm>
+
+#include "chrome/browser/chromeos/login/background_view.h"
+#include "chrome/browser/chromeos/login/login_utils.h"
+#include "chrome/browser/chromeos/login/webui_login_display.h"
+#include "chrome/browser/chromeos/setting_level_bubble_view.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/views/bubble/bubble.h" // for kBackgroundColor
+#include "ui/gfx/screen.h"
+#include "views/widget/root_view.h"
+
+using base::TimeDelta;
+using base::TimeTicks;
+using std::max;
+using std::min;
+
+namespace {
+
+// How long should the bubble be shown onscreen whenever the setting changes?
+const int kBubbleShowTimeoutMs = 1000;
+
+// How long should the level initially take to move up or down when it changes?
+// (The rate adapts to handle keyboard autorepeat.)
+const int64 kInitialAnimationDurationMs = 200;
+
+// Horizontal position of the center of the bubble on the screen: 0 is left
+// edge, 0.5 is center, 1 is right edge.
+const double kBubbleXRatio = 0.5;
+
+// Vertical gap from the bottom of the screen in pixels.
+const int kBubbleBottomGap = 30;
+
+// Duration between animation frames.
+// Chosen to match ui::SlideAnimation's kDefaultFramerateHz.
+const int kAnimationIntervalMs = 1000 / 50;
+
+double LimitPercent(double percent) {
+ return min(max(percent, 0.0), 100.0);
+}
+
+} // namespace
+
+namespace chromeos {
+
+// Temporary helper routine. Tries to first return the widget from the
+// most-recently-focused normal browser window, then from a login
+// background, and finally NULL if both of those fail.
+// TODO(glotov): remove this in favor of enabling Bubble class act
+// without |parent| specified. crosbug.com/4025
+static views::Widget* GetToplevelWidget() {
+#if defined(USE_AURA)
+ // TODO(saintlou): Need to fix in PureViews..... how?
+ return WebUILoginDisplay::GetLoginWindow();
+#else
+ GtkWindow* window = NULL;
+
+ // We just use the default profile here -- this gets overridden as needed
+ // in Chrome OS depending on whether the user is logged in or not.
+ Browser* browser =
+ BrowserList::FindTabbedBrowser(
+ ProfileManager::GetDefaultProfile(),
+ true); // match_incognito
+ if (browser) {
+ window = GTK_WINDOW(browser->window()->GetNativeHandle());
+ } else {
+ // Otherwise, see if there's a background window that we can use.
+ BackgroundView* background = LoginUtils::Get()->GetBackgroundView();
+ if (background)
+ window = GTK_WINDOW(background->GetNativeWindow());
+ }
+
+ if (window)
+ return views::Widget::GetWidgetForNativeWindow(window);
+ else
+ return WebUILoginDisplay::GetLoginWindow();
+#endif
+}
+
+// SettingLevelBubbleViewViews -------------------------------------------------
+// static
+views::Widget* SettingLevelBubbleViewViews::ConstructSettingLevelBubble(
+ SkBitmap* increase_icon,
+ SkBitmap* decrease_icon,
+ SkBitmap* zero_icon,
+ double percent,
+ bool enabled) {
+ views::Widget* parent = GetToplevelWidget();
+ SettingLevelBubbleViewViews* delegate =
+ new SettingLevelBubbleViewViews(increase_icon, decrease_icon, zero_icon);
+ delegate->UpdateSettingLevel(percent, enabled);
+ // Construct and initialize settings.
+ return views::BubbleDelegateView::ConstructBubble(delegate, parent);
+}
+
+SettingLevelBubbleViewViews::SettingLevelBubbleViewViews(
+ SkBitmap* increase_icon,
+ SkBitmap* decrease_icon,
+ SkBitmap* disabled_icon)
+ : current_percent_(-1.0),
+ target_percent_(-1.0),
+ increase_icon_(increase_icon),
+ decrease_icon_(decrease_icon),
+ disabled_icon_(disabled_icon),
+ current_icon_(NULL),
+ enabled_(false),
+ view_(NULL),
+ is_animating_(false) {
+}
+
+SettingLevelBubbleViewViews::~SettingLevelBubbleViewViews() {
+ WindowClosing();
+}
+
+void SettingLevelBubbleViewViews::Init() {
+ SettingLevelBubbleView* view = new SettingLevelBubbleView();
+ view->SetIcon(current_icon_);
+ view->SetEnabled(enabled_);
+
+ // Calculate the position in screen coordinates that the bubble should
+ // "point" at (since we use BubbleBorder::FLOAT, this position actually
+ // specifies the center of the bubble).
+ const gfx::Rect monitor_area =
+ gfx::Screen::GetMonitorAreaNearestWindow(
+ GetWidget()->GetTopLevelWidget()->GetNativeView());
+ const gfx::Size view_size = view->GetPreferredSize();
+ position_relative_to_ = gfx::Rect(
+ monitor_area.x() + kBubbleXRatio * monitor_area.width(),
+ monitor_area.bottom() - view_size.height() / 2 - kBubbleBottomGap,
+ 0, 0);
+ view->Init(current_icon_, current_percent_, enabled_);
+ AddChildView(view);
+}
+
+views::BubbleBorder::ArrowLocation
+SettingLevelBubbleViewViews::GetArrowLocation() const {
+ return views::BubbleBorder::FLOAT;
+}
+
+SkColor SettingLevelBubbleViewViews::GetColor() const {
+ return Bubble::kBackgroundColor;
+}
+
+bool SettingLevelBubbleViewViews::GetEnableAccelerator() const {
+ return false;
+}
+
+void SettingLevelBubbleViewViews::WindowClosing() {
+ StopAnimation();
+ current_percent_ = target_percent_;
+ target_time_ = TimeTicks();
+ last_animation_update_time_ = TimeTicks();
+ last_target_update_time_ = TimeTicks();
+}
+
+void SettingLevelBubbleViewViews::UpdateSettingLevel(double percent,
+ bool enabled) {
+ enabled_ = enabled;
+ const double old_target_percent = target_percent_;
+ UpdateTargetPercent(percent);
+ current_icon_ = increase_icon_;
+ if (!enabled || target_percent_ == 0)
+ current_icon_ = disabled_icon_;
+ else if (old_target_percent >= 0 && target_percent_ < old_target_percent)
+ current_icon_ = decrease_icon_;
+}
+
+void SettingLevelBubbleViewViews::UpdateWithoutShowingBubble(
+ double percent,
+ bool enabled) {
+ UpdateTargetPercent(percent);
+ if (view_)
+ view_->SetEnabled(enabled);
+}
+
+void SettingLevelBubbleViewViews::StartHideTimer() {
+ hide_timer_.Stop();
+ hide_timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kBubbleShowTimeoutMs),
+ this, &SettingLevelBubbleViewViews::OnHideTimeout);
+}
+
+void SettingLevelBubbleViewViews::OnHideTimeout() {
+ GetWidget()->Close();
+}
+
+void SettingLevelBubbleViewViews::OnAnimationTimeout() {
+ const TimeTicks now = TimeTicks::Now();
+ const int64 remaining_ms = (target_time_ - now).InMilliseconds();
+
+ if (remaining_ms <= 0) {
+ current_percent_ = target_percent_;
+ StopAnimation();
+ } else {
+ // Figure out what fraction of the total time until we want to reach the
+ // target has elapsed since the last update.
+ const double remaining_percent = target_percent_ - current_percent_;
+ const int64 elapsed_ms =
+ (now - last_animation_update_time_).InMilliseconds();
+ current_percent_ +=
+ remaining_percent *
+ (static_cast<double>(elapsed_ms) / (elapsed_ms + remaining_ms));
+ }
+ last_animation_update_time_ = now;
+
+ if (view_)
+ view_->SetLevel(current_percent_);
+}
+
+
+void SettingLevelBubbleViewViews::UpdateTargetPercent(double percent) {
+ target_percent_ = LimitPercent(percent);
+ const TimeTicks now = TimeTicks::Now();
+
+ if (current_percent_ < 0.0) {
+ // If we're setting the level for the first time, no need to animate.
+ current_percent_ = target_percent_;
+ if (view_)
+ view_->SetLevel(current_percent_);
+ } else {
+ // Use the time since the last request as a hint for the duration of the
+ // animation. This makes us automatically adapt to the repeat rate if a key
+ // is being held down to change a setting (which prevents us from lagging
+ // behind when the key is finally released).
+ int64 duration_ms = kInitialAnimationDurationMs;
+ if (!last_target_update_time_.is_null())
+ duration_ms = min(kInitialAnimationDurationMs,
+ (now - last_target_update_time_).InMilliseconds());
+ target_time_ = now + TimeDelta::FromMilliseconds(duration_ms);
+
+ if (!is_animating_) {
+ animation_timer_.Start(FROM_HERE,
+ TimeDelta::FromMilliseconds(kAnimationIntervalMs),
+ this,
+ &SettingLevelBubbleViewViews::OnAnimationTimeout);
+ is_animating_ = true;
+ last_animation_update_time_ = now;
+ }
+ }
+
+ last_target_update_time_ = now;
+}
+
+void SettingLevelBubbleViewViews::StopAnimation() {
+ animation_timer_.Stop();
+ is_animating_ = false;
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698