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 |