From 2974fe213721459f341201977a0d0b2cc2a086fc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 1 Sep 2017 22:57:12 +0800 Subject: [PATCH] add event filter contributed by A2Razor --- include/nana/gui/detail/bedrock.hpp | 5 +- include/nana/gui/detail/drawer.hpp | 75 ++++++++--- include/nana/gui/programming_interface.hpp | 11 ++ include/nana/gui/widgets/widget.hpp | 35 ++++- source/gui/detail/bedrock_pi.cpp | 46 ++++--- source/gui/detail/bedrock_posix.cpp | 8 +- source/gui/detail/bedrock_windows.cpp | 8 +- source/gui/detail/drawer.cpp | 148 ++++++++++++++++----- source/gui/programming_interface.cpp | 7 +- 9 files changed, 254 insertions(+), 89 deletions(-) diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 5462857d..0db691b3 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -91,9 +91,10 @@ namespace detail void manage_form_loader(core_window_t*, bool insert_or_remove); public: - bool emit(event_code, core_window_t*, const event_arg&, bool ask_update, thread_context*); + // if 'bForce__EmitInternal', then ONLY internal (widget's) events are processed (even through explicit filtering) + bool emit(event_code, core_window_t*, const event_arg&, bool ask_update, thread_context*, const bool bForce__EmitInternal = false); private: - void _m_emit_core(event_code, core_window_t*, bool draw_only, const event_arg&); + void _m_emit_core(event_code, core_window_t*, bool draw_only, const event_arg&, const bool bForce__EmitInternal); void _m_event_filter(event_code, core_window_t*, thread_context*); private: static bedrock bedrock_object; diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index 5a202438..63cea67f 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -17,6 +17,7 @@ #include "general_events.hpp" #include #include +#include namespace nana { @@ -27,6 +28,25 @@ namespace nana class drawer; } + class drawer_trigger; + class event_filter_status + { + public: + event_filter_status(); + event_filter_status(const event_filter_status& rOther); + event_filter_status(const unsigned evt_disabled_); + const event_filter_status& operator=(const event_filter_status& rOther); + const event_filter_status& operator=(const unsigned evt_disabled_); + + bool operator[](const nana::event_code evt_code) const; + bool operator==(const event_filter_status& rOther) const; + bool operator!=(const event_filter_status& rOther) const; + + private: + unsigned evt_disabled_; + friend class drawer_trigger; + }; + class drawer_trigger { friend class detail::drawer; @@ -70,11 +90,19 @@ namespace nana virtual void key_release(graph_reference, const arg_keyboard&); virtual void shortkey(graph_reference, const arg_keyboard&); + void filter_event(const event_code evt_code, const bool bDisabled); + void filter_event(const std::vector evt_codes, const bool bDisabled); + void filter_event(const event_filter_status& evt_all_states); + bool filter_event(const event_code evt_code); + event_filter_status filter_event(); + void clear_filter(); + private: void _m_reset_overrided(); bool _m_overrided(event_code) const; private: unsigned overrided_{ 0xFFFFFFFF }; + unsigned evt_disabled_{ 0 }; // bit set if event is filtered }; namespace detail @@ -99,23 +127,23 @@ namespace nana void bind(basic_window*); void typeface_changed(); - void click(const arg_click&); - void dbl_click(const arg_mouse&); - void mouse_enter(const arg_mouse&); - void mouse_move(const arg_mouse&); - void mouse_leave(const arg_mouse&); - void mouse_down(const arg_mouse&); - void mouse_up(const arg_mouse&); - void mouse_wheel(const arg_wheel&); - void mouse_dropfiles(const arg_dropfiles&); - void resizing(const arg_resizing&); - void resized(const arg_resized&); - void move(const arg_move&); - void focus(const arg_focus&); - void key_press(const arg_keyboard&); - void key_char(const arg_keyboard&); - void key_release(const arg_keyboard&); - void shortkey(const arg_keyboard&); + void click(const arg_click&, const bool); + void dbl_click(const arg_mouse&, const bool); + void mouse_enter(const arg_mouse&, const bool); + void mouse_move(const arg_mouse&, const bool); + void mouse_leave(const arg_mouse&, const bool); + void mouse_down(const arg_mouse&, const bool); + void mouse_up(const arg_mouse&, const bool); + void mouse_wheel(const arg_wheel&, const bool); + void mouse_dropfiles(const arg_dropfiles&, const bool); + void resizing(const arg_resizing&, const bool); + void resized(const arg_resized&, const bool); + void move(const arg_move&, const bool); + void focus(const arg_focus&, const bool); + void key_press(const arg_keyboard&, const bool); + void key_char(const arg_keyboard&, const bool); + void key_release(const arg_keyboard&, const bool); + void shortkey(const arg_keyboard&, const bool); void map(window, bool forced, const rectangle* update_area = nullptr); //Copy the root buffer to screen void refresh(); drawer_trigger* realizer() const; @@ -130,7 +158,7 @@ namespace nana method_state& _m_mth_state(int pos); template - void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr) + void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr, const bool bForce__EmitInternal) { const int pos = static_cast(evt_code); @@ -139,17 +167,22 @@ namespace nana if (realizer && (method_state::not_overrided != mth_state)) { + const bool bFiltered = !bForce__EmitInternal && realizer->filter_event(evt_code); if (method_state::pending == mth_state) { - (realizer->*mfptr)(graphics, arg); - + if (!bFiltered) + (realizer->*mfptr)(graphics, arg); + //Check realizer, when the window is closed in that event handler, the drawer will be //detached and realizer will be a nullptr if (realizer) mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); } else - (realizer->*mfptr)(graphics, arg); + { + if (!bFiltered) + (realizer->*mfptr)(graphics, arg); + } _m_effect_bground_subsequent(); } diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 4d1931dc..8c0d85fe 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -120,8 +120,13 @@ namespace API namespace detail { general_events* get_general_events(window); + + // emits both internal and external event (internal event can be filtered) bool emit_event(event_code, window, const ::nana::event_arg&); + // explicitly emits internal event (internal event not to be filtered) + bool emit_internal_event(event_code, window, const ::nana::event_arg&); + class enum_widgets_function_base { public: @@ -255,6 +260,12 @@ namespace API return detail::emit_event(evt_code, wd, arg); } + template::value>::type* = nullptr> + bool emit_internal_event(event_code evt_code, window wd, const EventArg& arg) + { + return detail::emit_internal_event(evt_code, wd, arg); + } + void umake_event(event_handle); template diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 922fbe3b..0ee37703 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -206,7 +206,7 @@ namespace nana API::dev::attach_drawer(*this, trigger_); if(visible) API::show_window(handle_, true); - + this->_m_complete_creation(); } return (this->empty() == false); @@ -227,6 +227,39 @@ namespace nana { return *scheme_; } + + // disables or re-enables internal handling of event within base-widget + void filter_event(const event_code evt_code, const bool bDisabled) + { + trigger_.filter_event(evt_code, bDisabled); + } + + void filter_event(const std::vector evt_codes, const bool bDisabled) + { + trigger_.filter_event(evt_codes, bDisabled); + } + + void filter_event(const event_filter_status& evt_all_states) + { + trigger_.filter_event(evt_all_states); + } + + void clear_filter() + { + trigger_.clear_filter(); + } + + // reads status of if event is filtered + bool filter_event(const event_code evt_code) + { + return trigger_.filter_event(evt_code); + } + + event_filter_status filter_event() + { + return trigger_.filter_event(); + } + protected: DrawerTrigger& get_drawer_trigger() { diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 294c56f9..ec27ac07 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -379,11 +379,13 @@ namespace nana return pi_data_->scheme; } - void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg) + void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg, const bool bForce__EmitInternal) { auto retain = wd->annex.events_ptr; auto evts_ptr = retain.get(); + // if 'bForce__EmitInternal', omit user defined events + const bool bProcess__External_event = !draw_only && !bForce__EmitInternal; switch (evt_code) { case event_code::click: @@ -394,9 +396,9 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - wd->drawer.click(*arg); + wd->drawer.click(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evts_ptr->click.emit(*arg, reinterpret_cast(wd)); } } @@ -412,7 +414,7 @@ namespace nana if (nullptr == arg) return; - void(::nana::detail::drawer::*drawer_event_fn)(const arg_mouse&); + void(::nana::detail::drawer::*drawer_event_fn)(const arg_mouse&, const bool); ::nana::basic_event* evt_addr; switch (evt_code) @@ -448,10 +450,10 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - (wd->drawer.*drawer_event_fn)(*arg); + (wd->drawer.*drawer_event_fn)(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evt_addr->emit(*arg, reinterpret_cast(wd)); break; } @@ -463,10 +465,10 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - wd->drawer.mouse_wheel(*arg); + wd->drawer.mouse_wheel(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evts_ptr->mouse_wheel.emit(*arg, reinterpret_cast(wd)); } break; @@ -480,7 +482,7 @@ namespace nana if (nullptr == arg) return; - void(::nana::detail::drawer::*drawer_event_fn)(const arg_keyboard&); + void(::nana::detail::drawer::*drawer_event_fn)(const arg_keyboard&, const bool); ::nana::basic_event* evt_addr; switch (evt_code) @@ -507,15 +509,15 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - (wd->drawer.*drawer_event_fn)(*arg); + (wd->drawer.*drawer_event_fn)(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evt_addr->emit(*arg, reinterpret_cast(wd)); break; } case event_code::expose: - if (!draw_only) + if (bProcess__External_event) { auto arg = dynamic_cast(&event_arg); if (arg) @@ -530,9 +532,9 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - wd->drawer.focus(*arg); + wd->drawer.focus(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evts_ptr->focus.emit(*arg, reinterpret_cast(wd)); } break; @@ -545,9 +547,9 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - wd->drawer.move(*arg); + wd->drawer.move(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evts_ptr->move.emit(*arg, reinterpret_cast(wd)); } break; @@ -560,9 +562,9 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - wd->drawer.resizing(*arg); + wd->drawer.resizing(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evts_ptr->resizing.emit(*arg, reinterpret_cast(wd)); } break; @@ -575,15 +577,15 @@ namespace nana { //enable refreshing flag, this is a RAII class for exception-safe flag_guard fguard(this, wd); - wd->drawer.resized(*arg); + wd->drawer.resized(*arg, bForce__EmitInternal); } - if (!draw_only) + if (bProcess__External_event) evts_ptr->resized.emit(*arg, reinterpret_cast(wd)); } break; } case event_code::unload: - if (!draw_only) + if (bProcess__External_event) { auto arg = dynamic_cast(&event_arg); if (arg && (wd->other.category == category::flags::root)) @@ -595,7 +597,7 @@ namespace nana } break; case event_code::destroy: - if (!draw_only) + if (bProcess__External_event) { auto arg = dynamic_cast(&event_arg); if (arg) diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 55c39b58..9b0e24e0 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -232,7 +232,7 @@ namespace detail //No implementation for Linux } - bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd) + bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd, const bool bForce__EmitInternal) { if(wd_manager().available(wd) == false) return false; @@ -248,7 +248,7 @@ namespace detail if(wd->other.upd_state == core_window_t::update_state::none) wd->other.upd_state = core_window_t::update_state::lazy; - _m_emit_core(evt_code, wd, false, arg); + _m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal); //A child of wd may not be drawn if it was out of wd's range before wd resized, //so refresh all children of wd when a resized occurs. @@ -396,7 +396,7 @@ namespace detail } template - void draw_invoker(void(::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) + void draw_invoker(void(::nana::detail::drawer::*event_ptr)(const Arg&, const bool), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) { if(bedrock::instance().wd_manager().available(wd) == false) return; @@ -410,7 +410,7 @@ namespace detail if(wd->other.upd_state == basic_window::update_state::none) wd->other.upd_state = basic_window::update_state::lazy; - (wd->drawer.*event_ptr)(arg); + (wd->drawer.*event_ptr)(arg, false); if(thrd) thrd->event_window = pre_wd; } diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 68d996b3..ebf32705 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -755,7 +755,7 @@ namespace detail } template - void draw_invoker(void (::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) + void draw_invoker(void (::nana::detail::drawer::*event_ptr)(const Arg&, const bool), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) { if (bedrock::instance().wd_manager().available(wd) == false) return; @@ -770,7 +770,7 @@ namespace detail if (wd->other.upd_state == basic_window::update_state::none) wd->other.upd_state = basic_window::update_state::lazy; - (wd->drawer.*event_ptr)(arg); + (wd->drawer.*event_ptr)(arg, false); if (thrd) thrd->event_window = prev_event_wd; } @@ -1626,7 +1626,7 @@ namespace detail } } - bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd) + bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd, const bool bForce__EmitInternal) { if (wd_manager().available(wd) == false) return false; @@ -1642,7 +1642,7 @@ namespace detail if (wd->other.upd_state == core_window_t::update_state::none) wd->other.upd_state = core_window_t::update_state::lazy; - _m_emit_core(evt_code, wd, false, arg); + _m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal); bool good_wd = false; if (wd_manager().available(wd)) diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index f73cb3ee..e6b9108a 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -128,8 +128,88 @@ namespace nana return 0 != (overrided_ & (1 << static_cast(evt_code))); } + void drawer_trigger::filter_event(const event_code evt_code, const bool bDisabled) + { + if (bDisabled) + evt_disabled_ |= 1 << static_cast(evt_code); // set + else + evt_disabled_ &= ~(1 << static_cast(evt_code)); // clear + } + + void drawer_trigger::filter_event(const std::vector evt_codes, const bool bDisabled) + { + const auto it_end = evt_codes.end(); + for (auto it = evt_codes.begin(); it != it_end; it++) + filter_event(*it, bDisabled); + } + + void drawer_trigger::filter_event(const event_filter_status& evt_all_states) + { + evt_disabled_ = evt_all_states.evt_disabled_; + } + + bool drawer_trigger::filter_event(const event_code evt_code) + { + return static_cast((evt_disabled_ >> static_cast(evt_code)) & 1); + } + + event_filter_status drawer_trigger::filter_event() + { + return event_filter_status(evt_disabled_); + } + + void drawer_trigger::clear_filter() + { + for (int i = 0; i < static_cast(nana::event_code::end); i++) + filter_event(static_cast(i), false); + } + //end class drawer_trigger + //class event_filter_status + event_filter_status::event_filter_status() + { + evt_disabled_ = 0; + } + + event_filter_status::event_filter_status(const event_filter_status& rOther) + { + this->evt_disabled_ = rOther.evt_disabled_; + } + + event_filter_status::event_filter_status(const unsigned evt_disabled_) + { + this->evt_disabled_ = evt_disabled_; + } + + bool event_filter_status::operator[](const nana::event_code evt_code) const + { + return static_cast((evt_disabled_ >> static_cast(evt_code)) & 1); + } + + bool event_filter_status::operator==(const event_filter_status& rOther) const + { + return evt_disabled_ == rOther.evt_disabled_; + } + + bool event_filter_status::operator!=(const event_filter_status& rOther) const + { + return evt_disabled_ != rOther.evt_disabled_; + } + + const event_filter_status& event_filter_status::operator=(const event_filter_status& rOther) + { + evt_disabled_ = rOther.evt_disabled_; + return *this; + } + + const event_filter_status& event_filter_status::operator=(const unsigned evt_disabled_) + { + this->evt_disabled_ = evt_disabled_; + return *this; + } + //end of class event_filter_status + namespace detail { typedef bedrock bedrock_type; @@ -174,89 +254,89 @@ namespace nana data_impl_->realizer->typeface_changed(graphics); } - void drawer::click(const arg_click& arg) + void drawer::click(const arg_click& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::click, arg, &drawer_trigger::click); + _m_emit(event_code::click, arg, &drawer_trigger::click, bForce__EmitInternal); } - void drawer::dbl_click(const arg_mouse& arg) + void drawer::dbl_click(const arg_mouse& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::dbl_click, arg, &drawer_trigger::dbl_click); + _m_emit(event_code::dbl_click, arg, &drawer_trigger::dbl_click, bForce__EmitInternal); } - void drawer::mouse_enter(const arg_mouse& arg) + void drawer::mouse_enter(const arg_mouse& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_enter, arg, &drawer_trigger::mouse_enter); + _m_emit(event_code::mouse_enter, arg, &drawer_trigger::mouse_enter, bForce__EmitInternal); } - void drawer::mouse_move(const arg_mouse& arg) + void drawer::mouse_move(const arg_mouse& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_move, arg, &drawer_trigger::mouse_move); + _m_emit(event_code::mouse_move, arg, &drawer_trigger::mouse_move, bForce__EmitInternal); } - void drawer::mouse_leave(const arg_mouse& arg) + void drawer::mouse_leave(const arg_mouse& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_leave, arg, &drawer_trigger::mouse_leave); + _m_emit(event_code::mouse_leave, arg, &drawer_trigger::mouse_leave, bForce__EmitInternal); } - void drawer::mouse_down(const arg_mouse& arg) + void drawer::mouse_down(const arg_mouse& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_down, arg, &drawer_trigger::mouse_down); + _m_emit(event_code::mouse_down, arg, &drawer_trigger::mouse_down, bForce__EmitInternal); } - void drawer::mouse_up(const arg_mouse& arg) + void drawer::mouse_up(const arg_mouse& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_up, arg, &drawer_trigger::mouse_up); + _m_emit(event_code::mouse_up, arg, &drawer_trigger::mouse_up, bForce__EmitInternal); } - void drawer::mouse_wheel(const arg_wheel& arg) + void drawer::mouse_wheel(const arg_wheel& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_wheel, arg, &drawer_trigger::mouse_wheel); + _m_emit(event_code::mouse_wheel, arg, &drawer_trigger::mouse_wheel, bForce__EmitInternal); } - void drawer::mouse_dropfiles(const arg_dropfiles& arg) + void drawer::mouse_dropfiles(const arg_dropfiles& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::mouse_drop, arg, &drawer_trigger::mouse_dropfiles); + _m_emit(event_code::mouse_drop, arg, &drawer_trigger::mouse_dropfiles, bForce__EmitInternal); } - void drawer::resizing(const arg_resizing& arg) + void drawer::resizing(const arg_resizing& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::resizing, arg, &drawer_trigger::resizing); + _m_emit(event_code::resizing, arg, &drawer_trigger::resizing, bForce__EmitInternal); } - void drawer::resized(const arg_resized& arg) + void drawer::resized(const arg_resized& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::resized, arg, &drawer_trigger::resized); + _m_emit(event_code::resized, arg, &drawer_trigger::resized, bForce__EmitInternal); } - void drawer::move(const arg_move& arg) + void drawer::move(const arg_move& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::move, arg, &drawer_trigger::move); + _m_emit(event_code::move, arg, &drawer_trigger::move, bForce__EmitInternal); } - void drawer::focus(const arg_focus& arg) + void drawer::focus(const arg_focus& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::focus, arg, &drawer_trigger::focus); + _m_emit(event_code::focus, arg, &drawer_trigger::focus, bForce__EmitInternal); } - void drawer::key_press(const arg_keyboard& arg) + void drawer::key_press(const arg_keyboard& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::key_press, arg, &drawer_trigger::key_press); + _m_emit(event_code::key_press, arg, &drawer_trigger::key_press, bForce__EmitInternal); } - void drawer::key_char(const arg_keyboard& arg) + void drawer::key_char(const arg_keyboard& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::key_char, arg, &drawer_trigger::key_char); + _m_emit(event_code::key_char, arg, &drawer_trigger::key_char, bForce__EmitInternal); } - void drawer::key_release(const arg_keyboard& arg) + void drawer::key_release(const arg_keyboard& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::key_release, arg, &drawer_trigger::key_release); + _m_emit(event_code::key_release, arg, &drawer_trigger::key_release, bForce__EmitInternal); } - void drawer::shortkey(const arg_keyboard& arg) + void drawer::shortkey(const arg_keyboard& arg, const bool bForce__EmitInternal) { - _m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey); + _m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey, bForce__EmitInternal); } void drawer::map(window wd, bool forced, const rectangle* update_area) //Copy the root buffer to screen diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 6121d95d..1fd7d158 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -62,7 +62,12 @@ namespace API bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg) { - return restrict::bedrock.emit(evt_code, reinterpret_cast<::nana::detail::basic_window*>(wd), arg, true, restrict::bedrock.get_thread_context()); + return restrict::bedrock.emit(evt_code, reinterpret_cast<::nana::detail::basic_window*>(wd), arg, true, restrict::bedrock.get_thread_context(), false); + } + + bool emit_internal_event(event_code evt_code, window wd, const ::nana::event_arg& arg) + { + return restrict::bedrock.emit(evt_code, reinterpret_cast<::nana::detail::basic_window*>(wd), arg, true, restrict::bedrock.get_thread_context(), true); } void enum_widgets_function_base::enum_widgets(window wd, bool recursive)