background_view.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
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/background_view.h" 6 7#include "app/l10n_util.h" 8#include "app/resource_bundle.h" 9#include "app/x11_util.h" 10#include "base/string_util.h" 11#include "base/utf_string_conversions.h" 12#include "chrome/browser/chromeos/login/helper.h" 13#include "chrome/browser/chromeos/status/clock_menu_button.h" 14#include "chrome/browser/chromeos/status/feedback_menu_button.h" 15#include "chrome/browser/chromeos/status/language_menu_button.h" 16#include "chrome/browser/chromeos/status/network_menu_button.h" 17#include "chrome/browser/chromeos/status/status_area_view.h" 18#include "chrome/browser/chromeos/wm_ipc.h" 19#include "cros/chromeos_wm_ipc_enums.h" 20#include "grit/chromium_strings.h" 21#include "grit/generated_resources.h" 22#include "views/controls/label.h" 23#include "views/screen.h" 24#include "views/widget/widget_gtk.h" 25 26// X Windows headers have "#define Status int". That interferes with 27// NetworkLibrary header which defines enum "Status". 28#include <X11/cursorfont.h> 29#include <X11/Xcursor/Xcursor.h> 30 31using views::WidgetGtk; 32 33namespace chromeos { 34 35BackgroundView::BackgroundView() 36 : status_area_(NULL), 37 os_version_label_(NULL), 38 boot_times_label_(NULL), 39 did_paint_(false) { 40 views::Painter* painter = CreateBackgroundPainter(); 41 set_background(views::Background::CreateBackgroundPainter(true, painter)); 42 InitStatusArea(); 43 InitInfoLabels(); 44} 45 46static void ResetXCursor() { 47 // TODO(sky): nuke this once new window manager is in place. 48 // This gets rid of the ugly X default cursor. 49 Display* display = x11_util::GetXDisplay(); 50 Cursor cursor = XCreateFontCursor(display, XC_left_ptr); 51 XID root_window = x11_util::GetX11RootWindow(); 52 XSetWindowAttributes attr; 53 attr.cursor = cursor; 54 XChangeWindowAttributes(display, root_window, CWCursor, &attr); 55} 56 57// static 58views::Widget* BackgroundView::CreateWindowContainingView( 59 const gfx::Rect& bounds, 60 BackgroundView** view) { 61 ResetXCursor(); 62 63 WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW); 64 window->Init(NULL, bounds); 65 *view = new BackgroundView(); 66 window->SetContentsView(*view); 67 68 (*view)->UpdateWindowType(); 69 70 // This keeps the window from flashing at startup. 71 GdkWindow* gdk_window = window->GetNativeView()->window; 72 gdk_window_set_back_pixmap(gdk_window, NULL, false); 73 74 return window; 75} 76 77void BackgroundView::SetStatusAreaVisible(bool visible) { 78 status_area_->SetVisible(visible); 79} 80 81void BackgroundView::Paint(gfx::Canvas* canvas) { 82 views::View::Paint(canvas); 83 if (!did_paint_) { 84 did_paint_ = true; 85 UpdateWindowType(); 86 } 87} 88 89void BackgroundView::Layout() { 90 int corner_padding = 5; 91 int kInfoLeftPadding = 60; 92 int kInfoBottomPadding = 40; 93 int kInfoBetweenLinesPadding = 4; 94 gfx::Size status_area_size = status_area_->GetPreferredSize(); 95 status_area_->SetBounds( 96 width() - status_area_size.width() - corner_padding, 97 corner_padding, 98 status_area_size.width(), 99 status_area_size.height()); 100 gfx::Size version_size = os_version_label_->GetPreferredSize(); 101 os_version_label_->SetBounds( 102 kInfoLeftPadding, 103 height() - 104 ((2 * version_size.height()) + 105 kInfoBottomPadding + 106 kInfoBetweenLinesPadding), 107 width() - 2 * kInfoLeftPadding, 108 version_size.height()); 109 boot_times_label_->SetBounds( 110 kInfoLeftPadding, 111 height() - (version_size.height() + kInfoBottomPadding), 112 width() - 2 * corner_padding, 113 version_size.height()); 114} 115 116void BackgroundView::ChildPreferredSizeChanged(View* child) { 117 Layout(); 118 SchedulePaint(); 119} 120 121gfx::NativeWindow BackgroundView::GetNativeWindow() const { 122 return 123 GTK_WINDOW(static_cast<WidgetGtk*>(GetWidget())->GetNativeView()); 124} 125 126bool BackgroundView::ShouldOpenButtonOptions( 127 const views::View* button_view) const { 128 if (button_view == status_area_->clock_view() || 129 button_view == status_area_->feedback_view() || 130 button_view == status_area_->language_view() || 131 button_view == status_area_->network_view()) { 132 return false; 133 } 134 return true; 135} 136 137void BackgroundView::OpenButtonOptions(const views::View* button_view) const { 138 // TODO(avayvod): Add some dialog for options or remove them completely. 139} 140 141bool BackgroundView::IsButtonVisible(const views::View* button_view) const { 142 if (button_view == status_area_->feedback_view()) 143 return false; 144 return true; 145} 146 147bool BackgroundView::IsBrowserMode() const { 148 return false; 149} 150 151bool BackgroundView::IsScreenLockerMode() const { 152 return false; 153} 154 155void BackgroundView::LocaleChanged() { 156 Layout(); 157 SchedulePaint(); 158} 159 160void BackgroundView::InitStatusArea() { 161 DCHECK(status_area_ == NULL); 162 status_area_ = new StatusAreaView(this); 163 status_area_->Init(); 164 AddChildView(status_area_); 165} 166 167void BackgroundView::InitInfoLabels() { 168 const SkColor kVersionColor = 0xff8eb1f4; 169 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 170 171 os_version_label_ = new views::Label(); 172 os_version_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 173 os_version_label_->SetColor(kVersionColor); 174 os_version_label_->SetFont(rb.GetFont(ResourceBundle::SmallFont)); 175 AddChildView(os_version_label_); 176 boot_times_label_ = new views::Label(); 177 boot_times_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 178 boot_times_label_->SetColor(kVersionColor); 179 boot_times_label_->SetFont(rb.GetFont(ResourceBundle::SmallFont)); 180 AddChildView(boot_times_label_); 181 182 if (CrosLibrary::Get()->EnsureLoaded()) { 183 version_loader_.GetVersion( 184 &version_consumer_, NewCallback(this, &BackgroundView::OnVersion)); 185 boot_times_loader_.GetBootTimes( 186 &boot_times_consumer_, NewCallback(this, &BackgroundView::OnBootTimes)); 187 } else { 188 os_version_label_->SetText( 189 ASCIIToWide(CrosLibrary::Get()->load_error_string())); 190 } 191} 192 193void BackgroundView::UpdateWindowType() { 194 std::vector<int> params; 195 params.push_back(did_paint_ ? 1 : 0); 196 WmIpc::instance()->SetWindowType( 197 GTK_WIDGET(GetNativeWindow()), 198 WM_IPC_WINDOW_LOGIN_BACKGROUND, 199 ¶ms); 200} 201 202void BackgroundView::OnVersion( 203 VersionLoader::Handle handle, std::string version) { 204 // TODO(jungshik): Is string concatenation OK here? 205 std::string version_text = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME); 206 version_text += ' '; 207 version_text += l10n_util::GetStringUTF8(IDS_VERSION_FIELD_PREFIX); 208 version_text += ' '; 209 version_text += version; 210 os_version_label_->SetText(UTF8ToWide(version_text)); 211} 212 213void BackgroundView::OnBootTimes( 214 BootTimesLoader::Handle handle, BootTimesLoader::BootTimes boot_times) { 215 // TODO(davemoore) if we decide to keep these times visible we will need 216 // to localize the strings. 217 const char* kBootTimesNoChromeExec = 218 "Boot took %.2f seconds (firmware %.2fs, kernel %.2fs, system %.2fs)"; 219 const char* kBootTimesChromeExec = 220 "Boot took %.2f seconds " 221 "(firmware %.2fs, kernel %.2fs, system %.2fs, chrome %.2fs)"; 222 std::string boot_times_text; 223 224 if (boot_times.chrome > 0) { 225 boot_times_text = 226 StringPrintf( 227 kBootTimesChromeExec, 228 boot_times.total, 229 boot_times.firmware, 230 boot_times.pre_startup, 231 boot_times.system, 232 boot_times.chrome); 233 } else { 234 boot_times_text = 235 StringPrintf( 236 kBootTimesNoChromeExec, 237 boot_times.total, 238 boot_times.firmware, 239 boot_times.pre_startup, 240 boot_times.system); 241 } 242 // Use UTF8ToWide once this string is localized. 243 boot_times_label_->SetText(ASCIIToWide(boot_times_text)); 244} 245 246} // namespace chromeos 247