Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / candidate_window_controller_impl.cc
bloba06600415ce66738b562682725df290411839739
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.
5 #include "chrome/browser/chromeos/input_method/candidate_window_controller_impl.h"
7 #include <string>
8 #include <vector>
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "ash/wm/window_util.h"
13 #include "base/logging.h"
14 #include "chrome/browser/chromeos/input_method/mode_indicator_controller.h"
15 #include "ui/chromeos/ime/infolist_window.h"
16 #include "ui/gfx/screen.h"
17 #include "ui/views/widget/widget.h"
19 namespace chromeos {
20 namespace input_method {
22 namespace {
24 } // namespace
26 CandidateWindowControllerImpl::CandidateWindowControllerImpl()
27 : candidate_window_view_(NULL),
28 infolist_window_(NULL) {
29 IMEBridge::Get()->SetCandidateWindowHandler(this);
30 // Create the mode indicator controller.
31 mode_indicator_controller_.reset(
32 new ModeIndicatorController(InputMethodManager::Get()));
35 CandidateWindowControllerImpl::~CandidateWindowControllerImpl() {
36 IMEBridge::Get()->SetCandidateWindowHandler(NULL);
37 if (candidate_window_view_) {
38 candidate_window_view_->RemoveObserver(this);
39 candidate_window_view_->GetWidget()->RemoveObserver(this);
43 void CandidateWindowControllerImpl::InitCandidateWindowView() {
44 if (candidate_window_view_)
45 return;
47 aura::Window* active_window = ash::wm::GetActiveWindow();
48 candidate_window_view_ =
49 new ui::ime::CandidateWindowView(ash::Shell::GetContainer(
50 active_window ? active_window->GetRootWindow()
51 : ash::Shell::GetTargetRootWindow(),
52 ash::kShellWindowId_SettingBubbleContainer));
53 candidate_window_view_->AddObserver(this);
54 candidate_window_view_->SetCursorBounds(cursor_bounds_, composition_head_);
55 views::Widget* widget = candidate_window_view_->InitWidget();
56 widget->AddObserver(this);
57 widget->Show();
58 FOR_EACH_OBSERVER(CandidateWindowController::Observer, observers_,
59 CandidateWindowOpened());
62 void CandidateWindowControllerImpl::Hide() {
63 if (candidate_window_view_)
64 candidate_window_view_->GetWidget()->Close();
65 if (infolist_window_)
66 infolist_window_->HideImmediately();
69 void CandidateWindowControllerImpl::SetCursorBounds(
70 const gfx::Rect& cursor_bounds,
71 const gfx::Rect& composition_head) {
72 // A workaround for http://crosbug.com/6460. We should ignore very short Y
73 // move to prevent the window from shaking up and down.
74 const int kKeepPositionThreshold = 2; // px
75 gfx::Rect last_bounds;
76 if (candidate_window_view_)
77 last_bounds = candidate_window_view_->GetAnchorRect();
79 const int delta_y = abs(last_bounds.y() - cursor_bounds.y());
80 if ((last_bounds.x() == cursor_bounds.x()) &&
81 (delta_y <= kKeepPositionThreshold)) {
82 DVLOG(1) << "Ignored set_cursor_bounds signal to prevent window shake";
83 return;
86 cursor_bounds_ = cursor_bounds;
87 composition_head_ = composition_head;
89 // Remember the cursor bounds.
90 if (candidate_window_view_)
91 candidate_window_view_->SetCursorBounds(cursor_bounds, composition_head);
93 // Mode indicator controller also needs the cursor bounds.
94 mode_indicator_controller_->SetCursorBounds(cursor_bounds);
97 void CandidateWindowControllerImpl::FocusStateChanged(bool is_focused) {
98 mode_indicator_controller_->FocusStateChanged(is_focused);
101 void CandidateWindowControllerImpl::UpdateLookupTable(
102 const ui::CandidateWindow& candidate_window,
103 bool visible) {
104 // If it's not visible, hide the lookup table and return.
105 if (!visible) {
106 if (candidate_window_view_)
107 candidate_window_view_->HideLookupTable();
108 if (infolist_window_)
109 infolist_window_->HideImmediately();
110 // TODO(nona): Introduce unittests for crbug.com/170036.
111 latest_infolist_entries_.clear();
112 return;
115 if (!candidate_window_view_)
116 InitCandidateWindowView();
117 candidate_window_view_->UpdateCandidates(candidate_window);
118 candidate_window_view_->ShowLookupTable();
120 bool has_highlighted = false;
121 std::vector<ui::InfolistEntry> infolist_entries;
122 candidate_window.GetInfolistEntries(&infolist_entries, &has_highlighted);
124 // If there is no change, just return.
125 if (latest_infolist_entries_ == infolist_entries)
126 return;
128 latest_infolist_entries_ = infolist_entries;
130 if (infolist_entries.empty()) {
131 if (infolist_window_)
132 infolist_window_->HideImmediately();
133 return;
136 // Highlight moves out of the infolist entries.
137 if (!has_highlighted) {
138 if (infolist_window_)
139 infolist_window_->HideWithDelay();
140 return;
143 if (infolist_window_) {
144 infolist_window_->Relayout(infolist_entries);
145 } else {
146 infolist_window_ = new ui::ime::InfolistWindow(
147 candidate_window_view_, infolist_entries);
148 infolist_window_->InitWidget();
149 infolist_window_->GetWidget()->AddObserver(this);
151 infolist_window_->ShowWithDelay();
154 void CandidateWindowControllerImpl::UpdatePreeditText(
155 const base::string16& text, unsigned int cursor, bool visible) {
156 // If it's not visible, hide the preedit text and return.
157 if (!visible || text.empty()) {
158 if (candidate_window_view_)
159 candidate_window_view_->HidePreeditText();
160 return;
162 if (!candidate_window_view_)
163 InitCandidateWindowView();
164 candidate_window_view_->UpdatePreeditText(text);
165 candidate_window_view_->ShowPreeditText();
168 void CandidateWindowControllerImpl::OnCandidateCommitted(int index) {
169 FOR_EACH_OBSERVER(CandidateWindowController::Observer, observers_,
170 CandidateClicked(index));
173 void CandidateWindowControllerImpl::OnWidgetClosing(views::Widget* widget) {
174 if (infolist_window_ && widget == infolist_window_->GetWidget()) {
175 widget->RemoveObserver(this);
176 infolist_window_ = NULL;
177 } else if (candidate_window_view_ &&
178 widget == candidate_window_view_->GetWidget()) {
179 widget->RemoveObserver(this);
180 candidate_window_view_->RemoveObserver(this);
181 candidate_window_view_ = NULL;
182 FOR_EACH_OBSERVER(CandidateWindowController::Observer, observers_,
183 CandidateWindowClosed());
187 void CandidateWindowControllerImpl::AddObserver(
188 CandidateWindowController::Observer* observer) {
189 observers_.AddObserver(observer);
192 void CandidateWindowControllerImpl::RemoveObserver(
193 CandidateWindowController::Observer* observer) {
194 observers_.RemoveObserver(observer);
197 } // namespace input_method
198 } // namespace chromeos