Commit 4c5efadb authored by yusukes@google.com's avatar yusukes@google.com

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
parent 6f1e8731
......@@ -128,4 +128,5 @@ bool InputMethodBase::GetCaretBoundsInWidget(gfx::Rect* rect) const {
return Widget::ConvertRect(GetFocusedView()->GetWidget(), widget_, rect);
return true;
}
} // namespace views
// 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
// 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_
......@@ -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>
......
......@@ -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);
......
......@@ -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',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment