Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: views/ime/input_method_win.cc

Issue 6688049: New InputMethod api for Views. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "views/ime/input_method_win.h"
6
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/string_util.h"
10 #include "ui/base/keycodes/keyboard_codes.h"
11 #include "views/events/event.h"
12
13 namespace views {
14
15 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate)
16 : active_(false),
17 direction_(base::i18n::UNKNOWN_DIRECTION),
18 pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION) {
19 set_delegate(delegate);
20 }
21
22 InputMethodWin::~InputMethodWin() {
23 if (widget())
24 ime_input_.DisableIME(hwnd());
25 }
26
27 void InputMethodWin::Init(Widget* widget) {
28 InputMethodBase::Init(widget);
29
30 // Gets the initial input locale and text direction information.
31 OnInputLangChange(0, 0);
32 }
33
34 void InputMethodWin::OnFocusIn() {
35 DCHECK(!widget_focused());
36 InputMethodBase::OnFocusIn();
37 UpdateIMEState();
38 }
39
40 void InputMethodWin::OnFocusOut() {
41 DCHECK(widget_focused());
42 ConfirmCompositionText();
43 InputMethodBase::OnFocusOut();
44 }
45
46 void InputMethodWin::DispatchKeyEvent(const KeyEvent& key) {
47 // Handles ctrl-shift key to change text direction and layout alignment.
48 if (ui::ImeInput::IsRTLKeyboardLayoutInstalled() && !IsTextInputTypeNone()) {
49 ui::KeyboardCode code = key.key_code();
50 if (key.type() == ui::ET_KEY_PRESSED) {
51 if (code == ui::VKEY_SHIFT) {
52 base::i18n::TextDirection dir;
53 if (ui::ImeInput::IsCtrlShiftPressed(&dir))
54 pending_requested_direction_ = dir;
55 } else if (code != ui::VKEY_CONTROL) {
56 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION;
57 }
58 } else if (key.type() == ui::ET_KEY_RELEASED &&
59 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) &&
60 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) {
61 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment(
62 pending_requested_direction_);
63 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION;
64 }
65 }
66
67 DispatchKeyEventPostIME(key);
68 }
69
70 void InputMethodWin::OnTextInputTypeChanged(View* view) {
71 if (IsViewFocused(view)) {
72 ime_input_.CancelIME(hwnd());
73 UpdateIMEState();
74 }
75 }
76
77 void InputMethodWin::OnCaretBoundsChanged(View* view) {
78 gfx::Rect rect;
79 if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
80 return;
81 ime_input_.UpdateCaretRect(hwnd(), rect);
82 }
83
84 void InputMethodWin::CancelComposition(View* view) {
85 if (IsViewFocused(view))
86 ime_input_.CancelIME(hwnd());
87 }
88
89 std::string InputMethodWin::GetInputLocale() {
90 return locale_;
91 }
92
93 base::i18n::TextDirection InputMethodWin::GetInputTextDirection() {
94 return direction_;
95 }
96
97 bool InputMethodWin::IsActive() {
98 return active_;
99 }
100
101 void InputMethodWin::FocusedViewWillChange() {
102 ConfirmCompositionText();
103 }
104
105 void InputMethodWin::FocusedViewDidChange() {
106 UpdateIMEState();
107 }
108
109 void InputMethodWin::OnInputLangChange(DWORD character_set,
110 HKL input_language_id) {
111 active_ = ime_input_.SetInputLanguage();
112 locale_ = ime_input_.GetInputLanguageName();
113 direction_ = ime_input_.GetTextDirection();
114 OnInputMethodChanged();
115 }
116
117 LRESULT InputMethodWin::OnImeSetContext(
118 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
119 active_ = (wparam == TRUE);
120 if (active_)
121 ime_input_.CreateImeWindow(hwnd());
122
123 OnInputMethodChanged();
124 return ime_input_.SetImeWindowStyle(hwnd(), message, wparam, lparam, handled);
125 }
126
127 LRESULT InputMethodWin::OnImeStartComposition(
128 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
129 // We have to prevent WTL from calling ::DefWindowProc() because the function
130 // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to
131 // over-write the position of IME windows.
132 *handled = TRUE;
133
134 if (IsTextInputTypeNone())
135 return 0;
136
137 // Reset the composition status and create IME windows.
138 ime_input_.CreateImeWindow(hwnd());
139 ime_input_.ResetComposition(hwnd());
140 return 0;
141 }
142
143 LRESULT InputMethodWin::OnImeComposition(
144 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
145 // We have to prevent WTL from calling ::DefWindowProc() because we do not
146 // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages.
147 *handled = TRUE;
148
149 if (IsTextInputTypeNone())
150 return 0;
151
152 // At first, update the position of the IME window.
153 ime_input_.UpdateImeWindow(hwnd());
154
155 // Retrieve the result string and its attributes of the ongoing composition
156 // and send it to a renderer process.
157 ui::CompositionText composition;
158 if (ime_input_.GetResult(hwnd(), lparam, &composition.text)) {
159 GetTextInputClient()->InsertText(composition.text);
160 ime_input_.ResetComposition(hwnd());
161 // Fall though and try reading the composition string.
162 // Japanese IMEs send a message containing both GCS_RESULTSTR and
163 // GCS_COMPSTR, which means an ongoing composition has been finished
164 // by the start of another composition.
165 }
166 // Retrieve the composition string and its attributes of the ongoing
167 // composition and send it to a renderer process.
168 if (ime_input_.GetComposition(hwnd(), lparam, &composition))
169 GetTextInputClient()->SetCompositionText(composition);
170
171 return 0;
172 }
173
174 LRESULT InputMethodWin::OnImeEndComposition(
175 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
176 // Let WTL call ::DefWindowProc() and release its resources.
177 *handled = FALSE;
178
179 if (IsTextInputTypeNone())
180 return 0;
181
182 if (GetTextInputClient()->HasCompositionText())
183 GetTextInputClient()->ClearCompositionText();
184
185 ime_input_.ResetComposition(hwnd());
186 ime_input_.DestroyImeWindow(hwnd());
187 return 0;
188 }
189
190 LRESULT InputMethodWin::OnChar(
191 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
192 *handled = TRUE;
193
194 // We need to send character events to the focused text input client event if
195 // its text input type is ui::TEXT_INPUT_TYPE_NONE.
196 if (!GetTextInputClient())
197 return 0;
198
199 int flags = 0;
200 flags |= (::GetKeyState(VK_MENU) & 0x80)? ui::EF_ALT_DOWN : 0;
201 flags |= (::GetKeyState(VK_SHIFT) & 0x80)? ui::EF_SHIFT_DOWN : 0;
202 flags |= (::GetKeyState(VK_CONTROL) & 0x80)? ui::EF_CONTROL_DOWN : 0;
203 GetTextInputClient()->InsertChar(static_cast<char16>(wparam), flags);
204 return 0;
205 }
206
207 LRESULT InputMethodWin::OnDeadChar(
208 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
209 *handled = TRUE;
210
211 if (IsTextInputTypeNone())
212 return 0;
213
214 // Shows the dead character as a composition text, so that the user can know
215 // what dead key was pressed.
216 ui::CompositionText composition;
217 composition.text.assign(1, static_cast<char16>(wparam));
218 composition.selection = ui::Range(0, 1);
219 composition.underlines.push_back(
220 ui::CompositionUnderline(0, 1, SK_ColorBLACK, false));
221 GetTextInputClient()->SetCompositionText(composition);
222 return 0;
223 }
224
225 void InputMethodWin::ConfirmCompositionText() {
226 if (!IsTextInputTypeNone()) {
227 ime_input_.CleanupComposition(hwnd());
228 // Though above line should confirm the client's composition text by sending
229 // a result text to us, in case the input method and the client are in
230 // inconsistent states, we check the client's composition state again.
231 if (GetTextInputClient()->HasCompositionText())
232 GetTextInputClient()->ConfirmCompositionText();
233 }
234 }
235
236 void InputMethodWin::UpdateIMEState() {
237 // Use switch here in case we are going to add more text input types.
238 // We disable input method in password field.
239 switch (GetTextInputType()) {
240 case ui::TEXT_INPUT_TYPE_NONE:
241 case ui::TEXT_INPUT_TYPE_PASSWORD:
242 ime_input_.DisableIME(hwnd());
243 break;
244 default:
245 ime_input_.EnableIME(hwnd());
246 break;
247 }
248 }
249
250 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698