1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/views/ime/input_method_base.h"
6
7#include "base/logging.h"
8#include "ui/base/ime/text_input_client.h"
9#include "ui/events/event.h"
10#include "ui/views/view.h"
11#include "ui/views/widget/widget.h"
12
13namespace views {
14
15InputMethodBase::InputMethodBase() : delegate_(NULL), widget_(NULL) {}
16
17InputMethodBase::~InputMethodBase() {
18  DetachFromWidget();
19}
20
21void InputMethodBase::SetDelegate(internal::InputMethodDelegate* delegate) {
22  DCHECK(delegate);
23  delegate_ = delegate;
24}
25
26void InputMethodBase::Init(Widget* widget) {
27  DCHECK(widget);
28  DCHECK(widget->GetFocusManager());
29  DCHECK(!widget_) << "The input method is already initialized.";
30
31  widget_ = widget;
32  // Alert the InputMethod of the Widget's currently focused view.
33  View* focused = widget->GetFocusManager()->GetFocusedView();
34  if (focused)
35    OnWillChangeFocus(NULL, focused);
36  widget->GetFocusManager()->AddFocusChangeListener(this);
37}
38
39views::View* InputMethodBase::GetFocusedView() const {
40  return widget_ ? widget_->GetFocusManager()->GetFocusedView() : NULL;
41}
42
43void InputMethodBase::OnTextInputTypeChanged(View* view) {}
44
45ui::TextInputClient* InputMethodBase::GetTextInputClient() const {
46  return (widget_ && widget_->IsActive() && GetFocusedView()) ?
47      GetFocusedView()->GetTextInputClient() : NULL;
48}
49
50ui::TextInputType InputMethodBase::GetTextInputType() const {
51  ui::TextInputClient* client = GetTextInputClient();
52  return client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE;
53}
54
55bool InputMethodBase::IsMock() const {
56  return false;
57}
58
59void InputMethodBase::OnWillChangeFocus(View* focused_before, View* focused) {}
60
61void InputMethodBase::OnDidChangeFocus(View* focused_before, View* focused) {}
62
63bool InputMethodBase::IsViewFocused(View* view) const {
64  return widget_ && widget_->IsActive() && view && GetFocusedView() == view;
65}
66
67bool InputMethodBase::IsTextInputTypeNone() const {
68  return GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE;
69}
70
71void InputMethodBase::OnInputMethodChanged() const {
72  ui::TextInputClient* client = GetTextInputClient();
73  if (client && client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE)
74    client->OnInputMethodChanged();
75}
76
77void InputMethodBase::DispatchKeyEventPostIME(const ui::KeyEvent& key) const {
78  if (delegate_)
79    delegate_->DispatchKeyEventPostIME(key);
80}
81
82bool InputMethodBase::GetCaretBoundsInWidget(gfx::Rect* rect) const {
83  DCHECK(rect);
84  ui::TextInputClient* client = GetTextInputClient();
85  if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
86    return false;
87
88  gfx::Rect caret_bounds = client->GetCaretBounds();
89  gfx::Point caret_origin = caret_bounds.origin();
90  View::ConvertPointFromScreen(GetFocusedView(), &caret_origin);
91  caret_bounds.set_origin(caret_origin);
92  *rect = GetFocusedView()->ConvertRectToWidget(caret_bounds);
93
94  // Convert coordinates if the focused view is inside a child Widget.
95  if (GetFocusedView()->GetWidget() != widget_)
96    return Widget::ConvertRect(GetFocusedView()->GetWidget(), widget_, rect);
97  return true;
98}
99
100void InputMethodBase::DetachFromWidget() {
101  if (!widget_)
102    return;
103
104  widget_->GetFocusManager()->RemoveFocusChangeListener(this);
105  widget_ = NULL;
106}
107
108}  // namespace views
109