// 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/login/helper.h" #include "base/file_util.h" #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/system_access.h" #include "chrome/browser/google/google_util.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas_skia.h" #include "views/controls/button/menu_button.h" #include "views/controls/button/native_button.h" #include "views/controls/label.h" #include "views/controls/textfield/textfield.h" #include "views/controls/throbber.h" #include "views/painter.h" #include "views/screen.h" #include "views/widget/widget.h" #include "views/widget/widget_gtk.h" namespace chromeos { namespace { // Time in ms per throbber frame. const int kThrobberFrameMs = 60; // Time in ms before smoothed throbber is shown. const int kThrobberStartDelayMs = 500; const SkColor kBackgroundCenterColor = SkColorSetRGB(41, 50, 67); const SkColor kBackgroundEdgeColor = SK_ColorBLACK; const char kAccountRecoveryHelpUrl[] = "https://www.google.com/support/accounts/bin/answer.py?answer=48598"; class BackgroundPainter : public views::Painter { public: BackgroundPainter() {} virtual void Paint(int w, int h, gfx::Canvas* canvas) { SkRect rect; rect.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(w), SkIntToScalar(h)); SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); SkColor colors[2] = { kBackgroundCenterColor, kBackgroundEdgeColor }; SkShader* s = SkGradientShader::CreateRadial( SkPoint::Make(SkIntToScalar(w / 2), SkIntToScalar(h / 2)), SkIntToScalar(w / 2), colors, NULL, 2, SkShader::kClamp_TileMode, NULL); paint.setShader(s); s->unref(); canvas->AsCanvasSkia()->drawRect(rect, paint); } private: DISALLOW_COPY_AND_ASSIGN(BackgroundPainter); }; } // namespace ThrobberHostView::ThrobberHostView() : host_view_(this), throbber_widget_(NULL) { } ThrobberHostView::~ThrobberHostView() { StopThrobber(); } void ThrobberHostView::StartThrobber() { StopThrobber(); views::Widget* host_widget = host_view_->GetWidget(); if (!host_widget) { LOG(WARNING) << "Failed to start the throbber: no Widget"; return; } GtkWidget* host_gtk_window = host_widget->GetNativeView(); while (host_gtk_window && !GTK_IS_WINDOW(host_gtk_window)) host_gtk_window = gtk_widget_get_parent(host_gtk_window); if (!host_gtk_window) { LOG(WARNING) << "Failed to start the throbber: no GtkWindow"; return; } views::SmoothedThrobber* throbber = CreateDefaultSmoothedThrobber(); throbber->set_stop_delay_ms(0); gfx::Rect throbber_bounds = CalculateThrobberBounds(throbber); views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_POPUP); params.transparent = true; throbber_widget_ = views::Widget::CreateWidget(params); static_cast<views::WidgetGtk*>(throbber_widget_)->make_transient_to_parent(); throbber_bounds.Offset(host_view_->GetScreenBounds().origin()); throbber_widget_->Init(host_gtk_window, throbber_bounds); throbber_widget_->SetContentsView(throbber); // This keeps the window from flashing at startup. gdk_window_set_back_pixmap( throbber_widget_->GetNativeView()->window, NULL, false); throbber_widget_->Show(); // WM can ignore bounds before widget is shown. throbber_widget_->SetBounds(throbber_bounds); throbber->Start(); } void ThrobberHostView::StopThrobber() { if (throbber_widget_) { throbber_widget_->Close(); throbber_widget_ = NULL; } } gfx::Rect ThrobberHostView::CalculateThrobberBounds(views::Throbber* throbber) { gfx::Rect bounds(throbber->GetPreferredSize()); bounds.set_x( host_view_->width() - login::kThrobberRightMargin - bounds.width()); bounds.set_y((host_view_->height() - bounds.height()) / 2); return bounds; } views::SmoothedThrobber* CreateDefaultSmoothedThrobber() { views::SmoothedThrobber* throbber = new views::SmoothedThrobber(kThrobberFrameMs); throbber->SetFrames( ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SPINNER)); throbber->set_start_delay_ms(kThrobberStartDelayMs); return throbber; } views::Throbber* CreateDefaultThrobber() { views::Throbber* throbber = new views::Throbber(kThrobberFrameMs, false); throbber->SetFrames( ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SPINNER)); return throbber; } views::Painter* CreateBackgroundPainter() { return new BackgroundPainter(); } gfx::Rect CalculateScreenBounds(const gfx::Size& size) { gfx::Rect bounds(views::Screen::GetMonitorWorkAreaNearestWindow(NULL)); if (!size.IsEmpty()) { int horizontal_diff = bounds.width() - size.width(); int vertical_diff = bounds.height() - size.height(); bounds.Inset(horizontal_diff / 2, vertical_diff / 2); } return bounds; } void CorrectLabelFontSize(views::Label* label) { if (label) label->SetFont(label->font().DeriveFont(kFontSizeCorrectionDelta)); } void CorrectMenuButtonFontSize(views::MenuButton* button) { if (button) button->SetFont(button->font().DeriveFont(kFontSizeCorrectionDelta)); } void CorrectNativeButtonFontSize(views::NativeButton* button) { if (button) button->set_font(button->font().DeriveFont(kFontSizeCorrectionDelta)); } void CorrectTextfieldFontSize(views::Textfield* textfield) { if (textfield) textfield->SetFont(textfield->font().DeriveFont(kFontSizeCorrectionDelta)); } void SetAndCorrectTextfieldFont(views::Textfield* textfield, const gfx::Font& font) { if (textfield) textfield->SetFont(font.DeriveFont(kFontSizeCorrectionDelta)); } GURL GetAccountRecoveryHelpUrl() { return google_util::AppendGoogleLocaleParam(GURL(kAccountRecoveryHelpUrl)); } string16 GetCurrentNetworkName(NetworkLibrary* network_library) { if (!network_library) return string16(); if (network_library->ethernet_connected()) { return l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); } else if (network_library->wifi_connected()) { return UTF8ToUTF16(network_library->wifi_network()->name()); } else if (network_library->cellular_connected()) { return UTF8ToUTF16(network_library->cellular_network()->name()); } else if (network_library->ethernet_connecting()) { return l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); } else if (network_library->wifi_connecting()) { return UTF8ToUTF16(network_library->wifi_network()->name()); } else if (network_library->cellular_connecting()) { return UTF8ToUTF16(network_library->cellular_network()->name()); } else { return string16(); } } namespace login { gfx::Size WideButton::GetPreferredSize() { gfx::Size preferred_size = NativeButton::GetPreferredSize(); // Set minimal width. if (preferred_size.width() < kButtonMinWidth) preferred_size.set_width(kButtonMinWidth); return preferred_size; } } // namespace login } // namespace chromeos