| 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* container) |
| 86 : container_(container), keyboard_(NULL) { |
| 87 CHECK(container_); |
| 88 } |
| 89 |
| 90 // Overridden from aura::LayoutManager |
| 91 virtual void OnWindowResized() OVERRIDE { |
| 92 if (!keyboard_) |
| 93 return; |
| 94 SetChildBoundsDirect(keyboard_, |
| 95 KeyboardBoundsFromWindowBounds(container_->bounds())); |
| 96 } |
| 97 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { |
| 98 DCHECK(!keyboard_); |
| 99 keyboard_ = child; |
| 100 } |
| 101 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} |
| 102 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} |
| 103 virtual void OnChildWindowVisibilityChanged(aura::Window* child, |
| 104 bool visible) OVERRIDE {} |
| 105 virtual void SetChildBounds(aura::Window* child, |
| 106 const gfx::Rect& requested_bounds) OVERRIDE { |
| 107 // Drop these: the size should only be set in OnWindowResized. |
| 108 } |
| 109 |
| 110 private: |
| 111 aura::Window* container_; |
| 112 aura::Window* keyboard_; |
| 113 |
| 114 DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); |
| 115 }; |
| 116 |
| 113 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) | 117 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
| 114 : proxy_(proxy), container_(NULL) { | 118 : proxy_(proxy), |
| 119 container_(NULL), |
| 120 input_method_(NULL) { |
| 115 CHECK(proxy); | 121 CHECK(proxy); |
| 116 proxy_->GetInputMethod()->AddObserver(this); | 122 input_method_ = proxy_->GetInputMethod(); |
| 123 input_method_->AddObserver(this); |
| 117 } | 124 } |
| 118 | 125 |
| 119 KeyboardController::~KeyboardController() { | 126 KeyboardController::~KeyboardController() { |
| 120 if (container_) | 127 if (container_) |
| 121 container_->RemoveObserver(this); | 128 container_->RemoveObserver(this); |
| 122 proxy_->GetInputMethod()->RemoveObserver(this); | 129 if (input_method_) |
| 130 input_method_->RemoveObserver(this); |
| 123 } | 131 } |
| 124 | 132 |
| 125 aura::Window* KeyboardController::GetContainerWindow() { | 133 aura::Window* KeyboardController::GetContainerWindow() { |
| 126 if (!container_) { | 134 if (!container_) { |
| 127 container_ = new aura::Window(new KeyboardWindowDelegate()); | 135 container_ = new aura::Window(new KeyboardWindowDelegate()); |
| 128 container_->SetName("KeyboardContainer"); | 136 container_->SetName("KeyboardContainer"); |
| 129 container_->Init(ui::LAYER_NOT_DRAWN); | 137 container_->Init(ui::LAYER_NOT_DRAWN); |
| 130 container_->AddObserver(this); | 138 container_->AddObserver(this); |
| 131 | 139 container_->SetLayoutManager(new KeyboardLayoutManager(container_)); |
| 132 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | |
| 133 keyboard->Show(); | |
| 134 | |
| 135 container_->SetLayoutManager( | |
| 136 new KeyboardLayoutManager(container_, keyboard)); | |
| 137 container_->AddChild(keyboard); | |
| 138 } | 140 } |
| 139 return container_; | 141 return container_; |
| 140 } | 142 } |
| 141 | 143 |
| 144 void KeyboardController::OnWindowParentChanged(aura::Window* window, |
| 145 aura::Window* parent) { |
| 146 OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); |
| 147 } |
| 148 |
| 149 void KeyboardController::OnWindowDestroying(aura::Window* window) { |
| 150 DCHECK_EQ(container_, window); |
| 151 container_ = NULL; |
| 152 } |
| 153 |
| 142 void KeyboardController::OnTextInputStateChanged( | 154 void KeyboardController::OnTextInputStateChanged( |
| 143 const ui::TextInputClient* client) { | 155 const ui::TextInputClient* client) { |
| 144 if (!container_) | 156 if (!container_) |
| 145 return; | 157 return; |
| 146 | 158 |
| 147 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { | 159 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { |
| 148 container_->Hide(); | 160 container_->Hide(); |
| 149 } else { | 161 } else { |
| 162 if (container_->children().empty()) { |
| 163 aura::Window* keyboard = proxy_->GetKeyboardWindow(); |
| 164 keyboard->Show(); |
| 165 container_->AddChild(keyboard); |
| 166 container_->layout_manager()->OnWindowResized(); |
| 167 } |
| 150 container_->parent()->StackChildAtTop(container_); | 168 container_->parent()->StackChildAtTop(container_); |
| 151 container_->Show(); | 169 container_->Show(); |
| 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::OnInputMethodDestroyed( |
| 160 aura::Window* parent) { | 177 const ui::InputMethod* input_method) { |
| 161 OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); | 178 DCHECK_EQ(input_method_, input_method); |
| 162 } | 179 input_method_ = NULL; |
| 163 | |
| 164 void KeyboardController::OnWindowDestroying(aura::Window* window) { | |
| 165 DCHECK_EQ(container_, window); | |
| 166 container_ = NULL; | |
| 167 } | 180 } |
| 168 | 181 |
| 169 } // namespace keyboard | 182 } // namespace keyboard |
| OLD | NEW |