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