summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornkostylev@google.com <nkostylev@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-27 11:08:50 +0000
committernkostylev@google.com <nkostylev@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-27 11:08:50 +0000
commit302cf651a0d929717107fc6a4f1d533074058cfa (patch)
tree43eee8f7825e4df1fb0c5e0942a822c34e53353d
parent68c549897be6b4a479eb09a325bc6019d19d7c20 (diff)
downloadchromium_src-302cf651a0d929717107fc6a4f1d533074058cfa.zip
chromium_src-302cf651a0d929717107fc6a4f1d533074058cfa.tar.gz
chromium_src-302cf651a0d929717107fc6a4f1d533074058cfa.tar.bz2
Show spinner on network response in OOBE welcome screen, account creation screen.
Block buttons/keyboard on login window when sign in is in process. BUG= http://crosbug.com/2573, http://crosbug.com/2528 TEST=Run through OOBE screens and observe spinner when network response is more than 0.5 seconds. Review URL: http://codereview.chromium.org/1755006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45683 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/theme/spinner.pngbin0 -> 14219 bytes
-rw-r--r--chrome/app/theme/theme_resources.grd3
-rw-r--r--chrome/browser/chromeos/login/account_creation_view.cc145
-rw-r--r--chrome/browser/chromeos/login/account_creation_view.h67
-rw-r--r--chrome/browser/chromeos/login/account_screen.cc6
-rw-r--r--chrome/browser/chromeos/login/account_screen.h1
-rw-r--r--chrome/browser/chromeos/login/login_manager_view.cc18
-rw-r--r--chrome/browser/chromeos/login/login_manager_view.h3
-rw-r--r--chrome/browser/chromeos/login/network_selection_view.cc37
-rw-r--r--chrome/browser/chromeos/login/network_selection_view.h2
-rw-r--r--views/controls/throbber.cc21
-rw-r--r--views/controls/throbber.h14
12 files changed, 281 insertions, 36 deletions
diff --git a/chrome/app/theme/spinner.png b/chrome/app/theme/spinner.png
new file mode 100644
index 0000000..e930743
--- /dev/null
+++ b/chrome/app/theme/spinner.png
Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 6ae7e8d..4f57a5b 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -425,7 +425,8 @@
<include name="IDR_COMPACTNAV_BACK" file="compactnav_back.png" type="BINDATA" />
<include name="IDR_COMPACTNAV_FORWARD" file="compactnav_forward.png" type="BINDATA" />
<include name="IDR_COMPACTNAV_SEPARATOR" file="compactnav_separator.png" type="BINDATA" />
-
+
+ <include name="IDR_SPINNER" file="spinner.png" type="BINDATA" />
<include name="IDR_STATUSBAR_MENU" file="statusbar_menu.png" type="BINDATA" />
<include name="IDR_STATUSBAR_BATTERY_CHARGED" file="statusbar_battery_charged.png" type="BINDATA" />
<include name="IDR_STATUSBAR_BATTERY_MISSING" file="statusbar_battery_missing.png" type="BINDATA" />
diff --git a/chrome/browser/chromeos/login/account_creation_view.cc b/chrome/browser/chromeos/login/account_creation_view.cc
index 1af6c06..192880a 100644
--- a/chrome/browser/chromeos/login/account_creation_view.cc
+++ b/chrome/browser/chromeos/login/account_creation_view.cc
@@ -4,8 +4,11 @@
#include "chrome/browser/chromeos/login/account_creation_view.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
#include "base/callback.h"
#include "base/string_util.h"
+#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/chromeos/login/rounded_rect_painter.h"
@@ -13,12 +16,34 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/bindings_policy.h"
#include "gfx/canvas.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
#include "ipc/ipc_message.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "views/background.h"
#include "views/border.h"
+#include "views/controls/label.h"
+#include "views/controls/throbber.h"
#include "webkit/glue/form_data.h"
+using base::TimeDelta;
+using views::Label;
+using views::Throbber;
+using views::View;
using webkit_glue::FormData;
+// Spacing (vertical/horizontal) between controls.
+const int kSpacing = 10;
+
+// Time in ms per throbber frame.
+const int kThrobberFrameMs = 60;
+
+// Time in ms after that waiting controls are shown on Start.
+const int kStartDelayMs = 500;
+
+// Time in ms after that waiting controls are hidden Stop.
+const int kStopDelayMs = 500;
+
namespace chromeos {
const char kCreateAccountFormName[] = "createaccount";
@@ -92,6 +117,10 @@ class AccountCreationTabContents : public TabContents,
delegate_->OnPageLoadFailed(security_origin);
}
+ virtual void DocumentLoadedInFrame() {
+ delegate_->OnPageLoaded();
+ }
+
virtual void OnContentBlocked(ContentSettingsType type) {
delegate_->OnPageLoadFailed("");
}
@@ -103,45 +132,133 @@ class AccountCreationTabContents : public TabContents,
};
///////////////////////////////////////////////////////////////////////////////
+// AccountCreationDomView, public:
+
+AccountCreationDomView::AccountCreationDomView() : delegate_(NULL) {
+}
+
+AccountCreationDomView::~AccountCreationDomView() {
+}
+
+void AccountCreationDomView::SetAccountCreationViewDelegate(
+ AccountCreationViewDelegate* delegate) {
+ delegate_ = delegate;
+}
+
+void AccountCreationDomView::SetTabContentsDelegate(
+ TabContentsDelegate* delegate) {
+ tab_contents_->set_delegate(delegate);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// AccountCreationDomView, DOMView implementation:
+
+TabContents* AccountCreationDomView::CreateTabContents(Profile* profile,
+ SiteInstance* instance) {
+ return new AccountCreationTabContents(profile, instance, delegate_);
+}
+
+///////////////////////////////////////////////////////////////////////////////
// AccountCreationView, public:
-AccountCreationView::AccountCreationView() : delegate_(NULL) {
+
+AccountCreationView::AccountCreationView()
+ : dom_view_(new AccountCreationDomView()),
+ throbber_(NULL),
+ connecting_label_(NULL) {
}
AccountCreationView::~AccountCreationView() {
}
void AccountCreationView::Init() {
- // Use rounded rect background.
- views::Border* border = chromeos::CreateWizardBorder(
- &chromeos::BorderDefinition::kScreenBorder);
- set_border(border);
+ chromeos::CreateWizardBorder(
+ &chromeos::BorderDefinition::kScreenBorder)->GetInsets(&insets_);
+ views::Painter* painter = CreateWizardPainter(
+ &BorderDefinition::kScreenBorder);
+ set_background(
+ views::Background::CreateBackgroundPainter(true, painter));
+ dom_view_->SetVisible(false);
+ AddChildView(dom_view_);
+
+ throbber_ = new views::Throbber(kThrobberFrameMs, false);
+ throbber_->SetFrames(
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SPINNER));
+ AddChildView(throbber_);
+
+ connecting_label_ = new views::Label();
+ connecting_label_->SetText(l10n_util::GetString(IDS_LOAD_STATE_CONNECTING));
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ connecting_label_->SetFont(rb.GetFont(ResourceBundle::MediumFont));
+ connecting_label_->SetVisible(false);
+ AddChildView(connecting_label_ );
+
+ start_timer_.Start(TimeDelta::FromMilliseconds(kStartDelayMs),
+ this,
+ &AccountCreationView::ShowWaitingControls);
}
void AccountCreationView::InitDOM(Profile* profile,
SiteInstance* site_instance) {
- DOMView::Init(profile, site_instance);
+ dom_view_->Init(profile, site_instance);
}
-TabContents* AccountCreationView::CreateTabContents(Profile* profile,
- SiteInstance* instance) {
- return new AccountCreationTabContents(profile, instance, delegate_);
+void AccountCreationView::LoadURL(const GURL& url) {
+ dom_view_->LoadURL(url);
}
void AccountCreationView::SetTabContentsDelegate(
TabContentsDelegate* delegate) {
- tab_contents_->set_delegate(delegate);
+ dom_view_->SetTabContentsDelegate(delegate);
}
void AccountCreationView::SetAccountCreationViewDelegate(
AccountCreationViewDelegate* delegate) {
- delegate_ = delegate;
+ dom_view_->SetAccountCreationViewDelegate(delegate);
+}
+
+void AccountCreationView::ShowPageContent() {
+ // TODO(nkostylev): Show throbber as an overlay until page has been rendered.
+ start_timer_.Stop();
+ if (!stop_timer_.IsRunning()) {
+ stop_timer_.Start(TimeDelta::FromMilliseconds(kStopDelayMs),
+ this,
+ &AccountCreationView::ShowRenderedPage);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// AccountCreationView, private:
+
+void AccountCreationView::ShowRenderedPage() {
+ throbber_->Stop();
+ connecting_label_->SetVisible(false);
+ dom_view_->SetVisible(true);
+}
+
+void AccountCreationView::ShowWaitingControls() {
+ throbber_->Start();
+ connecting_label_->SetVisible(true);
}
///////////////////////////////////////////////////////////////////////////////
// AccountCreationView, views::View implementation:
-void AccountCreationView::Paint(gfx::Canvas* canvas) {
- PaintBorder(canvas);
- DOMView::Paint(canvas);
+
+void AccountCreationView::Layout() {
+ dom_view_->SetBounds(insets_.left(),
+ insets_.top(),
+ bounds().width() - insets_.left() - insets_.right(),
+ bounds().height() - insets_.top() - insets_.bottom());
+ int y = height() / 2 - throbber_->GetPreferredSize().height() / 2;
+ throbber_->SetBounds(
+ width() / 2 - throbber_->GetPreferredSize().width() / 2,
+ y,
+ throbber_->GetPreferredSize().width(),
+ throbber_->GetPreferredSize().height());
+ connecting_label_->SetBounds(
+ width() / 2 - connecting_label_->GetPreferredSize().width() / 2,
+ y + throbber_->GetPreferredSize().height() + kSpacing,
+ connecting_label_->GetPreferredSize().width(),
+ connecting_label_->GetPreferredSize().height());
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/account_creation_view.h b/chrome/browser/chromeos/login/account_creation_view.h
index 7692e5b..7ce943d 100644
--- a/chrome/browser/chromeos/login/account_creation_view.h
+++ b/chrome/browser/chromeos/login/account_creation_view.h
@@ -7,12 +7,19 @@
#include <string>
+#include "base/timer.h"
#include "chrome/browser/views/dom_view.h"
+#include "views/view.h"
class Profile;
class SiteContents;
class TabContentsDelegate;
+namespace views {
+class Label;
+class Throbber;
+} // namespace views
+
namespace chromeos {
class AccountCreationViewDelegate {
@@ -25,11 +32,36 @@ class AccountCreationViewDelegate {
virtual void OnUserCreated(const std::string& username,
const std::string& password) = 0;
+ // Notify about document load event.
+ virtual void OnPageLoaded() = 0;
+
// Notify about navigation errors.
virtual void OnPageLoadFailed(const std::string& url) = 0;
};
-class AccountCreationView : public DOMView {
+class AccountCreationDomView : public DOMView {
+ public:
+ AccountCreationDomView();
+ virtual ~AccountCreationDomView();
+
+ // Set delegate that will be notified about user actions.
+ void SetAccountCreationViewDelegate(AccountCreationViewDelegate* delegate);
+
+ // Set delegate that will be notified about tab contents changes.
+ void SetTabContentsDelegate(TabContentsDelegate* delegate);
+
+ protected:
+ // Overriden from DOMView:
+ virtual TabContents* CreateTabContents(Profile* profile,
+ SiteInstance* instance);
+
+ private:
+ AccountCreationViewDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(AccountCreationDomView);
+};
+
+class AccountCreationView : public views::View {
public:
AccountCreationView();
virtual ~AccountCreationView();
@@ -38,21 +70,42 @@ class AccountCreationView : public DOMView {
void Init();
void InitDOM(Profile* profile, SiteInstance* site_instance);
+ void LoadURL(const GURL& url);
void SetTabContentsDelegate(TabContentsDelegate* delegate);
// Set delegate that will be notified about user actions.
void SetAccountCreationViewDelegate(AccountCreationViewDelegate* delegate);
- protected:
- // Overriden from DOMView:
- virtual TabContents* CreateTabContents(Profile* profile,
- SiteInstance* instance);
+ // Stops throbber and shows page content (starts renderer_timer_ for that).
+ void ShowPageContent();
private:
// Overriden from views::View:
- virtual void Paint(gfx::Canvas* canvas);
+ virtual void Layout();
- AccountCreationViewDelegate* delegate_;
+ // Called by stop_timer_. Shows rendered page.
+ void ShowRenderedPage();
+
+ // Called by start_timer_. Shows throbber and waiting label.
+ void ShowWaitingControls();
+
+ // View that renderes account creation page.
+ AccountCreationDomView* dom_view_;
+
+ // Screen border insets. Used for layout.
+ gfx::Insets insets_;
+
+ // Throbber shown during page load.
+ views::Throbber* throbber_;
+
+ // "Connecting..." label shown while waiting for the page to load/render.
+ views::Label* connecting_label_;
+
+ // Timer used when waiting for network response.
+ base::OneShotTimer<AccountCreationView> start_timer_;
+
+ // Timer used before toggling loaded page visibility.
+ base::OneShotTimer<AccountCreationView> stop_timer_;
DISALLOW_COPY_AND_ASSIGN(AccountCreationView);
};
diff --git a/chrome/browser/chromeos/login/account_screen.cc b/chrome/browser/chromeos/login/account_screen.cc
index e7abdce..c0cb17d 100644
--- a/chrome/browser/chromeos/login/account_screen.cc
+++ b/chrome/browser/chromeos/login/account_screen.cc
@@ -130,11 +130,17 @@ bool AccountScreen::HandleContextMenu(const ContextMenuParams& params) {
return true;
}
+///////////////////////////////////////////////////////////////////////////////
+// AccountScreen, AccountCreationViewDelegate implementation:
void AccountScreen::OnUserCreated(const std::string& username,
const std::string& password) {
delegate()->GetObserver(this)->OnSetUserNamePassword(username, password);
}
+void AccountScreen::OnPageLoaded() {
+ view()->ShowPageContent();
+}
+
void AccountScreen::OnPageLoadFailed(const std::string& url) {
delegate()->GetObserver(this)->OnExit(ScreenObserver::CONNECTION_FAILED);
}
diff --git a/chrome/browser/chromeos/login/account_screen.h b/chrome/browser/chromeos/login/account_screen.h
index 95de5dc..058d6f0 100644
--- a/chrome/browser/chromeos/login/account_screen.h
+++ b/chrome/browser/chromeos/login/account_screen.h
@@ -27,6 +27,7 @@ class AccountScreen : public ViewScreen<AccountCreationView>,
// AccountCreationViewDelegate implementation:
virtual void OnUserCreated(const std::string& username,
const std::string& password);
+ virtual void OnPageLoaded();
virtual void OnPageLoadFailed(const std::string& url);
// Sets the url for account creation. Used in tests.
diff --git a/chrome/browser/chromeos/login/login_manager_view.cc b/chrome/browser/chromeos/login/login_manager_view.cc
index 060970d..77878d7 100644
--- a/chrome/browser/chromeos/login/login_manager_view.cc
+++ b/chrome/browser/chromeos/login/login_manager_view.cc
@@ -32,7 +32,6 @@
#include "chrome/browser/profile_manager.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
#include "views/controls/button/native_button.h"
#include "views/controls/label.h"
#include "views/widget/widget.h"
@@ -78,12 +77,14 @@ LoginManagerView::LoginManagerView(ScreenObserver* observer)
error_label_(NULL),
sign_in_button_(NULL),
create_account_link_(NULL),
+ languages_menubutton_(NULL),
accel_focus_user_(views::Accelerator(base::VKEY_U, false, false, true)),
accel_focus_pass_(views::Accelerator(base::VKEY_P, false, false, true)),
observer_(observer),
error_id_(-1),
ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)),
- focus_delayed_(false) {
+ focus_delayed_(false),
+ login_in_process_(false) {
// Create login observer to record time of login when successful.
LogLoginSuccessObserver::Get();
if (kStubOutLogin)
@@ -163,6 +164,7 @@ void LoginManagerView::Init() {
ASCIIToWide(CrosLibrary::Get()->load_error_string()));
username_field_->SetReadOnly(true);
password_field_->SetReadOnly(true);
+ sign_in_button_->SetEnabled(false);
}
}
@@ -310,6 +312,12 @@ void LoginManagerView::SetPassword(const std::string& password) {
}
void LoginManagerView::Login() {
+ if (login_in_process_) {
+ return;
+ }
+ login_in_process_ = true;
+ sign_in_button_->SetEnabled(false);
+ create_account_link_->SetEnabled(false);
// Disallow 0 size username.
if (username_field_->text().empty()) {
// Return true so that processing ends
@@ -364,6 +372,9 @@ void LoginManagerView::OnLoginFailure(const std::string& error) {
ShowError(IDS_LOGIN_ERROR_AUTHENTICATING);
// TODO(someone): get |error| onto the UI somehow?
}
+ login_in_process_ = false;
+ sign_in_button_->SetEnabled(true);
+ create_account_link_->SetEnabled(true);
SetPassword(std::string());
password_field_->RequestFocus();
}
@@ -390,6 +401,9 @@ bool LoginManagerView::HandleKeystroke(views::Textfield* s,
if (!kStubOutLogin && !CrosLibrary::Get()->EnsureLoaded())
return false;
+ if (login_in_process_)
+ return false;
+
if (keystroke.GetKeyboardCode() == base::VKEY_TAB) {
if (username_field_->text().length() != 0) {
std::string username = UTF16ToUTF8(username_field_->text());
diff --git a/chrome/browser/chromeos/login/login_manager_view.h b/chrome/browser/chromeos/login/login_manager_view.h
index 540262a..14aa02a 100644
--- a/chrome/browser/chromeos/login/login_manager_view.h
+++ b/chrome/browser/chromeos/login/login_manager_view.h
@@ -148,6 +148,9 @@ class LoginManagerView : public views::View,
// (on the hidden tab, for example).
bool focus_delayed_;
+ // True when login is in process.
+ bool login_in_process_;
+
scoped_refptr<Authenticator> authenticator_;
LanguageSwitchModel language_switch_model_;
diff --git a/chrome/browser/chromeos/login/network_selection_view.cc b/chrome/browser/chromeos/login/network_selection_view.cc
index 986b2b1..c822e68 100644
--- a/chrome/browser/chromeos/login/network_selection_view.cc
+++ b/chrome/browser/chromeos/login/network_selection_view.cc
@@ -16,9 +16,11 @@
#include "chrome/browser/chromeos/login/language_switch_model.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
#include "views/controls/button/native_button.h"
#include "views/controls/combobox/combobox.h"
#include "views/controls/label.h"
+#include "views/controls/throbber.h"
#include "views/widget/widget.h"
#include "views/widget/widget_gtk.h"
#include "views/window/non_client_view.h"
@@ -27,6 +29,7 @@
using views::Background;
using views::Label;
+using views::SmoothedThrobber;
using views::View;
using views::Widget;
using views::WidgetGtk;
@@ -36,7 +39,6 @@ namespace {
const int kWelcomeLabelY = 150;
const int kOfflineButtonX = 30;
const int kSpacing = 25;
-const int kComboboxSpacing = 5;
const int kHorizontalSpacing = 25;
const int kNetworkComboboxWidth = 250;
const int kNetworkComboboxHeight = 30;
@@ -44,6 +46,9 @@ const int kLanguagesMenuWidth = 200;
const int kLanguagesMenuHeight = 30;
const SkColor kWelcomeColor = 0xFF1D6AB1;
+const int kThrobberFrameMs = 60;
+const int kThrobberStartDelayMs = 500;
+
} // namespace
namespace chromeos {
@@ -54,6 +59,8 @@ NetworkSelectionView::NetworkSelectionView(NetworkScreenDelegate* delegate)
welcome_label_(NULL),
select_network_label_(NULL),
connecting_network_label_(NULL),
+ offline_button_(NULL),
+ throbber_(NULL),
delegate_(delegate) {
}
@@ -79,8 +86,15 @@ void NetworkSelectionView::Init() {
select_network_label_->SetFont(rb.GetFont(ResourceBundle::MediumFont));
connecting_network_label_ = new views::Label();
+ connecting_network_label_->SetFont(rb.GetFont(ResourceBundle::MediumFont));
connecting_network_label_->SetVisible(false);
+ throbber_ = new views::SmoothedThrobber(kThrobberFrameMs);
+ throbber_->SetFrames(
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SPINNER));
+ throbber_->set_start_delay_ms(kThrobberStartDelayMs);
+ AddChildView(throbber_);
+
network_combobox_ = new views::Combobox(delegate_);
network_combobox_->set_listener(delegate_);
@@ -148,9 +162,18 @@ void NetworkSelectionView::Layout() {
width() - kHorizontalSpacing * 2,
connecting_network_label_->GetPreferredSize().height());
- select_network_x += select_network_label_->GetPreferredSize().width() +
- kHorizontalSpacing;
- y -= kComboboxSpacing;
+ throbber_->SetBounds(
+ width() / 2 + connecting_network_label_->GetPreferredSize().width() / 2 +
+ kHorizontalSpacing,
+ y + (connecting_network_label_->GetPreferredSize().height() -
+ throbber_->GetPreferredSize().height()) / 2,
+ throbber_->GetPreferredSize().width(),
+ throbber_->GetPreferredSize().height());
+
+ select_network_x +=
+ select_network_label_->GetPreferredSize().width() + kHorizontalSpacing;
+ y += (select_network_label_->GetPreferredSize().height() -
+ network_combobox_->GetPreferredSize().height()) / 2;
network_combobox_->SetBounds(select_network_x, y,
kNetworkComboboxWidth, kNetworkComboboxHeight);
@@ -198,6 +221,12 @@ void NetworkSelectionView::ShowConnectingStatus(bool connecting,
select_network_label_->SetVisible(!connecting);
network_combobox_->SetVisible(!connecting);
connecting_network_label_->SetVisible(connecting);
+ Layout();
+ if (connecting) {
+ throbber_->Start();
+ } else {
+ throbber_->Stop();
+ }
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/login/network_selection_view.h b/chrome/browser/chromeos/login/network_selection_view.h
index 268453b..56b60b2 100644
--- a/chrome/browser/chromeos/login/network_selection_view.h
+++ b/chrome/browser/chromeos/login/network_selection_view.h
@@ -16,6 +16,7 @@ namespace views {
class Combobox;
class Label;
class NativeButton;
+class SmoothedThrobber;
} // namespace views
namespace chromeos {
@@ -66,6 +67,7 @@ class NetworkSelectionView : public views::View {
views::Label* select_network_label_;
views::Label* connecting_network_label_;
views::NativeButton* offline_button_;
+ views::SmoothedThrobber* throbber_;
// NetworkScreen delegate.
NetworkScreenDelegate* delegate_;
diff --git a/views/controls/throbber.cc b/views/controls/throbber.cc
index bc5fa04..112f43b 100644
--- a/views/controls/throbber.cc
+++ b/views/controls/throbber.cc
@@ -21,11 +21,7 @@ Throbber::Throbber(int frame_time_ms,
paint_while_stopped_(paint_while_stopped),
frames_(NULL),
frame_time_(TimeDelta::FromMilliseconds(frame_time_ms)) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
- frames_ = rb.GetBitmapNamed(IDR_THROBBER);
- DCHECK(frames_->width() > 0 && frames_->height() > 0);
- DCHECK(frames_->width() % frames_->height() == 0);
- frame_count_ = frames_->width() / frames_->height();
+ SetFrames(ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_THROBBER));
}
Throbber::~Throbber() {
@@ -56,6 +52,13 @@ void Throbber::Stop() {
SchedulePaint(); // Important if we're not painting while stopped
}
+void Throbber::SetFrames(SkBitmap* frames) {
+ frames_ = frames;
+ DCHECK(frames_->width() > 0 && frames_->height() > 0);
+ DCHECK(frames_->width() % frames_->height() == 0);
+ frame_count_ = frames_->width() / frames_->height();
+}
+
void Throbber::Run() {
DCHECK(running_);
@@ -95,14 +98,16 @@ static const int kStopDelay = 50;
SmoothedThrobber::SmoothedThrobber(int frame_time_ms)
- : Throbber(frame_time_ms, /* paint_while_stopped= */ false) {
+ : Throbber(frame_time_ms, /* paint_while_stopped= */ false),
+ start_delay_ms_(kStartDelay),
+ stop_delay_ms_(kStopDelay) {
}
void SmoothedThrobber::Start() {
stop_timer_.Stop();
if (!running_ && !start_timer_.IsRunning()) {
- start_timer_.Start(TimeDelta::FromMilliseconds(kStartDelay), this,
+ start_timer_.Start(TimeDelta::FromMilliseconds(start_delay_ms_), this,
&SmoothedThrobber::StartDelayOver);
}
}
@@ -116,7 +121,7 @@ void SmoothedThrobber::Stop() {
start_timer_.Stop();
stop_timer_.Stop();
- stop_timer_.Start(TimeDelta::FromMilliseconds(kStopDelay), this,
+ stop_timer_.Start(TimeDelta::FromMilliseconds(stop_delay_ms_), this,
&SmoothedThrobber::StopDelayOver);
}
diff --git a/views/controls/throbber.h b/views/controls/throbber.h
index 53d669f..e5d0490 100644
--- a/views/controls/throbber.h
+++ b/views/controls/throbber.h
@@ -23,12 +23,16 @@ class Throbber : public View {
// If |paint_while_stopped| is false, this view will be invisible when not
// running.
Throbber(int frame_time_ms, bool paint_while_stopped);
+ Throbber(int frame_time_ms, bool paint_while_stopped, SkBitmap* frames);
virtual ~Throbber();
// Start and stop the throbber animation
virtual void Start();
virtual void Stop();
+ // Set custom throbber frames. Otherwise IDR_THROBBER is loaded.
+ void SetFrames(SkBitmap* frames);
+
// overridden from View
virtual gfx::Size GetPreferredSize();
virtual void Paint(gfx::Canvas* canvas);
@@ -57,10 +61,14 @@ class Throbber : public View {
class SmoothedThrobber : public Throbber {
public:
SmoothedThrobber(int frame_delay_ms);
+ SmoothedThrobber(int frame_delay_ms, SkBitmap* frames);
virtual void Start();
virtual void Stop();
+ void set_start_delay_ms(int value) { start_delay_ms_ = value; }
+ void set_stop_delay_ms(int value) { stop_delay_ms_ = value; }
+
private:
// Called when the startup-delay timer fires
// This function starts the actual throbbing.
@@ -70,6 +78,12 @@ class SmoothedThrobber : public Throbber {
// This function stops the actual throbbing.
void StopDelayOver();
+ // Delay after work starts before starting throbber, in milliseconds.
+ int start_delay_ms_;
+
+ // Delay after work stops before stopping, in milliseconds.
+ int stop_delay_ms_;
+
base::OneShotTimer<SmoothedThrobber> start_timer_;
base::OneShotTimer<SmoothedThrobber> stop_timer_;