Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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/webui_login_view.h" | |
| 6 | |
| 7 #include <vector> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "chrome/browser/chromeos/login/login_utils.h" | |
| 11 #include "chrome/browser/chromeos/login/proxy_settings_dialog.h" | |
| 12 #include "chrome/browser/chromeos/status/clock_menu_button.h" | |
| 13 #include "chrome/browser/chromeos/status/input_method_menu_button.h" | |
| 14 #include "chrome/browser/chromeos/status/network_menu_button.h" | |
| 15 #include "chrome/browser/chromeos/status/status_area_view.h" | |
| 16 #include "chrome/browser/chromeos/wm_ipc.h" | |
| 17 #include "chrome/browser/profiles/profile.h" | |
| 18 #include "chrome/browser/profiles/profile_manager.h" | |
| 19 #include "chrome/browser/renderer_host/render_widget_host_view_views.h" | |
| 20 #include "chrome/browser/ui/touch/frame/keyboard_container_view.h" | |
| 21 #include "chrome/browser/ui/views/dom_view.h" | |
| 22 #include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h" | |
| 23 #include "content/browser/renderer_host/render_view_host.h" | |
| 24 #include "content/browser/tab_contents/tab_contents.h" | |
| 25 #include "content/common/notification_service.h" | |
| 26 #include "googleurl/src/gurl.h" | |
| 27 #include "ui/base/x/x11_util.h" | |
| 28 #include "ui/gfx/transform.h" | |
| 29 #include "views/controls/textfield/textfield.h" | |
| 30 #include "views/widget/widget.h" | |
| 31 | |
| 32 // X Windows headers have "#define Status int". That interferes with | |
| 33 // NetworkLibrary header which defines enum "Status". | |
|
Nikita (slow)
2011/05/18 20:22:12
This issue is absolete. Please remove comment and
rharrison
2011/05/19 00:31:43
Done.
| |
| 34 #include <X11/cursorfont.h> // NOLINT | |
| 35 #include <X11/Xcursor/Xcursor.h> // NOLINT | |
| 36 | |
| 37 namespace { | |
| 38 | |
| 39 const int kKeyboardHeight = 300; | |
| 40 const int kKeyboardSlideDuration = 500; // In milliseconds | |
| 41 | |
| 42 // This gets rid of the ugly X default cursor. | |
| 43 static void ResetXCursor() { | |
|
Nikita (slow)
2011/05/18 20:22:12
background_view.cc has the same code.
Please move
rharrison
2011/05/19 00:31:43
Done.
| |
| 44 // TODO(sky): nuke this once new window manager is in place. | |
| 45 Display* display = ui::GetXDisplay(); | |
| 46 Cursor cursor = XCreateFontCursor(display, XC_left_ptr); | |
| 47 XID root_window = ui::GetX11RootWindow(); | |
| 48 XSetWindowAttributes attr; | |
| 49 attr.cursor = cursor; | |
| 50 XChangeWindowAttributes(display, root_window, CWCursor, &attr); | |
| 51 } | |
| 52 | |
| 53 PropertyAccessor<bool>* GetFocusedStateAccessor() { | |
| 54 static PropertyAccessor<bool> state; | |
| 55 return &state; | |
| 56 } | |
| 57 | |
| 58 bool TabContentsHasFocus(const TabContents* contents) { | |
| 59 views::View* view = static_cast<TabContentsViewTouch*>(contents->view()); | |
| 60 return view->Contains(view->GetFocusManager()->GetFocusedView()); | |
| 61 } | |
| 62 | |
| 63 } // namespace | |
| 64 | |
| 65 namespace chromeos { | |
| 66 | |
| 67 // static | |
| 68 const char WebUILoginView::kViewClassName[] = | |
| 69 "browser/chromeos/login/WebUILoginView"; | |
| 70 | |
| 71 // WebUILoginView public: ------------------------------------------------------ | |
| 72 | |
| 73 WebUILoginView::WebUILoginView() | |
| 74 : profile_(NULL), | |
| 75 status_area_(NULL), | |
| 76 did_paint_(false), | |
| 77 webui_login_(NULL), | |
| 78 keyboard_showing_(false), | |
| 79 focus_listener_added_(false), | |
| 80 keyboard_(NULL) { | |
| 81 } | |
| 82 | |
| 83 void WebUILoginView::Init(const GURL& login_url) { | |
| 84 CHECK(!login_url.is_empty()); | |
| 85 profile_ = ProfileManager::GetDefaultProfile(); | |
| 86 if (!profile_->GetExtensionService()) { | |
|
Nikita (slow)
2011/05/18 20:22:12
Are you sure that you need this block?
Extensions
rharrison
2011/05/19 00:31:43
Since we are not in a proper logged in browser I d
Nikita (slow)
2011/05/19 03:53:33
Let's clarify 2 things:
1. Is keyboard extension a
rharrison
2011/05/19 16:45:28
I think it is a component extension. I misundersto
| |
| 87 if (profile_->IsOffTheRecord()) | |
| 88 profile_ = profile_->GetOriginalProfile(); | |
| 89 profile_->InitExtensions(false); | |
| 90 } | |
| 91 | |
| 92 webui_login_ = new DOMView(); | |
| 93 AddChildView(webui_login_); | |
| 94 webui_login_->Init(profile_, NULL); | |
| 95 webui_login_->LoadURL(login_url); | |
| 96 webui_login_->SetVisible(true); | |
| 97 | |
| 98 InitStatusArea(); | |
| 99 | |
| 100 registrar_.Add(this, | |
| 101 NotificationType::FOCUS_CHANGED_IN_PAGE, | |
| 102 NotificationService::AllSources()); | |
| 103 registrar_.Add(this, | |
| 104 NotificationType::TAB_CONTENTS_DESTROYED, | |
| 105 NotificationService::AllSources()); | |
| 106 } | |
| 107 | |
| 108 // static | |
| 109 views::Widget* WebUILoginView::CreateWindowContainingView( | |
| 110 const gfx::Rect& bounds, | |
| 111 const GURL& login_url, | |
| 112 WebUILoginView** view) { | |
| 113 ResetXCursor(); | |
| 114 | |
| 115 views::Widget* window = new views::Widget; | |
| 116 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 117 params.bounds = bounds; | |
| 118 window->Init(params); | |
| 119 *view = new WebUILoginView(); | |
| 120 (*view)->Init(login_url); | |
| 121 | |
| 122 window->SetContentsView(*view); | |
| 123 | |
| 124 (*view)->UpdateWindowType(); | |
| 125 | |
| 126 // This keeps the window from flashing at startup. | |
| 127 GdkWindow* gdk_window = window->GetNativeView()->window; | |
| 128 gdk_window_set_back_pixmap(gdk_window, NULL, false); | |
| 129 | |
| 130 return window; | |
| 131 } | |
| 132 | |
| 133 std::string WebUILoginView::GetClassName() const { | |
| 134 return kViewClassName; | |
| 135 } | |
| 136 | |
| 137 gfx::NativeWindow WebUILoginView::GetNativeWindow() const { | |
| 138 return GetWidget()->GetNativeWindow(); | |
| 139 } | |
| 140 | |
| 141 void WebUILoginView::FocusWillChange(views::View* focused_before, | |
| 142 views::View* focused_now) { | |
|
oshima
2011/05/18 18:24:54
indent
rharrison
2011/05/19 00:31:43
Done.
| |
| 143 VirtualKeyboardType before = DecideKeyboardStateForView(focused_before); | |
| 144 VirtualKeyboardType now = DecideKeyboardStateForView(focused_now); | |
| 145 if (before != now) { | |
| 146 // TODO(varunjain): support other types of keyboard. | |
| 147 UpdateKeyboardAndLayout(now == GENERIC); | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 void WebUILoginView::SetStatusAreaVisible(bool visible) { | |
| 152 status_area_->SetVisible(visible); | |
| 153 } | |
| 154 | |
| 155 void WebUILoginView::SetStatusAreaEnabled(bool enable) { | |
| 156 status_area_->MakeButtonsActive(enable); | |
| 157 } | |
| 158 | |
| 159 // WebUILoginView protected: --------------------------------------------------- | |
| 160 | |
| 161 void WebUILoginView::OnPaint(gfx::Canvas* canvas) { | |
| 162 views::View::OnPaint(canvas); | |
| 163 if (!did_paint_) { | |
| 164 did_paint_ = true; | |
| 165 UpdateWindowType(); | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 void WebUILoginView::Layout() { | |
| 170 const int kCornerPadding = 5; | |
| 171 gfx::Size status_area_size = status_area_->GetPreferredSize(); | |
| 172 status_area_->SetBounds( | |
| 173 width() - status_area_size.width() - kCornerPadding, | |
| 174 kCornerPadding, | |
| 175 status_area_size.width(), | |
| 176 status_area_size.height()); | |
| 177 | |
| 178 if (webui_login_) | |
| 179 webui_login_->SetBoundsRect(bounds()); | |
| 180 | |
| 181 if (!keyboard_) | |
|
Nikita (slow)
2011/05/18 20:22:12
It's touch specific while it shouldn't be.
Since w
rharrison
2011/05/19 00:31:43
Done.
| |
| 182 return; | |
| 183 | |
| 184 keyboard_->SetVisible(keyboard_showing_); | |
| 185 gfx::Rect keyboard_bounds = bounds(); | |
| 186 keyboard_bounds.set_y(keyboard_bounds.height() - kKeyboardHeight); | |
| 187 keyboard_bounds.set_height(kKeyboardHeight); | |
| 188 keyboard_->SetBoundsRect(keyboard_bounds); | |
| 189 } | |
| 190 | |
| 191 void WebUILoginView::ChildPreferredSizeChanged(View* child) { | |
| 192 Layout(); | |
| 193 SchedulePaint(); | |
| 194 } | |
| 195 | |
| 196 bool WebUILoginView::ShouldOpenButtonOptions( | |
| 197 const views::View* button_view) const { | |
| 198 if (button_view == status_area_->network_view()) { | |
| 199 return true; | |
| 200 } | |
|
oshima
2011/05/18 18:24:54
nuke {}
rharrison
2011/05/19 00:31:43
Done.
| |
| 201 if (button_view == status_area_->clock_view() || | |
| 202 button_view == status_area_->input_method_view()) { | |
| 203 return false; | |
| 204 } | |
| 205 return true; | |
| 206 } | |
| 207 | |
| 208 void WebUILoginView::OpenButtonOptions(const views::View* button_view) { | |
| 209 if (button_view == status_area_->network_view()) { | |
| 210 if (proxy_settings_dialog_.get() == NULL) { | |
| 211 proxy_settings_dialog_.reset(new ProxySettingsDialog( | |
| 212 this, GetNativeWindow())); | |
| 213 } | |
| 214 proxy_settings_dialog_->Show(); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 StatusAreaHost::ScreenMode WebUILoginView::GetScreenMode() const { | |
| 219 return kLoginMode; | |
| 220 } | |
| 221 | |
| 222 StatusAreaHost::TextStyle WebUILoginView::GetTextStyle() const { | |
| 223 return kWhitePlain; | |
| 224 } | |
| 225 | |
| 226 // Overridden from LoginHtmlDialog::Delegate: | |
| 227 void WebUILoginView::OnLocaleChanged() { | |
|
Nikita (slow)
2011/05/18 20:22:12
Generic question: are you planning to have UI lang
rharrison
2011/05/19 00:31:43
I had not thought about it. I think we will have t
| |
| 228 // Proxy settings dialog contains localized strings. | |
| 229 proxy_settings_dialog_.reset(); | |
| 230 SchedulePaint(); | |
| 231 } | |
| 232 | |
| 233 // WebUILoginView private: ----------------------------------------------------- | |
| 234 | |
| 235 void WebUILoginView::InitStatusArea() { | |
| 236 DCHECK(status_area_ == NULL); | |
| 237 status_area_ = new StatusAreaView(this); | |
| 238 status_area_->Init(); | |
| 239 AddChildView(status_area_); | |
| 240 } | |
| 241 | |
| 242 void WebUILoginView::UpdateWindowType() { | |
| 243 std::vector<int> params; | |
| 244 WmIpc::instance()->SetWindowType( | |
| 245 GTK_WIDGET(GetNativeWindow()), | |
| 246 WM_IPC_WINDOW_LOGIN_WEBUI, | |
| 247 ¶ms); | |
| 248 } | |
| 249 | |
| 250 void WebUILoginView::InitVirtualKeyboard() { | |
| 251 if (keyboard_) | |
| 252 return; | |
| 253 | |
| 254 keyboard_ = new KeyboardContainerView(profile_, NULL); | |
| 255 keyboard_->SetVisible(false); | |
| 256 AddChildView(keyboard_); | |
| 257 } | |
| 258 | |
| 259 void WebUILoginView::UpdateKeyboardAndLayout(bool should_show_keyboard) { | |
| 260 if (should_show_keyboard) | |
| 261 InitVirtualKeyboard(); | |
| 262 | |
| 263 if (should_show_keyboard == keyboard_showing_) | |
| 264 return; | |
| 265 | |
| 266 DCHECK(keyboard_); | |
| 267 | |
| 268 keyboard_showing_ = should_show_keyboard; | |
| 269 Layout(); | |
| 270 } | |
| 271 | |
| 272 WebUILoginView::VirtualKeyboardType | |
| 273 WebUILoginView::DecideKeyboardStateForView(views::View* view) { | |
| 274 if (!view) | |
| 275 return NONE; | |
| 276 | |
| 277 std::string cname = GetClassName(); | |
|
oshima
2011/05/18 18:24:54
isn't this view->GetClassName?
rharrison
2011/05/19 00:31:43
yes
| |
| 278 if (cname == views::Textfield::kViewClassName) { | |
| 279 return GENERIC; | |
| 280 } else if (cname == RenderWidgetHostViewViews::kViewClassName) { | |
| 281 TabContents* contents = webui_login_->tab_contents(); | |
| 282 bool* editable = contents ? GetFocusedStateAccessor()->GetProperty( | |
| 283 contents->property_bag()) : NULL; | |
| 284 if (editable && *editable) | |
| 285 return GENERIC; | |
| 286 } | |
| 287 return NONE; | |
| 288 } | |
| 289 | |
| 290 void WebUILoginView::Observe(NotificationType type, | |
| 291 const NotificationSource& source, | |
| 292 const NotificationDetails& details) { | |
| 293 if (type == NotificationType::FOCUS_CHANGED_IN_PAGE) { | |
| 294 // Only modify the keyboard state if the currently active tab sent the | |
| 295 // notification. | |
| 296 const TabContents* current_tab = webui_login_->tab_contents(); | |
| 297 TabContents* source_tab = Source<TabContents>(source).ptr(); | |
| 298 const bool editable = *Details<const bool>(details).ptr(); | |
| 299 | |
| 300 if (current_tab == source_tab && TabContentsHasFocus(source_tab)) | |
| 301 UpdateKeyboardAndLayout(editable); | |
| 302 | |
| 303 // Save the state of the focused field so that the keyboard visibility | |
| 304 // can be determined after tab switching. | |
| 305 GetFocusedStateAccessor()->SetProperty( | |
| 306 source_tab->property_bag(), editable); | |
| 307 } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) { | |
| 308 GetFocusedStateAccessor()->DeleteProperty( | |
| 309 Source<TabContents>(source).ptr()->property_bag()); | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 } // namespace chromeos | |
| OLD | NEW |