Revision | e22b5d3d9e4edbd0e227503e3f469acf8d84008c (tree) |
---|---|
Time | 2017-01-15 22:22:46 |
Author | <exeal@user...> |
Refined around InputMethodEvent class.
@@ -54,7 +54,7 @@ | ||
54 | 54 | |
55 | 55 | // documentation is caret.cpp |
56 | 56 | class Caret : public VisualPoint, |
57 | - public kernel::DocumentListener, public detail::InputMethodEventHandler, public detail::InputMethodQueryEvent { | |
57 | + public kernel::DocumentListener, public detail::InputMethodEventHandler, public detail::InputMethodQueryEventHandler { | |
58 | 58 | public: |
59 | 59 | /// Mode of tracking match brackets. |
60 | 60 | enum MatchBracketsTrackingMode { |
@@ -201,9 +201,12 @@ | ||
201 | 201 | void documentAboutToBeChanged(const kernel::Document& document) override; |
202 | 202 | void documentChanged(const kernel::Document& document, const kernel::DocumentChange& change) override; |
203 | 203 | // detail.InputMethodEventHandler |
204 | - void handleInputMethodEvent(widgetapi::event::InputMethodEvent& event, const void* nativeEvent) BOOST_NOEXCEPT override; | |
205 | - // detail.InputMethodQueryEvent | |
206 | - void handleInputMethodQueryEvent(widgetapi::event::InputMethodQueryEvent& event, const void* nativeEvent) BOOST_NOEXCEPT override; | |
204 | + void commitString(widgetapi::event::InputMethodEvent& event) BOOST_NOEXCEPT override; | |
205 | + void preeditChanged(widgetapi::event::InputMethodEvent& event) BOOST_NOEXCEPT override; | |
206 | + void preeditEnded() BOOST_NOEXCEPT override; | |
207 | + void preeditStarted() BOOST_NOEXCEPT override; | |
208 | + // detail.InputMethodQueryEventHandler | |
209 | + std::pair<const StringPiece, StringPiece::const_iterator> querySurroundingText() const BOOST_NOEXCEPT override; | |
207 | 210 | private: |
208 | 211 | class SelectionAnchor : public VisualPoint { |
209 | 212 | public: |
@@ -21,13 +21,15 @@ | ||
21 | 21 | |
22 | 22 | namespace detail { |
23 | 23 | class InputMethodEventHandler { |
24 | - virtual void handleInputMethodEvent(widgetapi::event::InputMethodEvent& event, const void* nativeEvent) BOOST_NOEXCEPT = 0; | |
25 | - virtual void handleInputMethodQueryEvent(widgetapi::event::InputMethodQueryEvent& event, const void* nativeEvent) BOOST_NOEXCEPT = 0; | |
24 | + virtual void commitString(widgetapi::event::InputMethodEvent& event) BOOST_NOEXCEPT = 0; | |
25 | + virtual void preeditChanged(widgetapi::event::InputMethodEvent& event) BOOST_NOEXCEPT = 0; | |
26 | + virtual void preeditEnded() BOOST_NOEXCEPT = 0; | |
27 | + virtual void preeditStarted() BOOST_NOEXCEPT = 0; | |
26 | 28 | friend class TextViewer; |
27 | 29 | }; |
28 | 30 | |
29 | - class InputMethodQueryEvent { | |
30 | - virtual std::pair<const StringPiece, StringPiece::const_iterator> querySurroundingText() const = 0; | |
31 | + class InputMethodQueryEventHandler { | |
32 | + virtual std::pair<const StringPiece, StringPiece::const_iterator> querySurroundingText() const BOOST_NOEXCEPT = 0; | |
31 | 33 | friend class TextViewer; |
32 | 34 | }; |
33 | 35 |
@@ -256,8 +256,8 @@ | ||
256 | 256 | /// @{ |
257 | 257 | virtual void focusAboutToBeLost(widgetapi::event::Event& event); |
258 | 258 | virtual void focusGained(widgetapi::event::Event& event); |
259 | - virtual void handleInputMethodEvent(widgetapi::event::InputMethodEvent& event, const void* nativeEvent); | |
260 | - virtual void handleInputMethodQueryEvent(widgetapi::event::InputMethodQueryEvent& event, const void* nativeEvent); | |
259 | + virtual void handleInputMethodEvent(widgetapi::event::InputMethodEvent& event); | |
260 | + virtual void handleInputMethodQueryEvent(widgetapi::event::InputMethodQueryEvent& event); | |
261 | 261 | virtual void keyPressed(widgetapi::event::KeyInput& input); |
262 | 262 | virtual void keyReleased(widgetapi::event::KeyInput& input); |
263 | 263 | virtual void mouseDoubleClicked(widgetapi::event::MouseButtonInput& input); |
@@ -17,6 +17,24 @@ | ||
17 | 17 | namespace viewer { |
18 | 18 | namespace widgetapi { |
19 | 19 | namespace event { |
20 | + class InputMethodEventBase : public Event { | |
21 | + public: | |
22 | + /// Returns a pointer to the platform-native object. | |
23 | + const void* native() const BOOST_NOEXCEPT { | |
24 | + return native_; | |
25 | + } | |
26 | + | |
27 | + protected: | |
28 | + /** | |
29 | + * Protected constructor. | |
30 | + * @param native A pointer to the platform-native object | |
31 | + */ | |
32 | + InputMethodEventBase(const void* native) : native_(native) {} | |
33 | + | |
34 | + private: | |
35 | + const void* native_; | |
36 | + }; | |
37 | + | |
20 | 38 | /** |
21 | 39 | * Provides parameters for input method events. |
22 | 40 | * <table> |
@@ -28,7 +46,7 @@ | ||
28 | 46 | * </table> |
29 | 47 | * @see InputMethodQueryEvent |
30 | 48 | */ |
31 | - class InputMethodEvent : public Event { | |
49 | + class InputMethodEvent : public InputMethodEventBase { | |
32 | 50 | public: |
33 | 51 | /// Destructor. |
34 | 52 | virtual ~InputMethodEvent() BOOST_NOEXCEPT {} |
@@ -54,6 +72,9 @@ | ||
54 | 72 | */ |
55 | 73 | virtual boost::optional<NumericRange<Index>> replacementInlineRange() const BOOST_NOEXCEPT = 0; |
56 | 74 | /// @} |
75 | + | |
76 | + protected: | |
77 | + explicit InputMethodEvent(const void* native) BOOST_NOEXCEPT : InputMethodEventBase(native) {} | |
57 | 78 | }; |
58 | 79 | |
59 | 80 | /// Simple implementation of @c InputMethodEvent interface. |
@@ -70,48 +91,55 @@ | ||
70 | 91 | /// @{ |
71 | 92 | /** |
72 | 93 | * Creates a @c ConstantInputMethodEvent instance which means the composition canceled. |
94 | + * @param native A pointer to the platform-native object | |
73 | 95 | */ |
74 | - static ConstantInputMethodEvent createCanceledInstance() { | |
75 | - return ConstantInputMethodEvent(String(), boost::none, boost::none); | |
96 | + static ConstantInputMethodEvent createCanceledInstance(const void* native) { | |
97 | + return ConstantInputMethodEvent(native, String(), boost::none, boost::none); | |
76 | 98 | } |
77 | 99 | /** |
78 | 100 | * Creates a @c ConstantInputMethodEvent instance which means the composition changed. |
101 | + * @param native A pointer to the platform-native object | |
79 | 102 | * @param preeditString |
80 | 103 | * @param replacementInlineRange |
81 | 104 | */ |
82 | - static ConstantInputMethodEvent createChangedInstance(const String& preeditString, boost::optional<NumericRange<Index>> replacementInlineRange = boost::none) { | |
83 | - return ConstantInputMethodEvent(boost::none, preeditString, replacementInlineRange); | |
105 | + static ConstantInputMethodEvent createChangedInstance(const void* native, const String& preeditString, boost::optional<NumericRange<Index>> replacementInlineRange = boost::none) { | |
106 | + return ConstantInputMethodEvent(native, boost::none, preeditString, replacementInlineRange); | |
84 | 107 | } |
85 | 108 | /** |
86 | 109 | * Creates a @c ConstantInputMethodEvent instance which means the composition completed. |
110 | + * @param native A pointer to the platform-native object | |
87 | 111 | * @param commitString |
88 | 112 | * @param replacementInlineRange |
89 | 113 | */ |
90 | - static ConstantInputMethodEvent createCompletedInstance(const String& commitString, boost::optional<NumericRange<Index>> replacementInlineRange = boost::none) { | |
91 | - return ConstantInputMethodEvent(commitString, boost::none, replacementInlineRange); | |
114 | + static ConstantInputMethodEvent createCompletedInstance(const void* native, const String& commitString, boost::optional<NumericRange<Index>> replacementInlineRange = boost::none) { | |
115 | + return ConstantInputMethodEvent(native, commitString, boost::none, replacementInlineRange); | |
92 | 116 | } |
93 | 117 | /** |
94 | 118 | * Creates a @c ConstantInputMethodEvent which means the composition started. |
119 | + * @param native A pointer to the platform-native object | |
95 | 120 | */ |
96 | - static ConstantInputMethodEvent createStartedInstance() { | |
97 | - return ConstantInputMethodEvent(boost::none, String(), boost::none); | |
121 | + static ConstantInputMethodEvent createStartedInstance(const void* native) { | |
122 | + return ConstantInputMethodEvent(native, boost::none, String(), boost::none); | |
98 | 123 | } |
99 | 124 | /// @} |
100 | 125 | |
101 | 126 | private: |
102 | 127 | /** |
103 | 128 | * Creates @c ConstantInputMethodEvent instance. |
129 | + * @param native A pointer to the platform-native object | |
104 | 130 | * @param commitString The value returned by @c #commitString method |
105 | 131 | * @param preeditString The value returned by @c #preeditString method |
106 | 132 | * @param replacementInlineRange The value returned by @c #replacementInlineRange method |
107 | 133 | */ |
108 | - ConstantInputMethodEvent(boost::optional<String> commitString, boost::optional<String> preeditString, boost::optional<NumericRange<Index>> replacementInlineRange) | |
109 | - : commitString_(commitString), preeditString_(preeditString), replacementInlineRange_(replacementInlineRange_) {} | |
134 | + ConstantInputMethodEvent(const void* native, boost::optional<String> commitString, boost::optional<String> preeditString, boost::optional<NumericRange<Index>> replacementInlineRange) | |
135 | + : InputMethodEvent(native), commitString_(commitString), preeditString_(preeditString), replacementInlineRange_(replacementInlineRange_) {} | |
110 | 136 | const boost::optional<String> commitString_, preeditString_; |
111 | 137 | const boost::optional<NumericRange<Index>> replacementInlineRange_; |
112 | 138 | }; |
113 | 139 | |
114 | - class InputMethodQueryEvent : public Event { | |
140 | + class InputMethodQueryEvent : public InputMethodEventBase { | |
141 | + protected: | |
142 | + explicit InputMethodQueryEvent(const void* native) BOOST_NOEXCEPT : InputMethodEventBase(native) {} | |
115 | 143 | }; |
116 | 144 | } |
117 | 145 | } |
@@ -114,61 +114,6 @@ | ||
114 | 114 | return clipboardLocale_; |
115 | 115 | } |
116 | 116 | |
117 | - /// @see detail#InputMethodEventHandler#handleInputMethodEvent | |
118 | - void Caret::handleInputMethodEvent(widgetapi::event::InputMethodEvent& event, const void* nativeEvent) BOOST_NOEXCEPT { | |
119 | - if(document().isReadOnly()) | |
120 | - return; | |
121 | - const auto preeditString(event.preeditString()); | |
122 | - if(preeditString == boost::none) { // completed or canceled | |
123 | - context_.inputMethodCompositionActivated = false; | |
124 | - | |
125 | - const auto commitString(event.commitString()); | |
126 | - if(commitString != boost::none && boost::get(commitString).empty()) { // completed => commit | |
127 | - if(!context_.inputMethodComposingCharacter) | |
128 | - texteditor::commands::TextInputCommand(textArea().textViewer(), boost::get(commitString))(); | |
129 | - else { | |
130 | - auto& d = document(); | |
131 | - try { | |
132 | - d.insertUndoBoundary(); | |
133 | - d.replace( | |
134 | - kernel::Region( | |
135 | - insertionPosition(*this), | |
136 | - static_cast<kernel::DocumentCharacterIterator&>(++kernel::DocumentCharacterIterator(d, insertionPosition(*this))).tell()), | |
137 | - String(1, static_cast<Char>(static_cast<const MSG*>(nativeEvent)->wParam))); | |
138 | - d.insertUndoBoundary(); | |
139 | - } catch(const kernel::DocumentCantChangeException&) { | |
140 | - } | |
141 | - context_.inputMethodComposingCharacter = false; | |
142 | - } | |
143 | - } | |
144 | - | |
145 | - resetVisualization(); | |
146 | - } else if(boost::get(preeditString).empty()) { // started | |
147 | - context_.inputMethodCompositionActivated = true; | |
148 | - adjustInputMethodCompositionWindow(); | |
149 | - utils::closeCompletionProposalsPopup(textArea().textViewer()); | |
150 | - } else { // changed | |
151 | - auto& nativeMessage = *static_cast<const MSG*>(nativeEvent); | |
152 | - if((nativeMessage.lParam & CS_INSERTCHAR) != 0) { | |
153 | - const auto p(insertionPosition(*this)); // position before motion | |
154 | - try { | |
155 | - if(context_.inputMethodComposingCharacter) | |
156 | - document().replace( | |
157 | - kernel::Region( | |
158 | - p, | |
159 | - static_cast<kernel::DocumentCharacterIterator&>(++kernel::DocumentCharacterIterator(document(), p)).tell()), | |
160 | - String(1, static_cast<Char>(nativeMessage.wParam))); | |
161 | - else | |
162 | - kernel::insert(document(), p, String(1, static_cast<Char>(nativeMessage.wParam))); | |
163 | - context_.inputMethodComposingCharacter = true; | |
164 | - if((nativeMessage.lParam & CS_NOMOVECARET) != 0) | |
165 | - moveTo(TextHit::leading(p)); | |
166 | - } catch(...) { | |
167 | - } | |
168 | - event.consume(); | |
169 | - resetVisualization(); | |
170 | - } | |
171 | - } | |
172 | 117 | #if 0 |
173 | 118 | switch(message) { |
174 | 119 | case WM_IME_NOTIFY: |
@@ -182,64 +127,6 @@ | ||
182 | 127 | break; |
183 | 128 | } |
184 | 129 | #endif |
185 | - } | |
186 | - | |
187 | - /// Handles Win32 @c WM_IME_COMPOSITION window message. | |
188 | - void Caret::onImeComposition(WPARAM wp, LPARAM lp, bool& consumed) { | |
189 | - if(document().isReadOnly()) | |
190 | - return; | |
191 | - else if(/*event.lParam == 0 ||*/ win32::boole(lp & GCS_RESULTSTR)) { // completed | |
192 | - auto imc(inputMethod(textArea().textViewer())); | |
193 | - if(imc.get() != nullptr) { | |
194 | - if(const Index len = ::ImmGetCompositionStringW(imc.get(), GCS_RESULTSTR, nullptr, 0) / sizeof(WCHAR)) { | |
195 | - // this was not canceled | |
196 | - const std::unique_ptr<Char[]> text(new Char[len + 1]); | |
197 | - ::ImmGetCompositionStringW(imc.get(), GCS_RESULTSTR, text.get(), static_cast<DWORD>(len * sizeof(WCHAR))); | |
198 | - text[len] = 0; | |
199 | - if(!context_.inputMethodComposingCharacter) | |
200 | - texteditor::commands::TextInputCommand(textArea().textViewer(), text.get())(); | |
201 | - else { | |
202 | - auto& doc = document(); | |
203 | - try { | |
204 | - doc.insertUndoBoundary(); | |
205 | - doc.replace( | |
206 | - kernel::Region( | |
207 | - insertionPosition(*this), | |
208 | - static_cast<kernel::DocumentCharacterIterator&>(++kernel::DocumentCharacterIterator(doc, insertionPosition(*this))).tell()), | |
209 | - String(1, static_cast<Char>(wp))); | |
210 | - doc.insertUndoBoundary(); | |
211 | - } catch(const kernel::DocumentCantChangeException&) { | |
212 | - } | |
213 | - context_.inputMethodComposingCharacter = false; | |
214 | - resetVisualization(); | |
215 | - } | |
216 | - } | |
217 | -// adjustInputMethodCompositionWindow(); | |
218 | - consumed = true; // prevent to be send WM_CHARs | |
219 | - } | |
220 | - } | |
221 | - else if(win32::boole(GCS_COMPSTR & lp)) { | |
222 | - if(win32::boole(lp & CS_INSERTCHAR)) { | |
223 | - const auto p(insertionPosition(*this)); // position before motion | |
224 | - try { | |
225 | - if(context_.inputMethodComposingCharacter) | |
226 | - document().replace( | |
227 | - kernel::Region( | |
228 | - p, | |
229 | - static_cast<kernel::DocumentCharacterIterator&>(++kernel::DocumentCharacterIterator(document(), p)).tell()), | |
230 | - String(1, static_cast<Char>(wp))); | |
231 | - else | |
232 | - kernel::insert(document(), p, String(1, static_cast<Char>(wp))); | |
233 | - context_.inputMethodComposingCharacter = true; | |
234 | - if(win32::boole(lp & CS_NOMOVECARET)) | |
235 | - moveTo(TextHit::leading(p)); | |
236 | - } catch(...) { | |
237 | - } | |
238 | - consumed = true; | |
239 | - resetVisualization(); | |
240 | - } | |
241 | - } | |
242 | - } | |
243 | 130 | |
244 | 131 | /// Handles Win32 @c WM_IME_REQUEST window message. |
245 | 132 | LRESULT Caret::onImeRequest(WPARAM command, LPARAM lp, bool& consumed) { |
@@ -367,6 +254,31 @@ | ||
367 | 254 | document().insertUndoBoundary(); |
368 | 255 | } |
369 | 256 | |
257 | + void Caret::preeditChanged(widgetapi::event::InputMethodEvent& event) BOOST_NOEXCEPT { | |
258 | + if(!document().isReadOnly()) { | |
259 | + auto& nativeMessage = *static_cast<const MSG*>(event.native()); | |
260 | + if((nativeMessage.lParam & CS_INSERTCHAR) != 0) { | |
261 | + const auto p(insertionPosition(*this)); // position before motion | |
262 | + try { | |
263 | + if(context_.inputMethodComposingCharacter) | |
264 | + document().replace( | |
265 | + kernel::Region( | |
266 | + p, | |
267 | + static_cast<kernel::DocumentCharacterIterator&>(++kernel::DocumentCharacterIterator(document(), p)).tell()), | |
268 | + String(1, static_cast<Char>(nativeMessage.wParam))); | |
269 | + else | |
270 | + kernel::insert(document(), p, String(1, static_cast<Char>(nativeMessage.wParam))); | |
271 | + context_.inputMethodComposingCharacter = true; | |
272 | + if((nativeMessage.lParam & CS_NOMOVECARET) != 0) | |
273 | + moveTo(TextHit::leading(p)); | |
274 | + } catch(...) { | |
275 | + } | |
276 | + event.consume(); | |
277 | + resetVisualization(); | |
278 | + } | |
279 | + } | |
280 | + } | |
281 | + | |
370 | 282 | /** |
371 | 283 | * Sets the locale used to convert non-Unicode data in the clipboard. |
372 | 284 | * @param newLocale The locale identifier |
@@ -15,6 +15,7 @@ | ||
15 | 15 | #include <ascension/graphics/font/line-layout-vector.hpp> |
16 | 16 | #include <ascension/graphics/font/text-viewport.hpp> |
17 | 17 | #include <ascension/kernel/document.hpp> |
18 | +#include <ascension/kernel/document-character-iterator.hpp> | |
18 | 19 | #include <ascension/text-editor/commands/inputs.hpp> |
19 | 20 | #include <ascension/text-editor/input-sequence-checker.hpp> |
20 | 21 | #include <ascension/text-editor/session.hpp> |
@@ -258,10 +259,28 @@ | ||
258 | 259 | moveTo(hit()); |
259 | 260 | } |
260 | 261 | |
261 | - /// @see detail#InputMethodEvent#commitInputString | |
262 | - void Caret::commitInputString(const StringPiece& text) { | |
263 | -// if(!context_.inputMethodComposingCharacter) | |
264 | - texteditor::commands::TextInputCommand(textArea().textViewer(), text.to_string())(); | |
262 | + /// @see detail#InputMethodEventHandler#commitString | |
263 | + void Caret::commitString(widgetapi::event::InputMethodEvent& event) BOOST_NOEXCEPT { | |
264 | + const auto commitString(event.commitString()); | |
265 | + assert(commitString != boost::none); | |
266 | + if(!context_.inputMethodComposingCharacter) | |
267 | + texteditor::commands::TextInputCommand(textArea().textViewer(), boost::get(commitString))(); | |
268 | + else { | |
269 | +#if ASCENSION_SELECTS_WINDOW_SYSTEM(WIN32) | |
270 | + auto& d = document(); | |
271 | + try { | |
272 | + d.insertUndoBoundary(); | |
273 | + d.replace( | |
274 | + kernel::Region( | |
275 | + insertionPosition(*this), | |
276 | + static_cast<kernel::DocumentCharacterIterator&>(++kernel::DocumentCharacterIterator(d, insertionPosition(*this))).tell()), | |
277 | + String(1, static_cast<Char>(static_cast<const MSG*>(event.native())->wParam))); | |
278 | + d.insertUndoBoundary(); | |
279 | + } catch(const kernel::DocumentCantChangeException&) { | |
280 | + } | |
281 | +#endif | |
282 | + context_.inputMethodComposingCharacter = false; | |
283 | + } | |
265 | 284 | } |
266 | 285 | |
267 | 286 | /// @see kernel#DocumentListener#documentAboutToBeChanged |
@@ -613,26 +632,21 @@ | ||
613 | 632 | } |
614 | 633 | } |
615 | 634 | |
616 | - /// @see detail#InputMethodEvent#preeditChanged | |
617 | - void Caret::preeditChanged() { | |
618 | - // TODO: Not implemented. | |
619 | - } | |
620 | - | |
621 | 635 | /// @see detail#InputMethodEvent#preeditEnded |
622 | - void Caret::preeditEnded() { | |
636 | + void Caret::preeditEnded() BOOST_NOEXCEPT { | |
623 | 637 | context_.inputMethodCompositionActivated = false; |
624 | 638 | updateVisualAttributes(); |
625 | 639 | } |
626 | 640 | |
627 | - /// @see detail#InputMethodEvent#preeditStarted | |
628 | - void Caret::preeditStarted() { | |
641 | + /// @see detail#InputMethodEventHandler#preeditStarted | |
642 | + void Caret::preeditStarted() BOOST_NOEXCEPT { | |
629 | 643 | context_.inputMethodCompositionActivated = true; |
630 | 644 | adjustInputMethodCompositionWindow(); |
631 | 645 | utils::closeCompletionProposalsPopup(textArea().textViewer()); |
632 | 646 | } |
633 | 647 | |
634 | 648 | // @see detail#InputMethodQueryEvent#querySurroundingText |
635 | - std::pair<const StringPiece, StringPiece::const_iterator> Caret::querySurroundingText() const { | |
649 | + std::pair<const StringPiece, StringPiece::const_iterator> Caret::querySurroundingText() const BOOST_NOEXCEPT { | |
636 | 650 | const StringPiece lineString(document().lineString(kernel::line(hit().characterIndex()))); |
637 | 651 | StringPiece::const_iterator position(lineString.cbegin()); |
638 | 652 | if(boost::size(selectedRegion().lines()) == 1) |
@@ -140,21 +140,31 @@ | ||
140 | 140 | /** |
141 | 141 | * Invoked when received input method composition events. |
142 | 142 | * @param event The event |
143 | - * @param nativeEvent The platform-native event | |
144 | 143 | */ |
145 | - void TextViewer::handleInputMethodEvent(widgetapi::event::InputMethodEvent& event, const void* nativeEvent) { | |
144 | + void TextViewer::handleInputMethodEvent(widgetapi::event::InputMethodEvent& event) { | |
146 | 145 | if(auto ta = textArea()) { |
147 | - if(auto caret = ta->caret()) | |
148 | - static_cast<detail::InputMethodEventHandler*>(caret.get())->handleInputMethodEvent(event, nativeEvent); | |
146 | + if(auto caret = ta->caret()) { | |
147 | + auto& handler = *static_cast<detail::InputMethodEventHandler*>(caret.get()); | |
148 | + const auto preeditString(event.preeditString()); | |
149 | + if(preeditString == boost::none) { // completed or canceled | |
150 | + const auto commitString(event.commitString()); | |
151 | + if(commitString != boost::none && boost::get(commitString).empty()) // completed => commit | |
152 | + handler.commitString(event); | |
153 | + handler.preeditEnded(); | |
154 | + } else if(boost::get(preeditString).empty()) { // started | |
155 | + event.consume(); | |
156 | + handler.preeditStarted(); | |
157 | + } else // changed | |
158 | + handler.preeditChanged(event); | |
159 | + } | |
149 | 160 | } |
150 | 161 | } |
151 | 162 | |
152 | 163 | /** |
153 | 164 | * Invoked when received input method query events. |
154 | 165 | * @param event The event |
155 | - * @param nativeEvent The platform-native event | |
156 | 166 | */ |
157 | - void TextViewer::handleInputMethodQueryEvent(widgetapi::event::InputMethodQueryEvent& event, const void* nativeEvent) { | |
167 | + void TextViewer::handleInputMethodQueryEvent(widgetapi::event::InputMethodQueryEvent& event) { | |
158 | 168 | if(auto ta = textArea()) { |
159 | 169 | if(auto caret = ta->caret()) |
160 | 170 | static_cast<detail::InputMethodEventHandler*>(caret.get())->handleInputMethodQueryEvent(event, nativeEvent); |
@@ -1097,8 +1097,8 @@ | ||
1097 | 1097 | std::unique_ptr<WCHAR[]> buffer(new WCHAR[length]); |
1098 | 1098 | nbytes = ::ImmGetCompositionStringW(im.get(), GCS_RESULTSTR, buffer.get(), nbytes); |
1099 | 1099 | if(nbytes > 0) { |
1100 | - auto e(widgetapi::event::ConstantInputMethodEvent::createCompletedInstance(String(win32::wideString<const Char>(buffer.get())))); | |
1101 | - handleInputMethodEvent(e, &native); | |
1100 | + auto e(widgetapi::event::ConstantInputMethodEvent::createCompletedInstance(&native, String(win32::wideString<const Char>(buffer.get())))); | |
1101 | + handleInputMethodEvent(e); | |
1102 | 1102 | if(consumed = e.isConsumed()) |
1103 | 1103 | return 0L; // block WM_CHARs |
1104 | 1104 | } |
@@ -1111,7 +1111,7 @@ | ||
1111 | 1111 | case WM_IME_ENDCOMPOSITION: { |
1112 | 1112 | MSG native; |
1113 | 1113 | nativeMessage(*this, message, wp, lp, native); |
1114 | - handleInputMethodEvent(widgetapi::event::ConstantInputMethodEvent::createCanceledInstance(), &native); | |
1114 | + handleInputMethodEvent(widgetapi::event::ConstantInputMethodEvent::createCanceledInstance(&native)); | |
1115 | 1115 | break; |
1116 | 1116 | } |
1117 | 1117 | case WM_IME_REQUEST: |
@@ -1119,7 +1119,7 @@ | ||
1119 | 1119 | case WM_IME_STARTCOMPOSITION: { |
1120 | 1120 | MSG native; |
1121 | 1121 | nativeMessage(*this, message, wp, lp, native); |
1122 | - handleInputMethodEvent(widgetapi::event::ConstantInputMethodEvent::createStartedInstance(), &native); | |
1122 | + handleInputMethodEvent(widgetapi::event::ConstantInputMethodEvent::createStartedInstance(&native)); | |
1123 | 1123 | break; |
1124 | 1124 | } |
1125 | 1125 | case WM_KEYDOWN: |