Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: chrome/browser/chromeos/login/touch_login_view.cc

Issue 7302015: A keyboard widget that manages itself (the animation and all that). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge with trunk Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/touch_login_view.h"
6
7 #include "chrome/browser/chromeos/status/status_area_view.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/renderer_host/render_widget_host_view_views.h"
10 #include "chrome/browser/ui/touch/frame/keyboard_container_view.h"
11 #include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
12 #include "chrome/browser/ui/views/dom_view.h"
13 #include "chrome/common/chrome_notification_types.h"
14 #include "content/browser/tab_contents/tab_contents.h"
15 #include "content/common/notification_service.h"
16 #include "googleurl/src/gurl.h"
17 #include "ui/base/animation/slide_animation.h"
18 #include "ui/gfx/transform.h"
19 #include "views/controls/textfield/textfield.h"
20 #include "views/widget/widget.h"
21
22 namespace {
23
24 const char kViewClassName[] = "browser/chromeos/login/TouchLoginView";
25 const int kDefaultKeyboardHeight = 300;
26 const int kKeyboardSlideDuration = 300; // In milliseconds
27
28 PropertyAccessor<bool>* GetFocusedStateAccessor() {
29 static PropertyAccessor<bool> state;
30 return &state;
31 }
32
33 bool TabContentsHasFocus(const TabContents* contents) {
34 views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
35 return view->Contains(view->GetFocusManager()->GetFocusedView());
36 }
37
38 } // namespace
39
40 namespace chromeos {
41
42 // TouchLoginView public: ------------------------------------------------------
43
44 TouchLoginView::TouchLoginView()
45 : WebUILoginView(),
46 keyboard_showing_(false),
47 keyboard_height_(kDefaultKeyboardHeight),
48 focus_listener_added_(false),
49 keyboard_(NULL) {
50 }
51
52 TouchLoginView::~TouchLoginView() {
53 }
54
55 void TouchLoginView::Init() {
56 WebUILoginView::Init();
57 InitStatusArea();
58 InitVirtualKeyboard();
59
60
61 Source<TabContents> tab_contents(webui_login_->tab_contents());
62 registrar_.Add(this,
63 content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
64 tab_contents);
65 registrar_.Add(this,
66 content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
67 tab_contents);
68 registrar_.Add(this,
69 chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED,
70 NotificationService::AllSources());
71 registrar_.Add(this,
72 chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED,
73 NotificationService::AllSources());
74 }
75
76 std::string TouchLoginView::GetClassName() const {
77 return kViewClassName;
78 }
79
80 void TouchLoginView::FocusWillChange(views::View* focused_before,
81 views::View* focused_now) {
82 VirtualKeyboardType before = DecideKeyboardStateForView(focused_before);
83 VirtualKeyboardType now = DecideKeyboardStateForView(focused_now);
84 if (before != now) {
85 // TODO(varunjain): support other types of keyboard.
86 UpdateKeyboardAndLayout(now == GENERIC);
87 }
88 }
89
90 void TouchLoginView::OnWindowCreated() {
91 }
92
93 // TouchLoginView protected: ---------------------------------------------------
94
95 void TouchLoginView::Layout() {
96 WebUILoginView::Layout();
97 DCHECK(status_area_);
98
99 // Layout the Status Area up in the right corner. This should always be done.
100 gfx::Size status_area_size = status_area_->GetPreferredSize();
101 status_area_->SetBounds(
102 width() - status_area_size.width() -
103 WebUILoginView::kStatusAreaCornerPadding,
104 WebUILoginView::kStatusAreaCornerPadding,
105 status_area_size.width(),
106 status_area_size.height());
107
108 if (!keyboard_)
109 return;
110
111 // We are not resizing the DOMView here, so the keyboard is going to occlude
112 // the login screen partially. It is the responsibility of the UX layer to
113 // handle this.
114
115 // Lastly layout the keyboard
116 bool display_keyboard = (keyboard_showing_ || animation_->is_animating());
117 keyboard_->SetVisible(display_keyboard);
118 gfx::Rect keyboard_bounds = bounds();
119 int keyboard_height = display_keyboard ? keyboard_height_ : 0;
120 keyboard_bounds.set_y(keyboard_bounds.height() - keyboard_height);
121 keyboard_bounds.set_height(keyboard_height);
122 keyboard_->SetBoundsRect(keyboard_bounds);
123 }
124
125 void TouchLoginView::InitStatusArea() {
126 if (status_area_)
127 return;
128 status_area_ = new StatusAreaView(this);
129 status_area_->Init();
130 AddChildView(status_area_);
131 }
132
133 // TouchLoginView private: -----------------------------------------------------
134
135 void TouchLoginView::InitVirtualKeyboard() {
136 // TODO(yusukes): Support non-US virtual keyboard on the login screen.
137 keyboard_ = new KeyboardContainerView(profile_, NULL, GURL());
138
139 keyboard_->SetVisible(false);
140 AddChildView(keyboard_);
141
142 animation_.reset(new ui::SlideAnimation(this));
143 animation_->SetTweenType(ui::Tween::LINEAR);
144 animation_->SetSlideDuration(kKeyboardSlideDuration);
145 }
146
147 void TouchLoginView::UpdateKeyboardAndLayout(bool should_show_keyboard) {
148 DCHECK(keyboard_);
149 if (should_show_keyboard == keyboard_showing_)
150 return;
151 keyboard_showing_ = should_show_keyboard;
152 if (keyboard_showing_) {
153 ui::Transform transform;
154 transform.SetTranslateY(-keyboard_height_);
155 keyboard_->SetTransform(transform);
156 Layout();
157 animation_->Show();
158 } else {
159 ui::Transform transform;
160 keyboard_->SetTransform(transform);
161 animation_->Hide();
162 Layout();
163 }
164 }
165
166 TouchLoginView::VirtualKeyboardType
167 TouchLoginView::DecideKeyboardStateForView(views::View* view) {
168 if (!view)
169 return NONE;
170
171 std::string cname = view->GetClassName();
172 if (cname == views::Textfield::kViewClassName) {
173 return GENERIC;
174 } else if (cname == RenderWidgetHostViewViews::kViewClassName) {
175 TabContents* contents = webui_login_->tab_contents();
176 bool* editable = contents ? GetFocusedStateAccessor()->GetProperty(
177 contents->property_bag()) : NULL;
178 if (editable && *editable)
179 return GENERIC;
180 }
181 return NONE;
182 }
183
184 void TouchLoginView::Observe(int type,
185 const NotificationSource& source,
186 const NotificationDetails& details) {
187 if (type == content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE) {
188 // Only modify the keyboard state if the currently active tab sent the
189 // notification.
190 const TabContents* current_tab = webui_login_->tab_contents();
191 TabContents* source_tab = Source<TabContents>(source).ptr();
192 const bool editable = *Details<const bool>(details).ptr();
193
194 if (current_tab == source_tab && TabContentsHasFocus(source_tab))
195 UpdateKeyboardAndLayout(editable);
196
197 // Save the state of the focused field so that the keyboard visibility
198 // can be determined after tab switching.
199 GetFocusedStateAccessor()->SetProperty(
200 source_tab->property_bag(), editable);
201 } else if (type == content::NOTIFICATION_TAB_CONTENTS_DESTROYED) {
202 GetFocusedStateAccessor()->DeleteProperty(
203 Source<TabContents>(source).ptr()->property_bag());
204 } else if (type == chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED) {
205 UpdateKeyboardAndLayout(false);
206 } else if (type == chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED) {
207 // TODO(penghuang) Allow extension conrtol the virtual keyboard directly
208 // instead of using Notification.
209 int height = *(Details<int>(details).ptr());
210 if (height != keyboard_height_) {
211 DCHECK_GE(height, 0) << "Height of the keyboard is less than 0.";
212 DCHECK_LE(height, View::height()) << "Height of the keyboard is greater "
213 "than the height of containing view.";
214 keyboard_height_ = height;
215 Layout();
216 }
217 }
218 }
219
220 // ui::AnimationDelegate implementation ----------------------------------------
221
222 void TouchLoginView::AnimationProgressed(const ui::Animation* anim) {
223 ui::Transform transform;
224 transform.SetTranslateY(
225 ui::Tween::ValueBetween(anim->GetCurrentValue(), keyboard_height_, 0));
226 keyboard_->SetTransform(transform);
227 }
228
229 void TouchLoginView::AnimationEnded(const ui::Animation* animation) {
230 if (keyboard_showing_) {
231 Layout();
232 } else {
233 // Notify the keyboard that it is hidden now.
234 keyboard_->SetVisible(false);
235 }
236 }
237
238 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/touch_login_view.h ('k') | chrome/browser/chromeos/login/webui_login_display_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698