diff options
author | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 06:36:07 +0000 |
---|---|---|
committer | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 06:36:07 +0000 |
commit | 4c5efadb9fc23637f82ccc2be85b1312f6d515ae (patch) | |
tree | 53e1b2ac9919fc44b18e9cdf27d5731960ee8ced | |
parent | 6f1e8731318f5ee11592e4323e919e4756a78984 (diff) | |
download | chromium_src-4c5efadb9fc23637f82ccc2be85b1312f6d515ae.zip chromium_src-4c5efadb9fc23637f82ccc2be85b1312f6d515ae.tar.gz chromium_src-4c5efadb9fc23637f82ccc2be85b1312f6d515ae.tar.bz2 |
IME (input method editor) support for Aura, part 2 of 3: Add views::InputMethodBridge
InputMethodBridge:
- Implements ui::TextInputClient interface, and receives IME results (e.g. composition text) from ui::InputMethod and forwards them to UI (e.g. a text field).
- Also receives a request like 'CancelComposition' from the UI and forwards it to ui::InputMethod.
Original review: http://codereview.chromium.org/8576005/ (PatchSet #1-8, Comment #1-24)
BUG=97261
TEST=see part 3 of 3.
Review URL: http://codereview.chromium.org/8687027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113131 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/views/ime/input_method_base.cc | 1 | ||||
-rw-r--r-- | ui/views/ime/input_method_bridge.cc | 204 | ||||
-rw-r--r-- | ui/views/ime/input_method_bridge.h | 82 | ||||
-rw-r--r-- | ui/views/ime/input_method_ibus.cc | 3 | ||||
-rw-r--r-- | ui/views/ime/input_method_ibus.h | 2 | ||||
-rw-r--r-- | ui/views/views.gyp | 2 |
6 files changed, 294 insertions, 0 deletions
diff --git a/ui/views/ime/input_method_base.cc b/ui/views/ime/input_method_base.cc index 14d2efd..f75b664 100644 --- a/ui/views/ime/input_method_base.cc +++ b/ui/views/ime/input_method_base.cc @@ -128,4 +128,5 @@ bool InputMethodBase::GetCaretBoundsInWidget(gfx::Rect* rect) const { return Widget::ConvertRect(GetFocusedView()->GetWidget(), widget_, rect); return true; } + } // namespace views diff --git a/ui/views/ime/input_method_bridge.cc b/ui/views/ime/input_method_bridge.cc new file mode 100644 index 0000000..1ca1631 --- /dev/null +++ b/ui/views/ime/input_method_bridge.cc @@ -0,0 +1,204 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/ime/input_method_bridge.h" + +#include "ui/base/ime/input_method.h" +#include "ui/gfx/rect.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace views { + +InputMethodBridge::InputMethodBridge(internal::InputMethodDelegate* delegate, + ui::InputMethod* host) + : host_(host), + context_focused_(false) { + DCHECK(host_); + set_delegate(delegate); +} + +InputMethodBridge::~InputMethodBridge() { + if (host_->GetTextInputClient() == this) + host_->SetFocusedTextInputClient(NULL); +} + +void InputMethodBridge::Init(Widget* widget) { + InputMethodBase::Init(widget); +} + +void InputMethodBridge::OnFocus() { + DCHECK(!widget_focused()); + InputMethodBase::OnFocus(); + + // Ask the system-wide IME to send all TextInputClient messages to |this| + // object. + host_->SetFocusedTextInputClient(this); + + // TODO(yusukes): We don't need to call OnTextInputTypeChanged() once we move + // text input type tracker code to ui::InputMethodBase. + if (GetFocusedView()) + OnTextInputTypeChanged(GetFocusedView()); +} + +void InputMethodBridge::OnBlur() { + DCHECK(widget_focused()); + + ConfirmCompositionText(); + InputMethodBase::OnBlur(); + if (host_->GetTextInputClient() == this) + host_->SetFocusedTextInputClient(NULL); +} + +void InputMethodBridge::DispatchKeyEvent(const KeyEvent& key) { + DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED); + DCHECK(widget_focused()); + + // We can just dispatch the event here since the |key| is already processed by + // the system-wide IME. + DispatchKeyEventPostIME(key); +} + +void InputMethodBridge::OnTextInputTypeChanged(View* view) { + if (IsViewFocused(view)) + host_->OnTextInputTypeChanged(this); + InputMethodBase::OnTextInputTypeChanged(view); +} + +void InputMethodBridge::OnCaretBoundsChanged(View* view) { + if (IsViewFocused(view) && !IsTextInputTypeNone()) + host_->OnCaretBoundsChanged(this); +} + +void InputMethodBridge::CancelComposition(View* view) { + if (IsViewFocused(view)) + host_->CancelComposition(this); +} + +std::string InputMethodBridge::GetInputLocale() { + return host_->GetInputLocale(); +} + +base::i18n::TextDirection InputMethodBridge::GetInputTextDirection() { + return host_->GetInputTextDirection(); +} + +bool InputMethodBridge::IsActive() { + return host_->IsActive(); +} + +// Overridden from TextInputClient. Forward an event from the system-wide IME +// to the text input |client|, which is e.g. views::NativeTextfieldViews. +void InputMethodBridge::SetCompositionText( + const ui::CompositionText& composition) { + TextInputClient* client = GetTextInputClient(); + if (client) + client->SetCompositionText(composition); +} + +void InputMethodBridge::ConfirmCompositionText() { + TextInputClient* client = GetTextInputClient(); + if (client) + client->ConfirmCompositionText(); +} + +void InputMethodBridge::ClearCompositionText() { + TextInputClient* client = GetTextInputClient(); + if (client) + client->ClearCompositionText(); +} + +void InputMethodBridge::InsertText(const string16& text) { + TextInputClient* client = GetTextInputClient(); + if (client) + client->InsertText(text); +} + +void InputMethodBridge::InsertChar(char16 ch, int flags) { + TextInputClient* client = GetTextInputClient(); + if (client) + client->InsertChar(ch, flags); +} + +ui::TextInputType InputMethodBridge::GetTextInputType() const { + TextInputClient* client = GetTextInputClient(); + return client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE; +} + +gfx::Rect InputMethodBridge::GetCaretBounds() { + TextInputClient* client = GetTextInputClient(); + if (!client || !GetFocusedView()) + return gfx::Rect(); + + const gfx::Rect rect = client->GetCaretBounds(); + gfx::Point origin = rect.origin(); + gfx::Point end = gfx::Point(rect.right(), rect.bottom()); + View::ConvertPointToScreen(GetFocusedView(), &origin); + View::ConvertPointToScreen(GetFocusedView(), &end); + return gfx::Rect(origin.x(), + origin.y(), + end.x() - origin.x(), + end.y() - origin.y()); +} + +bool InputMethodBridge::HasCompositionText() { + TextInputClient* client = GetTextInputClient(); + return client ? client->HasCompositionText() : false; +} + +bool InputMethodBridge::GetTextRange(ui::Range* range) { + TextInputClient* client = GetTextInputClient(); + return client ? client->GetTextRange(range) : false; +} + +bool InputMethodBridge::GetCompositionTextRange(ui::Range* range) { + TextInputClient* client = GetTextInputClient(); + return client ? client->GetCompositionTextRange(range) : false; +} + +bool InputMethodBridge::GetSelectionRange(ui::Range* range) { + TextInputClient* client = GetTextInputClient(); + return client ? client->GetSelectionRange(range) : false; +} + +bool InputMethodBridge::SetSelectionRange(const ui::Range& range) { + TextInputClient* client = GetTextInputClient(); + return client ? client->SetSelectionRange(range) : false; +} + +bool InputMethodBridge::DeleteRange(const ui::Range& range) { + TextInputClient* client = GetTextInputClient(); + return client ? client->DeleteRange(range) : false; +} + +bool InputMethodBridge::GetTextFromRange( + const ui::Range& range, string16* text) { + TextInputClient* client = GetTextInputClient(); + return client ? client->GetTextFromRange(range, text) : false; +} + +void InputMethodBridge::OnInputMethodChanged() { + TextInputClient* client = GetTextInputClient(); + if (client) + client->OnInputMethodChanged(); +} + +bool InputMethodBridge::ChangeTextDirectionAndLayoutAlignment( + base::i18n::TextDirection direction) { + TextInputClient* client = GetTextInputClient(); + return client ? + client->ChangeTextDirectionAndLayoutAlignment(direction) : false; +} + +// Overridden from FocusChangeListener. +void InputMethodBridge::OnWillChangeFocus(View* focused_before, View* focused) { + ConfirmCompositionText(); +} + +void InputMethodBridge::OnDidChangeFocus(View* focused_before, View* focused) { + OnTextInputTypeChanged(GetFocusedView()); + OnCaretBoundsChanged(GetFocusedView()); +} + +} // namespace views diff --git a/ui/views/ime/input_method_bridge.h b/ui/views/ime/input_method_bridge.h new file mode 100644 index 0000000..6f4b384 --- /dev/null +++ b/ui/views/ime/input_method_bridge.h @@ -0,0 +1,82 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_IME_INPUT_METHOD_BRIDGE_H_ +#define UI_VIEWS_IME_INPUT_METHOD_BRIDGE_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/base/ime/text_input_client.h" +#include "ui/views/ime/input_method_base.h" + +namespace ui { +class InputMethod; +} // namespace ui + +namespace views { + +class View; + +// A "bridge" InputMethod implementation for views top-level widgets, which just +// sends/receives IME related events to/from a system-wide ui::InputMethod +// object. +class InputMethodBridge : public InputMethodBase, + public ui::TextInputClient { + public: + InputMethodBridge(internal::InputMethodDelegate* delegate, + ui::InputMethod* host); + virtual ~InputMethodBridge(); + + // Overridden from InputMethod: + virtual void Init(Widget* widget) OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; + virtual void DispatchKeyEvent(const KeyEvent& key) OVERRIDE; + virtual void OnTextInputTypeChanged(View* view) OVERRIDE; + virtual void OnCaretBoundsChanged(View* view) OVERRIDE; + virtual void CancelComposition(View* view) OVERRIDE; + virtual std::string GetInputLocale() OVERRIDE; + virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE; + virtual bool IsActive() OVERRIDE; + + // Overridden from TextInputClient: + virtual void SetCompositionText( + const ui::CompositionText& composition) OVERRIDE; + virtual void ConfirmCompositionText() OVERRIDE; + virtual void ClearCompositionText() OVERRIDE; + virtual void InsertText(const string16& text) OVERRIDE; + virtual void InsertChar(char16 ch, int flags) OVERRIDE; + virtual ui::TextInputType GetTextInputType() const OVERRIDE; + virtual gfx::Rect GetCaretBounds() OVERRIDE; + virtual bool HasCompositionText() OVERRIDE; + virtual bool GetTextRange(ui::Range* range) OVERRIDE; + virtual bool GetCompositionTextRange(ui::Range* range) OVERRIDE; + virtual bool GetSelectionRange(ui::Range* range) OVERRIDE; + virtual bool SetSelectionRange(const ui::Range& range) OVERRIDE; + virtual bool DeleteRange(const ui::Range& range) OVERRIDE; + virtual bool GetTextFromRange( + const ui::Range& range, string16* text) OVERRIDE; + virtual void OnInputMethodChanged() OVERRIDE; + virtual bool ChangeTextDirectionAndLayoutAlignment( + base::i18n::TextDirection direction) OVERRIDE; + + // Overridden from FocusChangeListener. + virtual void OnWillChangeFocus(View* focused_before, View* focused) OVERRIDE; + virtual void OnDidChangeFocus(View* focused_before, View* focused) OVERRIDE; + + private: + void UpdateViewFocusState(); + + ui::InputMethod* const host_; + bool context_focused_; + + DISALLOW_COPY_AND_ASSIGN(InputMethodBridge); +}; + +} // namespace views + +#endif // UI_VIEWS_IME_INPUT_METHOD_BRIDGE_H_ diff --git a/ui/views/ime/input_method_ibus.cc b/ui/views/ime/input_method_ibus.cc index 3f3a6b8..a68c74f 100644 --- a/ui/views/ime/input_method_ibus.cc +++ b/ui/views/ime/input_method_ibus.cc @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// TODO(yusukes): Remove this class when TOUCH_UI migrates to Aura. For Aura, +// ui/base/ime/input_method_* classes are available. + #include "ui/views/ime/input_method_ibus.h" #include <ibus.h> diff --git a/ui/views/ime/input_method_ibus.h b/ui/views/ime/input_method_ibus.h index 8af9c11..eba28c8 100644 --- a/ui/views/ime/input_method_ibus.h +++ b/ui/views/ime/input_method_ibus.h @@ -30,6 +30,8 @@ typedef struct _IBusText IBusText; namespace views { // An InputMethod implementation based on IBus. +// TODO(yusukes): Remove this class when TOUCH_UI migrates to Aura. For Aura, +// ui/base/ime/input_method_* classes are available. class InputMethodIBus : public InputMethodBase { public: explicit InputMethodIBus(internal::InputMethodDelegate* delegate); diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 9c527ee..3b60864 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -274,6 +274,8 @@ 'focus/widget_focus_manager.h', 'ime/input_method_base.cc', 'ime/input_method_base.h', + 'ime/input_method_bridge.cc', + 'ime/input_method_bridge.h', 'ime/input_method_delegate.h', 'ime/input_method_gtk.cc', 'ime/input_method_gtk.h', |