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

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

Issue 7646004: chromeos: Improve brightness and volume animations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: hopefully fix windows compile and DCHECK Created 9 years, 4 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
« no previous file with comments | « chrome/browser/chromeos/setting_level_bubble.h ('k') | chrome/browser/chromeos/setting_level_bubble_view.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/setting_level_bubble.cc
diff --git a/chrome/browser/chromeos/setting_level_bubble.cc b/chrome/browser/chromeos/setting_level_bubble.cc
index 3f467aec3ef9c2b75a495030a69c7ce1a7238c48..4320ea180bd7c104ae2d8d0375988151fac3e9a8 100644
--- a/chrome/browser/chromeos/setting_level_bubble.cc
+++ b/chrome/browser/chromeos/setting_level_bubble.cc
@@ -4,9 +4,10 @@
#include "chrome/browser/chromeos/setting_level_bubble.h"
+#include <algorithm>
+
#include <gdk/gdk.h>
-#include "base/timer.h"
#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"
@@ -19,10 +20,19 @@
#include "ui/gfx/screen.h"
#include "views/widget/root_view.h"
+using base::TimeDelta;
+using base::TimeTicks;
+using std::max;
+using std::min;
+
namespace {
-const int kBubbleShowTimeoutSec = 2;
-const int kAnimationDurationMs = 200;
+// 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.
@@ -31,12 +41,12 @@ const double kBubbleXRatio = 0.5;
// Vertical gap from the bottom of the screen in pixels.
const int kBubbleBottomGap = 30;
-int LimitPercent(int percent) {
- if (percent < 0)
- percent = 0;
- else if (percent > 100)
- percent = 100;
- return percent;
+// 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
@@ -75,30 +85,26 @@ static views::Widget* GetToplevelWidget() {
SettingLevelBubble::SettingLevelBubble(SkBitmap* increase_icon,
SkBitmap* decrease_icon,
SkBitmap* disabled_icon)
- : previous_percent_(-1),
- current_percent_(-1),
+ : current_percent_(-1.0),
+ target_percent_(-1.0),
increase_icon_(increase_icon),
decrease_icon_(decrease_icon),
disabled_icon_(disabled_icon),
bubble_(NULL),
view_(NULL),
- animation_(this) {
- animation_.SetSlideDuration(kAnimationDurationMs);
- animation_.SetTweenType(ui::Tween::LINEAR);
+ is_animating_(false) {
}
SettingLevelBubble::~SettingLevelBubble() {}
-void SettingLevelBubble::ShowBubble(int percent, bool enabled) {
- percent = LimitPercent(percent);
- if (previous_percent_ == -1)
- previous_percent_ = percent;
- current_percent_ = percent;
+void SettingLevelBubble::ShowBubble(double percent, bool enabled) {
+ const double old_target_percent = target_percent_;
+ UpdateTargetPercent(percent);
SkBitmap* icon = increase_icon_;
- if (!enabled || current_percent_ == 0)
+ if (!enabled || target_percent_ == 0)
icon = disabled_icon_;
- else if (current_percent_ < previous_percent_)
+ else if (old_target_percent >= 0 && target_percent_ < old_target_percent)
icon = decrease_icon_;
if (!bubble_) {
@@ -109,7 +115,7 @@ void SettingLevelBubble::ShowBubble(int percent, bool enabled) {
}
DCHECK(view_ == NULL);
view_ = new SettingLevelBubbleView;
- view_->Init(icon, previous_percent_, enabled);
+ view_->Init(icon, current_percent_, enabled);
// Calculate the position in screen coordinates that the bubble should
// "point" at (since we use BubbleBorder::FLOAT, this position actually
@@ -123,29 +129,27 @@ void SettingLevelBubble::ShowBubble(int percent, bool enabled) {
monitor_area.bottom() - view_size.height() / 2 - kBubbleBottomGap,
0, 0);
- // ShowFocusless doesn't set ESC accelerator.
bubble_ = Bubble::ShowFocusless(parent_widget,
position_relative_to,
BubbleBorder::FLOAT,
view_, // contents
this, // delegate
true); // show while screen is locked
- bubble_->set_fade_away_on_close(true);
+ // TODO(derat): We probably shouldn't be using Bubble. It'd be nice to call
+ // bubble_->set_fade_away_on_close(true) here, but then, if ShowBubble()
+ // gets called while the bubble is fading away, we end up just adjusting the
+ // value on the disappearing bubble; ideally we'd have a way to cancel the
+ // fade and show the bubble at full opacity for another
+ // kBubbleShowTimeoutMs.
} else {
DCHECK(view_);
- timeout_timer_.Stop();
+ hide_timer_.Stop();
view_->SetIcon(icon);
+ view_->SetEnabled(enabled);
}
- view_->SetEnabled(enabled);
-
- if (animation_.is_animating())
- animation_.End();
- animation_.Reset();
- animation_.Show();
-
- timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec),
- this, &SettingLevelBubble::OnTimeout);
+ hide_timer_.Start(base::TimeDelta::FromMilliseconds(kBubbleShowTimeoutMs),
+ this, &SettingLevelBubble::OnHideTimeout);
}
void SettingLevelBubble::HideBubble() {
@@ -153,36 +157,51 @@ void SettingLevelBubble::HideBubble() {
bubble_->Close();
}
-void SettingLevelBubble::UpdateWithoutShowingBubble(int percent, bool enabled) {
+void SettingLevelBubble::UpdateWithoutShowingBubble(double percent,
+ bool enabled) {
+ UpdateTargetPercent(percent);
if (view_)
view_->SetEnabled(enabled);
+}
- percent = LimitPercent(percent);
+void SettingLevelBubble::OnHideTimeout() {
+ HideBubble();
+}
- previous_percent_ =
- animation_.is_animating() ?
- animation_.GetCurrentValue() :
- current_percent_;
- if (previous_percent_ < 0)
- previous_percent_ = percent;
- current_percent_ = percent;
+void SettingLevelBubble::OnAnimationTimeout() {
+ const TimeTicks now = TimeTicks::Now();
+ const int64 remaining_ms = (target_time_ - now).InMilliseconds();
- if (animation_.is_animating())
- animation_.End();
- animation_.Reset();
- animation_.Show();
-}
+ 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;
-void SettingLevelBubble::OnTimeout() {
- HideBubble();
+ if (view_)
+ view_->SetLevel(current_percent_);
}
void SettingLevelBubble::BubbleClosing(Bubble* bubble, bool) {
DCHECK(bubble == bubble_);
- timeout_timer_.Stop();
- animation_.Stop();
+ hide_timer_.Stop();
+ StopAnimation();
bubble_ = NULL;
view_ = NULL;
+ current_percent_ = -1.0;
+ target_percent_ = -1.0;
+ target_time_ = TimeTicks();
+ last_animation_update_time_ = TimeTicks();
+ last_target_update_time_ = TimeTicks();
}
bool SettingLevelBubble::CloseOnEscape() {
@@ -193,17 +212,41 @@ bool SettingLevelBubble::FadeInOnShow() {
return false;
}
-void SettingLevelBubble::AnimationEnded(const ui::Animation* animation) {
- previous_percent_ = current_percent_;
-}
+void SettingLevelBubble::UpdateTargetPercent(double percent) {
+ target_percent_ = LimitPercent(percent);
+ const TimeTicks now = TimeTicks::Now();
-void SettingLevelBubble::AnimationProgressed(const ui::Animation* animation) {
- if (view_) {
- view_->SetLevel(
- ui::Tween::ValueBetween(animation->GetCurrentValue(),
- previous_percent_,
- current_percent_));
+ 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(TimeDelta::FromMilliseconds(kAnimationIntervalMs),
+ this,
+ &SettingLevelBubble::OnAnimationTimeout);
+ is_animating_ = true;
+ last_animation_update_time_ = now;
+ }
}
+
+ last_target_update_time_ = now;
+}
+
+void SettingLevelBubble::StopAnimation() {
+ animation_timer_.Stop();
+ is_animating_ = false;
}
} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/setting_level_bubble.h ('k') | chrome/browser/chromeos/setting_level_bubble_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698