OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/keyboard/keyboard_controller.h" | 5 #include "ui/keyboard/keyboard_controller.h" |
6 | 6 |
7 #include "ui/aura/layout_manager.h" | 7 #include "ui/aura/layout_manager.h" |
8 #include "ui/aura/window.h" | 8 #include "ui/aura/window.h" |
9 #include "ui/aura/window_delegate.h" | 9 #include "ui/aura/window_delegate.h" |
10 #include "ui/base/hit_test.h" | 10 #include "ui/base/hit_test.h" |
11 #include "ui/base/ime/input_method.h" | 11 #include "ui/base/ime/input_method.h" |
12 #include "ui/base/ime/input_method_base.h" | |
13 #include "ui/base/ime/text_input_client.h" | 12 #include "ui/base/ime/text_input_client.h" |
14 #include "ui/base/ime/text_input_type.h" | 13 #include "ui/base/ime/text_input_type.h" |
15 #include "ui/gfx/path.h" | 14 #include "ui/gfx/path.h" |
16 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
17 #include "ui/gfx/skia_util.h" | 16 #include "ui/gfx/skia_util.h" |
18 #include "ui/keyboard/keyboard_controller_proxy.h" | 17 #include "ui/keyboard/keyboard_controller_proxy.h" |
19 | 18 |
20 namespace { | 19 namespace { |
21 | 20 |
22 gfx::Rect KeyboardBoundsFromWindowBounds(const gfx::Rect& window_bounds) { | 21 gfx::Rect KeyboardBoundsFromWindowBounds(const gfx::Rect& window_bounds) { |
23 const float kKeyboardHeightRatio = 0.3f; | 22 const float kKeyboardHeightRatio = 0.3f; |
24 return gfx::Rect( | 23 return gfx::Rect( |
25 window_bounds.x(), | 24 window_bounds.x(), |
26 window_bounds.y() + window_bounds.height() * (1 - kKeyboardHeightRatio), | 25 window_bounds.y() + window_bounds.height() * (1 - kKeyboardHeightRatio), |
27 window_bounds.width(), | 26 window_bounds.width(), |
28 window_bounds.height() * kKeyboardHeightRatio); | 27 window_bounds.height() * kKeyboardHeightRatio); |
29 } | 28 } |
30 | 29 |
31 // LayoutManager for the virtual keyboard container. Manages a single window | |
32 // (the virtual keyboard) and keeps it positioned at the bottom of the | |
33 // container window. | |
34 class KeyboardLayoutManager : public aura::LayoutManager { | |
35 public: | |
36 KeyboardLayoutManager(aura::Window* owner, aura::Window* keyboard) | |
37 : owner_(owner), keyboard_(keyboard) {} | |
38 | |
39 // Overridden from aura::LayoutManager | |
40 virtual void OnWindowResized() OVERRIDE { | |
41 SetChildBoundsDirect(keyboard_, | |
42 KeyboardBoundsFromWindowBounds(owner_->bounds())); | |
43 } | |
44 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { | |
45 CHECK(child == keyboard_); | |
46 } | |
47 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} | |
48 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} | |
49 virtual void OnChildWindowVisibilityChanged(aura::Window* child, | |
50 bool visible) OVERRIDE {} | |
51 virtual void SetChildBounds(aura::Window* child, | |
52 const gfx::Rect& requested_bounds) OVERRIDE { | |
53 // Drop these: the size should only be set in OnWindowResized. | |
54 } | |
55 | |
56 private: | |
57 aura::Window* owner_; | |
58 aura::Window* keyboard_; | |
59 | |
60 DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); | |
61 }; | |
62 | |
63 // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. | 30 // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. |
64 // This is necessary to make sure that the synthetic key-events reach the target | 31 // This is necessary to make sure that the synthetic key-events reach the target |
65 // window. | 32 // window. |
66 // The delegate deletes itself when the window is destroyed. | 33 // The delegate deletes itself when the window is destroyed. |
67 class KeyboardWindowDelegate : public aura::WindowDelegate { | 34 class KeyboardWindowDelegate : public aura::WindowDelegate { |
68 public: | 35 public: |
69 KeyboardWindowDelegate() {} | 36 KeyboardWindowDelegate() {} |
70 virtual ~KeyboardWindowDelegate() {} | 37 virtual ~KeyboardWindowDelegate() {} |
71 | 38 |
72 private: | 39 private: |
(...skipping 30 matching lines...) Expand all Loading... | |
103 virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE { return NULL; } | 70 virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE { return NULL; } |
104 | 71 |
105 gfx::Rect bounds_; | 72 gfx::Rect bounds_; |
106 DISALLOW_COPY_AND_ASSIGN(KeyboardWindowDelegate); | 73 DISALLOW_COPY_AND_ASSIGN(KeyboardWindowDelegate); |
107 }; | 74 }; |
108 | 75 |
109 } // namespace | 76 } // namespace |
110 | 77 |
111 namespace keyboard { | 78 namespace keyboard { |
112 | 79 |
80 // LayoutManager for the virtual keyboard container. Manages a single window | |
81 // (the virtual keyboard) and keeps it positioned at the bottom of the | |
82 // owner window. | |
83 class KeyboardLayoutManager : public aura::LayoutManager { | |
84 public: | |
85 KeyboardLayoutManager(aura::Window* owner) : owner_(owner), keyboard_(NULL) { | |
86 CHECK(owner_); | |
87 } | |
88 | |
89 aura::Window* owner() { return owner_; } | |
90 | |
91 void AddKeyboard(aura::Window* keyboard) { | |
92 keyboard->Show(); | |
93 owner_->AddChild(keyboard); | |
94 OnWindowResized(); | |
95 } | |
96 | |
97 bool HasKeyboard() { return keyboard_ != NULL; } | |
98 | |
99 void ShowKeyboard() { | |
100 owner_->parent()->StackChildAtTop(owner_); | |
101 owner_->Show(); | |
102 } | |
103 | |
104 void HideKeyboard() { | |
105 owner_->Hide(); | |
106 } | |
107 | |
108 // Overridden from aura::LayoutManager | |
109 virtual void OnWindowResized() OVERRIDE { | |
110 if (!keyboard_) | |
111 return; | |
112 SetChildBoundsDirect(keyboard_, | |
113 KeyboardBoundsFromWindowBounds(owner_->bounds())); | |
114 } | |
115 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { | |
116 DCHECK(!keyboard_); | |
117 keyboard_ = child; | |
118 } | |
119 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} | |
120 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} | |
121 virtual void OnChildWindowVisibilityChanged(aura::Window* child, | |
122 bool visible) OVERRIDE {} | |
123 virtual void SetChildBounds(aura::Window* child, | |
124 const gfx::Rect& requested_bounds) OVERRIDE { | |
125 // Drop these: the size should only be set in OnWindowResized. | |
126 } | |
127 | |
128 private: | |
129 aura::Window* owner_; | |
130 aura::Window* keyboard_; | |
131 | |
132 DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); | |
133 }; | |
134 | |
113 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) | 135 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
114 : proxy_(proxy), container_(NULL) { | 136 : proxy_(proxy), layout_manager_(NULL), input_method_(NULL) { |
115 CHECK(proxy); | 137 CHECK(proxy); |
116 proxy_->GetInputMethod()->AddObserver(this); | 138 input_method_ = proxy_->GetInputMethod(); |
139 input_method_->AddObserver(this); | |
sadrul
2013/04/15 03:48:44
I don't think having |input_method_| is useful her
bryeung
2013/04/15 15:02:22
Fetching the InputMethod from the Window propertie
| |
117 } | 140 } |
118 | 141 |
119 KeyboardController::~KeyboardController() { | 142 KeyboardController::~KeyboardController() { |
120 if (container_) | 143 input_method_->RemoveObserver(this); |
121 container_->RemoveObserver(this); | |
122 proxy_->GetInputMethod()->RemoveObserver(this); | |
123 } | 144 } |
124 | 145 |
125 aura::Window* KeyboardController::GetContainerWindow() { | 146 aura::Window* KeyboardController::GetContainerWindow() { |
126 if (!container_) { | 147 if (!layout_manager_) { |
127 container_ = new aura::Window(new KeyboardWindowDelegate()); | 148 aura::Window* container = new aura::Window(new KeyboardWindowDelegate()); |
128 container_->SetName("KeyboardContainer"); | 149 container->SetName("KeyboardContainer"); |
129 container_->Init(ui::LAYER_NOT_DRAWN); | 150 container->Init(ui::LAYER_NOT_DRAWN); |
130 container_->AddObserver(this); | 151 container->AddObserver(this); |
131 | 152 |
132 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | 153 layout_manager_ = new KeyboardLayoutManager(container); |
133 keyboard->Show(); | 154 container->SetLayoutManager(layout_manager_); |
134 | |
135 container_->SetLayoutManager( | |
136 new KeyboardLayoutManager(container_, keyboard)); | |
137 container_->AddChild(keyboard); | |
138 } | 155 } |
139 return container_; | 156 return layout_manager_->owner(); |
sadrul
2013/04/15 03:48:44
I think having the |container_| in the KC is easie
bryeung
2013/04/15 15:02:22
Okay. I didn't like having two different referenc
| |
140 } | 157 } |
141 | 158 |
142 void KeyboardController::OnTextInputStateChanged( | 159 void KeyboardController::OnTextInputStateChanged( |
143 const ui::TextInputClient* client) { | 160 const ui::TextInputClient* client) { |
144 if (!container_) | 161 if (!layout_manager_) |
145 return; | 162 return; |
146 | 163 |
147 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { | 164 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { |
148 container_->Hide(); | 165 layout_manager_->HideKeyboard(); |
149 } else { | 166 } else { |
150 container_->parent()->StackChildAtTop(container_); | 167 if (!layout_manager_->HasKeyboard()) |
sadrul
2013/04/15 03:48:44
Could you have just checked that container_->child
bryeung
2013/04/15 15:02:22
Done.
| |
151 container_->Show(); | 168 layout_manager_->AddKeyboard(proxy_->GetKeyboardWindow()); |
169 layout_manager_->ShowKeyboard(); | |
152 } | 170 } |
153 | |
154 // TODO(bryeung): whenever the TextInputClient changes we need to notify the | 171 // TODO(bryeung): whenever the TextInputClient changes we need to notify the |
155 // keyboard (with the TextInputType) so that it can reset it's state (e.g. | 172 // keyboard (with the TextInputType) so that it can reset it's state (e.g. |
156 // abandon compositions in progress) | 173 // abandon compositions in progress) |
157 } | 174 } |
158 | 175 |
159 void KeyboardController::OnWindowParentChanged(aura::Window* window, | 176 void KeyboardController::OnWindowParentChanged(aura::Window* window, |
160 aura::Window* parent) { | 177 aura::Window* parent) { |
161 OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); | 178 OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); |
162 } | 179 } |
163 | 180 |
164 void KeyboardController::OnWindowDestroying(aura::Window* window) { | 181 void KeyboardController::OnWindowDestroying(aura::Window* window) { |
165 DCHECK_EQ(container_, window); | 182 DCHECK(layout_manager_); |
166 container_ = NULL; | 183 DCHECK_EQ(layout_manager_->owner(), window); |
184 layout_manager_->owner()->RemoveObserver(this); | |
167 } | 185 } |
168 | 186 |
169 } // namespace keyboard | 187 } // namespace keyboard |
OLD | NEW |