Home | History | Annotate | Download | only in login
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/login/helper.h"
      6 
      7 #include "base/file_util.h"
      8 #include "chrome/browser/chromeos/cros/network_library.h"
      9 #include "chrome/browser/chromeos/system_access.h"
     10 #include "chrome/browser/google/google_util.h"
     11 #include "googleurl/src/gurl.h"
     12 #include "grit/generated_resources.h"
     13 #include "grit/theme_resources.h"
     14 #include "third_party/skia/include/effects/SkGradientShader.h"
     15 #include "ui/base/l10n/l10n_util.h"
     16 #include "ui/base/resource/resource_bundle.h"
     17 #include "ui/gfx/canvas_skia.h"
     18 #include "views/controls/button/menu_button.h"
     19 #include "views/controls/button/native_button.h"
     20 #include "views/controls/label.h"
     21 #include "views/controls/textfield/textfield.h"
     22 #include "views/controls/throbber.h"
     23 #include "views/painter.h"
     24 #include "views/screen.h"
     25 #include "views/widget/widget.h"
     26 #include "views/widget/widget_gtk.h"
     27 
     28 namespace chromeos {
     29 
     30 namespace {
     31 
     32 // Time in ms per throbber frame.
     33 const int kThrobberFrameMs = 60;
     34 
     35 // Time in ms before smoothed throbber is shown.
     36 const int kThrobberStartDelayMs = 500;
     37 
     38 const SkColor kBackgroundCenterColor = SkColorSetRGB(41, 50, 67);
     39 const SkColor kBackgroundEdgeColor = SK_ColorBLACK;
     40 
     41 const char kAccountRecoveryHelpUrl[] =
     42     "https://www.google.com/support/accounts/bin/answer.py?answer=48598";
     43 
     44 class BackgroundPainter : public views::Painter {
     45  public:
     46   BackgroundPainter() {}
     47 
     48   virtual void Paint(int w, int h, gfx::Canvas* canvas) {
     49     SkRect rect;
     50     rect.set(SkIntToScalar(0),
     51              SkIntToScalar(0),
     52              SkIntToScalar(w),
     53              SkIntToScalar(h));
     54     SkPaint paint;
     55     paint.setStyle(SkPaint::kFill_Style);
     56     paint.setFlags(SkPaint::kAntiAlias_Flag);
     57     SkColor colors[2] = { kBackgroundCenterColor, kBackgroundEdgeColor };
     58     SkShader* s = SkGradientShader::CreateRadial(
     59         SkPoint::Make(SkIntToScalar(w / 2), SkIntToScalar(h / 2)),
     60         SkIntToScalar(w / 2),
     61         colors,
     62         NULL,
     63         2,
     64         SkShader::kClamp_TileMode,
     65         NULL);
     66     paint.setShader(s);
     67     s->unref();
     68     canvas->AsCanvasSkia()->drawRect(rect, paint);
     69   }
     70 
     71  private:
     72   DISALLOW_COPY_AND_ASSIGN(BackgroundPainter);
     73 };
     74 
     75 }  // namespace
     76 
     77 ThrobberHostView::ThrobberHostView()
     78     : host_view_(this),
     79       throbber_widget_(NULL) {
     80 }
     81 
     82 ThrobberHostView::~ThrobberHostView() {
     83   StopThrobber();
     84 }
     85 
     86 void ThrobberHostView::StartThrobber() {
     87   StopThrobber();
     88 
     89   views::Widget* host_widget = host_view_->GetWidget();
     90   if (!host_widget) {
     91     LOG(WARNING) << "Failed to start the throbber: no Widget";
     92     return;
     93   }
     94 
     95   GtkWidget* host_gtk_window = host_widget->GetNativeView();
     96   while (host_gtk_window && !GTK_IS_WINDOW(host_gtk_window))
     97     host_gtk_window = gtk_widget_get_parent(host_gtk_window);
     98   if (!host_gtk_window) {
     99     LOG(WARNING) << "Failed to start the throbber: no GtkWindow";
    100     return;
    101   }
    102 
    103   views::SmoothedThrobber* throbber = CreateDefaultSmoothedThrobber();
    104   throbber->set_stop_delay_ms(0);
    105   gfx::Rect throbber_bounds = CalculateThrobberBounds(throbber);
    106 
    107   views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_POPUP);
    108   params.transparent = true;
    109   throbber_widget_ = views::Widget::CreateWidget(params);
    110   static_cast<views::WidgetGtk*>(throbber_widget_)->make_transient_to_parent();
    111 
    112   throbber_bounds.Offset(host_view_->GetScreenBounds().origin());
    113   throbber_widget_->Init(host_gtk_window, throbber_bounds);
    114   throbber_widget_->SetContentsView(throbber);
    115   // This keeps the window from flashing at startup.
    116   gdk_window_set_back_pixmap(
    117       throbber_widget_->GetNativeView()->window, NULL, false);
    118   throbber_widget_->Show();
    119   // WM can ignore bounds before widget is shown.
    120   throbber_widget_->SetBounds(throbber_bounds);
    121   throbber->Start();
    122 }
    123 
    124 void ThrobberHostView::StopThrobber() {
    125   if (throbber_widget_) {
    126     throbber_widget_->Close();
    127     throbber_widget_ = NULL;
    128   }
    129 }
    130 
    131 gfx::Rect ThrobberHostView::CalculateThrobberBounds(views::Throbber* throbber) {
    132   gfx::Rect bounds(throbber->GetPreferredSize());
    133   bounds.set_x(
    134       host_view_->width() - login::kThrobberRightMargin - bounds.width());
    135   bounds.set_y((host_view_->height() - bounds.height()) / 2);
    136   return bounds;
    137 }
    138 
    139 views::SmoothedThrobber* CreateDefaultSmoothedThrobber() {
    140   views::SmoothedThrobber* throbber =
    141       new views::SmoothedThrobber(kThrobberFrameMs);
    142   throbber->SetFrames(
    143       ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SPINNER));
    144   throbber->set_start_delay_ms(kThrobberStartDelayMs);
    145   return throbber;
    146 }
    147 
    148 views::Throbber* CreateDefaultThrobber() {
    149   views::Throbber* throbber = new views::Throbber(kThrobberFrameMs, false);
    150   throbber->SetFrames(
    151       ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SPINNER));
    152   return throbber;
    153 }
    154 
    155 views::Painter* CreateBackgroundPainter() {
    156   return new BackgroundPainter();
    157 }
    158 
    159 gfx::Rect CalculateScreenBounds(const gfx::Size& size) {
    160   gfx::Rect bounds(views::Screen::GetMonitorWorkAreaNearestWindow(NULL));
    161   if (!size.IsEmpty()) {
    162     int horizontal_diff = bounds.width() - size.width();
    163     int vertical_diff = bounds.height() - size.height();
    164     bounds.Inset(horizontal_diff / 2, vertical_diff / 2);
    165   }
    166   return bounds;
    167 }
    168 
    169 void CorrectLabelFontSize(views::Label* label) {
    170   if (label)
    171     label->SetFont(label->font().DeriveFont(kFontSizeCorrectionDelta));
    172 }
    173 
    174 void CorrectMenuButtonFontSize(views::MenuButton* button) {
    175   if (button)
    176     button->SetFont(button->font().DeriveFont(kFontSizeCorrectionDelta));
    177 }
    178 
    179 void CorrectNativeButtonFontSize(views::NativeButton* button) {
    180   if (button)
    181     button->set_font(button->font().DeriveFont(kFontSizeCorrectionDelta));
    182 }
    183 
    184 void CorrectTextfieldFontSize(views::Textfield* textfield) {
    185   if (textfield)
    186     textfield->SetFont(textfield->font().DeriveFont(kFontSizeCorrectionDelta));
    187 }
    188 
    189 void SetAndCorrectTextfieldFont(views::Textfield* textfield,
    190                                 const gfx::Font& font) {
    191   if (textfield)
    192     textfield->SetFont(font.DeriveFont(kFontSizeCorrectionDelta));
    193 }
    194 
    195 GURL GetAccountRecoveryHelpUrl() {
    196   return google_util::AppendGoogleLocaleParam(GURL(kAccountRecoveryHelpUrl));
    197 }
    198 
    199 string16 GetCurrentNetworkName(NetworkLibrary* network_library) {
    200   if (!network_library)
    201     return string16();
    202 
    203   if (network_library->ethernet_connected()) {
    204     return l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
    205   } else if (network_library->wifi_connected()) {
    206     return UTF8ToUTF16(network_library->wifi_network()->name());
    207   } else if (network_library->cellular_connected()) {
    208     return UTF8ToUTF16(network_library->cellular_network()->name());
    209   } else if (network_library->ethernet_connecting()) {
    210     return l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
    211   } else if (network_library->wifi_connecting()) {
    212     return UTF8ToUTF16(network_library->wifi_network()->name());
    213   } else if (network_library->cellular_connecting()) {
    214     return UTF8ToUTF16(network_library->cellular_network()->name());
    215   } else {
    216     return string16();
    217   }
    218 }
    219 
    220 namespace login {
    221 
    222 gfx::Size WideButton::GetPreferredSize() {
    223   gfx::Size preferred_size = NativeButton::GetPreferredSize();
    224   // Set minimal width.
    225   if (preferred_size.width() < kButtonMinWidth)
    226     preferred_size.set_width(kButtonMinWidth);
    227   return preferred_size;
    228 }
    229 
    230 }  // namespace login
    231 
    232 }  // namespace chromeos
    233