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:
BackgroundPainter()46 BackgroundPainter() {}
47
Paint(int w,int h,gfx::Canvas * canvas)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
ThrobberHostView()77 ThrobberHostView::ThrobberHostView()
78 : host_view_(this),
79 throbber_widget_(NULL) {
80 }
81
~ThrobberHostView()82 ThrobberHostView::~ThrobberHostView() {
83 StopThrobber();
84 }
85
StartThrobber()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
StopThrobber()124 void ThrobberHostView::StopThrobber() {
125 if (throbber_widget_) {
126 throbber_widget_->Close();
127 throbber_widget_ = NULL;
128 }
129 }
130
CalculateThrobberBounds(views::Throbber * throbber)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
CreateDefaultSmoothedThrobber()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
CreateDefaultThrobber()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
CreateBackgroundPainter()155 views::Painter* CreateBackgroundPainter() {
156 return new BackgroundPainter();
157 }
158
CalculateScreenBounds(const gfx::Size & size)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
CorrectLabelFontSize(views::Label * label)169 void CorrectLabelFontSize(views::Label* label) {
170 if (label)
171 label->SetFont(label->font().DeriveFont(kFontSizeCorrectionDelta));
172 }
173
CorrectMenuButtonFontSize(views::MenuButton * button)174 void CorrectMenuButtonFontSize(views::MenuButton* button) {
175 if (button)
176 button->SetFont(button->font().DeriveFont(kFontSizeCorrectionDelta));
177 }
178
CorrectNativeButtonFontSize(views::NativeButton * button)179 void CorrectNativeButtonFontSize(views::NativeButton* button) {
180 if (button)
181 button->set_font(button->font().DeriveFont(kFontSizeCorrectionDelta));
182 }
183
CorrectTextfieldFontSize(views::Textfield * textfield)184 void CorrectTextfieldFontSize(views::Textfield* textfield) {
185 if (textfield)
186 textfield->SetFont(textfield->font().DeriveFont(kFontSizeCorrectionDelta));
187 }
188
SetAndCorrectTextfieldFont(views::Textfield * textfield,const gfx::Font & font)189 void SetAndCorrectTextfieldFont(views::Textfield* textfield,
190 const gfx::Font& font) {
191 if (textfield)
192 textfield->SetFont(font.DeriveFont(kFontSizeCorrectionDelta));
193 }
194
GetAccountRecoveryHelpUrl()195 GURL GetAccountRecoveryHelpUrl() {
196 return google_util::AppendGoogleLocaleParam(GURL(kAccountRecoveryHelpUrl));
197 }
198
GetCurrentNetworkName(NetworkLibrary * network_library)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
GetPreferredSize()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