Merge branch 'JannLee-hotfix-1.7.2' into hotfix-1.7.2
This commit is contained in:
commit
a5a7a36b2f
@ -85,6 +85,7 @@ namespace nana
|
||||
virtual void mouse_dropfiles(graph_reference, const arg_dropfiles&);
|
||||
|
||||
virtual void focus(graph_reference, const arg_focus&);
|
||||
virtual void key_ime(graph_reference, const arg_ime&);
|
||||
virtual void key_press(graph_reference, const arg_keyboard&);
|
||||
virtual void key_char(graph_reference, const arg_keyboard&);
|
||||
virtual void key_release(graph_reference, const arg_keyboard&);
|
||||
@ -140,6 +141,7 @@ namespace nana
|
||||
void resized(const arg_resized&, const bool);
|
||||
void move(const arg_move&, const bool);
|
||||
void focus(const arg_focus&, const bool);
|
||||
void key_ime(const arg_ime& arg, const bool bForce__EmitInternal);
|
||||
void key_press(const arg_keyboard&, const bool);
|
||||
void key_char(const arg_keyboard&, const bool);
|
||||
void key_release(const arg_keyboard&, const bool);
|
||||
|
@ -34,6 +34,7 @@ namespace nana
|
||||
unload, ///< A form is closed by clicking the X button, only works for root widget.
|
||||
destroy, ///< A widget is about to be destroyed.
|
||||
focus, ///< A widget's focus is changed.
|
||||
key_ime,
|
||||
key_press, ///< A keyboard is pressed on a focus widget.
|
||||
key_char, ///< The focus widget received a character.
|
||||
key_release, ///< A keyboard is released on a focus widget.
|
||||
|
@ -466,6 +466,19 @@ namespace nana
|
||||
reason focus_reason; ///< determines how the widget receives keyboard focus, it is ignored when 'getting' is equal to false
|
||||
};
|
||||
|
||||
struct arg_ime: public event_arg
|
||||
{
|
||||
enum class reason
|
||||
{
|
||||
composition,
|
||||
result
|
||||
};
|
||||
|
||||
::nana::window window_handle; ///< A handle to the event window
|
||||
reason ime_reason;
|
||||
std::wstring composition_string;
|
||||
};
|
||||
|
||||
struct arg_keyboard : public event_arg
|
||||
{
|
||||
event_code evt_code; ///< it is event_code::key_press in current event
|
||||
|
@ -65,6 +65,7 @@ namespace nana
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_wheel(graph_reference, const arg_wheel&) override;
|
||||
void key_ime(graph_reference, const arg_ime&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
private:
|
||||
|
@ -98,6 +98,7 @@ namespace nana{ namespace widgets
|
||||
|
||||
void set_accept(std::function<bool(char_type)>);
|
||||
void set_accept(accepts);
|
||||
bool respond_ime(const arg_ime& arg);
|
||||
bool respond_char(const arg_keyboard& arg);
|
||||
bool respond_key(const arg_keyboard& arg);
|
||||
|
||||
@ -328,6 +329,8 @@ namespace nana{ namespace widgets
|
||||
nana::upoint caret; //position of caret by text, it specifies the position of a new character
|
||||
nana::upoint shift_begin_caret;
|
||||
}points_;
|
||||
|
||||
size_t composition_size_ { 0 };
|
||||
};
|
||||
}//end namespace skeletons
|
||||
}//end namespace widgets
|
||||
|
@ -66,6 +66,7 @@ namespace nana
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse& arg) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void key_ime(graph_reference, const arg_ime& arg) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
void resized(graph_reference, const arg_resized&) override;
|
||||
|
@ -83,6 +83,7 @@ namespace nana
|
||||
void mouse_enter(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void dbl_click(graph_reference, const arg_mouse&) override;
|
||||
void key_ime(graph_reference, const arg_ime&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&)override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
void mouse_wheel(graph_reference, const arg_wheel&) override;
|
||||
|
@ -77,6 +77,9 @@ namespace detail
|
||||
|
||||
typedef BOOL (__stdcall* imm_set_composition_window_type)(HIMC, LPCOMPOSITIONFORM);
|
||||
imm_set_composition_window_type imm_set_composition_window;
|
||||
|
||||
typedef LONG(__stdcall* imm_get_composition_string_type)(HIMC, DWORD, LPVOID, DWORD);
|
||||
imm_get_composition_string_type imm_get_composition_string;
|
||||
}
|
||||
#pragma pack(1)
|
||||
//Decoder of WPARAM and LPARAM
|
||||
@ -210,6 +213,9 @@ namespace detail
|
||||
|
||||
restrict::imm_set_composition_window = reinterpret_cast<restrict::imm_set_composition_window_type>(
|
||||
::GetProcAddress(imm32, "ImmSetCompositionWindow"));
|
||||
|
||||
restrict::imm_get_composition_string = reinterpret_cast<restrict::imm_get_composition_string_type>(
|
||||
::GetProcAddress(imm32, "ImmGetCompositionStringW"));
|
||||
}
|
||||
|
||||
bedrock::~bedrock()
|
||||
@ -639,6 +645,8 @@ namespace detail
|
||||
case WM_NCRBUTTONDOWN:
|
||||
case WM_NCMBUTTONDOWN:
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
case WM_IME_COMPOSITION:
|
||||
case WM_IME_CHAR:
|
||||
case WM_DROPFILES:
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_MOUSEWHEEL: //The WM_MOUSELAST may not include the WM_MOUSEWHEEL/WM_MOUSEHWHEEL when the version of SDK is low.
|
||||
@ -786,25 +794,67 @@ namespace detail
|
||||
}
|
||||
break;
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
if (msgwnd->other.attribute.root->ime_enabled)
|
||||
break;
|
||||
case WM_IME_COMPOSITION:
|
||||
if (lParam & (GCS_COMPSTR | GCS_RESULTSTR))
|
||||
{
|
||||
auto native_font = msgwnd->drawer.graphics.typeface().handle();
|
||||
LOGFONTW logfont;
|
||||
::GetObjectW(reinterpret_cast<HFONT>(native_font), sizeof logfont, &logfont);
|
||||
msgwnd = brock.focus();
|
||||
if (msgwnd && msgwnd->flags.enabled)
|
||||
{
|
||||
auto & wd_manager = brock.wd_manager();
|
||||
auto composition_index = static_cast<DWORD>(lParam & (GCS_COMPSTR | GCS_RESULTSTR));
|
||||
|
||||
HIMC imc = restrict::imm_get_context(root_window);
|
||||
restrict::imm_set_composition_font(imc, &logfont);
|
||||
arg_ime arg;
|
||||
arg.window_handle = msgwnd;
|
||||
if (lParam & GCS_COMPSTR)
|
||||
{
|
||||
arg.ime_reason = arg_ime::reason::composition;
|
||||
}
|
||||
if (lParam & GCS_RESULTSTR)
|
||||
{
|
||||
arg.ime_reason = arg_ime::reason::result;
|
||||
}
|
||||
|
||||
POINT pos;
|
||||
::GetCaretPos(&pos);
|
||||
HIMC imc = restrict::imm_get_context(root_window);
|
||||
auto size = restrict::imm_get_composition_string(imc, composition_index, nullptr, 0);
|
||||
if (size > 0)
|
||||
{
|
||||
wchar_t * buffer = new wchar_t[100 / sizeof(wchar_t) + 1];
|
||||
size = restrict::imm_get_composition_string(imc, composition_index, buffer, size + sizeof(wchar_t));
|
||||
buffer[size / sizeof(wchar_t)] = '\0';
|
||||
arg.composition_string = std::move(buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
restrict::imm_release_context(root_window, imc);
|
||||
|
||||
COMPOSITIONFORM cf = { CFS_POINT };
|
||||
cf.ptCurrentPos = pos;
|
||||
restrict::imm_set_composition_window(imc, &cf);
|
||||
restrict::imm_release_context(root_window, imc);
|
||||
if (wd_manager.available(msgwnd))
|
||||
draw_invoker(&drawer::key_ime, msgwnd, arg, &context);
|
||||
|
||||
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||
}
|
||||
}
|
||||
def_window_proc = true;
|
||||
break;
|
||||
case WM_IME_CHAR:
|
||||
msgwnd = brock.focus();
|
||||
if (msgwnd && msgwnd->flags.enabled)
|
||||
{
|
||||
auto & wd_manager = brock.wd_manager();
|
||||
|
||||
arg_keyboard arg;
|
||||
arg.evt_code = event_code::key_char;
|
||||
arg.window_handle = msgwnd;
|
||||
arg.key = static_cast<wchar_t>(wParam);
|
||||
brock.get_key_state(arg);
|
||||
arg.ignore = false;
|
||||
|
||||
msgwnd->annex.events_ptr->key_char.emit(arg, msgwnd);
|
||||
if ((false == arg.ignore) && wd_manager.available(msgwnd))
|
||||
draw_invoker(&drawer::key_char, msgwnd, arg, &context);
|
||||
|
||||
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||
}
|
||||
break;
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
bool take_over = false;
|
||||
|
@ -96,6 +96,11 @@ namespace nana
|
||||
overridden_ &= ~(1 << static_cast<int>(event_code::focus));
|
||||
}
|
||||
|
||||
void drawer_trigger::key_ime(graph_reference, const arg_ime&)
|
||||
{
|
||||
overridden_ &= ~(1 << static_cast<int>(event_code::key_ime));
|
||||
}
|
||||
|
||||
void drawer_trigger::key_press(graph_reference, const arg_keyboard&)
|
||||
{
|
||||
overridden_ &= ~(1 << static_cast<int>(event_code::key_press));
|
||||
@ -318,6 +323,11 @@ namespace nana
|
||||
_m_emit(event_code::focus, arg, &drawer_trigger::focus, bForce__EmitInternal);
|
||||
}
|
||||
|
||||
void drawer::key_ime(const arg_ime& arg, const bool bForce__EmitInternal)
|
||||
{
|
||||
_m_emit(event_code::key_ime, arg, &drawer_trigger::key_ime, bForce__EmitInternal);
|
||||
}
|
||||
|
||||
void drawer::key_press(const arg_keyboard& arg, const bool bForce__EmitInternal)
|
||||
{
|
||||
_m_emit(event_code::key_press, arg, &drawer_trigger::key_press, bForce__EmitInternal);
|
||||
|
@ -773,6 +773,13 @@ namespace nana
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void trigger::key_ime(graph_reference, const arg_ime& arg)
|
||||
{
|
||||
drawer_->editor()->respond_ime(arg);
|
||||
if (drawer_->editor()->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void trigger::key_char(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
drawer_->editor()->respond_char(arg);
|
||||
|
@ -1163,6 +1163,43 @@ namespace nana {
|
||||
impl_->capacities.acceptive = acceptive;
|
||||
}
|
||||
|
||||
bool text_editor::respond_ime(const arg_ime& arg)
|
||||
{
|
||||
if (!API::window_enabled(window_))
|
||||
return false;
|
||||
|
||||
if (select_.a != select_.b)
|
||||
{
|
||||
points_.caret = _m_erase_select(false);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < composition_size_; ++i)
|
||||
{
|
||||
backspace(false, false);
|
||||
}
|
||||
|
||||
if (arg.ime_reason == arg_ime::reason::composition)
|
||||
{
|
||||
composition_size_ = arg.composition_string.length();
|
||||
points_.caret = _m_put(std::move(arg.composition_string), false);
|
||||
|
||||
_m_reset_content_size(true);
|
||||
textbase().text_changed();
|
||||
|
||||
if (this->_m_adjust_view())
|
||||
impl_->cview->sync(false);
|
||||
|
||||
reset_caret();
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
else
|
||||
{
|
||||
composition_size_ = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool text_editor::respond_char(const arg_keyboard& arg) //key is a character of ASCII code
|
||||
{
|
||||
if (!API::window_enabled(window_))
|
||||
|
@ -621,6 +621,13 @@ namespace nana
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void drawer::key_ime(graph_reference, const arg_ime& arg)
|
||||
{
|
||||
impl_->editor()->respond_ime(arg);
|
||||
if (impl_->editor()->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void drawer::key_press(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
if (impl_->editor()->respond_key(arg))
|
||||
|
@ -152,6 +152,13 @@ namespace drawerbase {
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void drawer::key_ime(graph_reference, const arg_ime& arg)
|
||||
{
|
||||
editor_->respond_ime(arg);
|
||||
if (editor_->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void drawer::key_press(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
editor_->respond_key(arg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user