172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 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" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/login/background_view.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/login/login_utils.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" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/bubble/bubble.h" 1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "views/widget/root_view.h" 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace { 2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kBubbleShowTimeoutSec = 2; 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kAnimationDurationMs = 200; 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Horizontal relative position: 0 - leftmost, 0.5 - center, 1 - rightmost. 2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst double kBubbleXRatio = 0.5; 2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Vertical gap from the bottom of the screen in pixels. 2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kBubbleBottomGap = 30; 3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint LimitPercent(int percent) { 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (percent < 0) 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen percent = 0; 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else if (percent > 100) 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen percent = 100; 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return percent; 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace 4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace chromeos { 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Temporary helper routine. Tries to first return the widget from the 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// most-recently-focused normal browser window, then from a login 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// background, and finally NULL if both of those fail. 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(glotov): remove this in favor of enabling Bubble class act 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// without |parent| specified. crosbug.com/4025 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic views::Widget* GetToplevelWidget() { 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkWindow* window = NULL; 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // We just use the default profile here -- this gets overridden as needed 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // in Chrome OS depending on whether the user is logged in or not. 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Browser* browser = 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen BrowserList::FindBrowserWithType( 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProfileManager::GetDefaultProfile(), 5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Browser::TYPE_NORMAL, 5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen true); // match_incognito 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (browser) { 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen window = GTK_WINDOW(browser->window()->GetNativeHandle()); 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Otherwise, see if there's a background window that we can use. 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BackgroundView* background = LoginUtils::Get()->GetBackgroundView(); 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (background) 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen window = GTK_WINDOW(background->GetNativeWindow()); 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!window) 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return NULL; 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget* native_widget = 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::NativeWidget::GetNativeWidgetForNativeWindow(window); 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return native_widget->GetWidget(); 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenSettingLevelBubble::SettingLevelBubble(SkBitmap* increase_icon, 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SkBitmap* decrease_icon, 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SkBitmap* zero_icon) 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : previous_percent_(-1), 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen current_percent_(-1), 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen increase_icon_(increase_icon), 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen decrease_icon_(decrease_icon), 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen zero_icon_(zero_icon), 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bubble_(NULL), 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen view_(NULL), 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen animation_(this) { 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen animation_.SetSlideDuration(kAnimationDurationMs); 873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen animation_.SetTweenType(ui::Tween::LINEAR); 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::ShowBubble(int percent) { 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen percent = LimitPercent(percent); 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (previous_percent_ == -1) 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen previous_percent_ = percent; 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen current_percent_ = percent; 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SkBitmap* icon = increase_icon_; 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (current_percent_ == 0) 9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen icon = zero_icon_; 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen else if (current_percent_ < previous_percent_) 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen icon = decrease_icon_; 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!bubble_) { 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen views::Widget* widget = GetToplevelWidget(); 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (widget == NULL) 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(view_ == NULL); 10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen view_ = new SettingLevelBubbleView; 10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen view_->Init(icon, previous_percent_); 10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Calculate position of the bubble. 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gfx::Rect bounds = widget->GetClientAreaScreenBounds(); 11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const gfx::Size view_size = view_->GetPreferredSize(); 11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Note that (x, y) is the point of the center of the bubble. 11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const int x = view_size.width() / 2 + 11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen kBubbleXRatio * (bounds.width() - view_size.width()); 11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const int y = bounds.height() - view_size.height() / 2 - kBubbleBottomGap; 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bubble_ = Bubble::ShowFocusless(widget, // parent 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect(x, y, 0, 20), 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BubbleBorder::FLOAT, 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen view_, // contents 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this, // delegate 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen true); // show while screen is locked 12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(view_); 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen timeout_timer_.Stop(); 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen view_->SetIcon(icon); 12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (animation_.is_animating()) 12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen animation_.End(); 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen animation_.Reset(); 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen animation_.Show(); 13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen timeout_timer_.Start(base::TimeDelta::FromSeconds(kBubbleShowTimeoutSec), 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen this, &SettingLevelBubble::OnTimeout); 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::HideBubble() { 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (bubble_) 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bubble_->Close(); 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SettingLevelBubble::UpdateWithoutShowingBubble(int percent) { 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen percent = LimitPercent(percent); 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen previous_percent_ = 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen animation_.is_animating() ? 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen animation_.GetCurrentValue() : 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen current_percent_; 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (previous_percent_ < 0) 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen previous_percent_ = percent; 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen current_percent_ = percent; 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (animation_.is_animating()) 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen animation_.End(); 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen animation_.Reset(); 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen animation_.Show(); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SettingLevelBubble::OnTimeout() { 15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HideBubble(); 15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SettingLevelBubble::BubbleClosing(Bubble* bubble, bool) { 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(bubble == bubble_); 16321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen timeout_timer_.Stop(); 16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen animation_.Stop(); 16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bubble_ = NULL; 16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen view_ = NULL; 16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SettingLevelBubble::AnimationEnded(const ui::Animation* animation) { 17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen previous_percent_ = current_percent_; 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SettingLevelBubble::AnimationProgressed(const ui::Animation* animation) { 17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (view_) { 17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen view_->Update( 1763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ui::Tween::ValueBetween(animation->GetCurrentValue(), 1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen previous_percent_, 1783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen current_percent_)); 17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace chromeos 183