setting_level_bubble.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved.
221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be
321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file.
421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/setting_level_bubble.h"
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <gdk/gdk.h>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/timer.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/browser_list.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/browser_window.h"
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/setting_level_bubble_view.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/browser.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/views/info_bubble.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "views/widget/root_view.h"
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace {
1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kBubbleShowTimeoutSec = 2;
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kAnimationDurationMs = 200;
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Horizontal relative position: 0 - leftmost, 0.5 - center, 1 - rightmost.
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst double kBubbleXRatio = 0.5;
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Vertical gap from the bottom of the screen in pixels.
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kBubbleBottomGap = 30;
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace chromeos {
3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Temporary helper routine. Returns the widget from the most-recently-focused
3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// normal browser window or NULL.
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(glotov): remove this in favor of enabling InfoBubble class act
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// without |parent| specified. crosbug.com/4025
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic views::Widget* GetToplevelWidget() {
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // We just use the default profile here -- this gets overridden as needed
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // in Chrome OS depending on whether the user is logged in or not.
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Browser* browser =
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      BrowserList::FindBrowserWithType(
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          ProfileManager::GetDefaultProfile(),
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          Browser::TYPE_NORMAL,
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          true);  // match_incognito
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!browser)
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return NULL;
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  views::RootView* root =
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      views::Widget::FindRootView(
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          GTK_WINDOW(browser->window()->GetNativeHandle()));
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(root);
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!root)
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return NULL;
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return root->GetWidget();
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenSettingLevelBubble::SettingLevelBubble(SkBitmap* increase_icon,
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       SkBitmap* decrease_icon,
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       SkBitmap* zero_icon)
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    : previous_percent_(-1),
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      current_percent_(-1),
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      increase_icon_(increase_icon),
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      decrease_icon_(decrease_icon),
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      zero_icon_(zero_icon),
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      bubble_(NULL),
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      view_(NULL),
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      animation_(this) {
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  animation_.SetSlideDuration(kAnimationDurationMs);
703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  animation_.SetTweenType(ui::Tween::LINEAR);
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::ShowBubble(int percent) {
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (percent < 0)
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    percent = 0;
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (percent > 100)
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    percent = 100;
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (previous_percent_ == -1)
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    previous_percent_ = percent;
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  current_percent_ = percent;
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SkBitmap* icon = increase_icon_;
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (current_percent_ == 0)
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    icon = zero_icon_;
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  else if (current_percent_ < previous_percent_)
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    icon = decrease_icon_;
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!bubble_) {
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    views::Widget* widget = GetToplevelWidget();
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (widget == NULL)
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(view_ == NULL);
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    view_ = new SettingLevelBubbleView;
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    view_->Init(icon, previous_percent_);
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Calculate position of the bubble.
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    gfx::Rect bounds;
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    widget->GetBounds(&bounds, false);
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const gfx::Size view_size = view_->GetPreferredSize();
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Note that (x, y) is the point of the center of the bubble.
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const int x = view_size.width() / 2 +
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        kBubbleXRatio * (bounds.width() - view_size.width());
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const int y = bounds.height() - view_size.height() / 2 - kBubbleBottomGap;
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bubble_ = InfoBubble::ShowFocusless(widget,  // parent
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        gfx::Rect(x, y, 0, 20),
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        BubbleBorder::FLOAT,
10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        view_,  // contents
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        this,   // delegate
10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        true);  // show while screen is locked
10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(view_);
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    timeout_timer_.Stop();
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    view_->SetIcon(icon);
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (animation_.is_animating())
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    animation_.End();
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  animation_.Reset();
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  animation_.Show();
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec),
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                       this, &SettingLevelBubble::OnTimeout);
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::HideBubble() {
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (bubble_)
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bubble_->Close();
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::OnTimeout() {
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  HideBubble();
12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool) {
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(info_bubble == bubble_);
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  timeout_timer_.Stop();
13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  animation_.Stop();
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bubble_ = NULL;
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  view_ = NULL;
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SettingLevelBubble::AnimationEnded(const ui::Animation* animation) {
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  previous_percent_ = current_percent_;
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SettingLevelBubble::AnimationProgressed(const ui::Animation* animation) {
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (view_) {
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    view_->Update(
1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        ui::Tween::ValueBetween(animation->GetCurrentValue(),
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                previous_percent_,
1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                current_percent_));
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace chromeos
153