// 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