15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/ime/input_method_base.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ime/text_input_client.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)InputMethodBase::InputMethodBase() : delegate_(NULL), widget_(NULL) {}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputMethodBase::~InputMethodBase() {
18558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DetachFromWidget();
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodBase::SetDelegate(internal::InputMethodDelegate* delegate) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodBase::Init(Widget* widget) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(widget);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(widget->GetFocusManager());
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!widget_) << "The input method is already initialized.";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget_ = widget;
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Alert the InputMethod of the Widget's currently focused view.
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  View* focused = widget->GetFocusManager()->GetFocusedView();
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (focused)
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    OnWillChangeFocus(NULL, focused);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->GetFocusManager()->AddFocusChangeListener(this);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* InputMethodBase::GetFocusedView() const {
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return widget_ ? widget_->GetFocusManager()->GetFocusedView() : NULL;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodBase::OnTextInputTypeChanged(View* view) {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::TextInputClient* InputMethodBase::GetTextInputClient() const {
46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return (widget_ && widget_->IsActive() && GetFocusedView()) ?
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetFocusedView()->GetTextInputClient() : NULL;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::TextInputType InputMethodBase::GetTextInputType() const {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TextInputClient* client = GetTextInputClient();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodBase::IsMock() const {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodBase::OnWillChangeFocus(View* focused_before, View* focused) {}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodBase::OnDidChangeFocus(View* focused_before, View* focused) {}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodBase::IsViewFocused(View* view) const {
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return widget_ && widget_->IsActive() && view && GetFocusedView() == view;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodBase::IsTextInputTypeNone() const {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodBase::OnInputMethodChanged() const {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TextInputClient* client = GetTextInputClient();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client && client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client->OnInputMethodChanged();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodBase::DispatchKeyEventPostIME(const ui::KeyEvent& key) const {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->DispatchKeyEventPostIME(key);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodBase::GetCaretBoundsInWidget(gfx::Rect* rect) const {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rect);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TextInputClient* client = GetTextInputClient();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gfx::Rect caret_bounds = client->GetCaretBounds();
89a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gfx::Point caret_origin = caret_bounds.origin();
90a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  View::ConvertPointFromScreen(GetFocusedView(), &caret_origin);
91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  caret_bounds.set_origin(caret_origin);
92a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  *rect = GetFocusedView()->ConvertRectToWidget(caret_bounds);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Convert coordinates if the focused view is inside a child Widget.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetFocusedView()->GetWidget() != widget_)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Widget::ConvertRect(GetFocusedView()->GetWidget(), widget_, rect);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid InputMethodBase::DetachFromWidget() {
101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!widget_)
102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget_->GetFocusManager()->RemoveFocusChangeListener(this);
105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget_ = NULL;
106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
107558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
109