summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-06 06:36:07 +0000
committeryusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-06 06:36:07 +0000
commit4c5efadb9fc23637f82ccc2be85b1312f6d515ae (patch)
tree53e1b2ac9919fc44b18e9cdf27d5731960ee8ced
parent6f1e8731318f5ee11592e4323e919e4756a78984 (diff)
downloadchromium_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.cc1
-rw-r--r--ui/views/ime/input_method_bridge.cc204
-rw-r--r--ui/views/ime/input_method_bridge.h82
-rw-r--r--ui/views/ime/input_method_ibus.cc3
-rw-r--r--ui/views/ime/input_method_ibus.h2
-rw-r--r--ui/views/views.gyp2
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',