add event filter contributed by A2Razor

This commit is contained in:
Jinhao
2017-09-01 22:57:12 +08:00
parent 2cf0adf777
commit 2974fe2137
9 changed files with 254 additions and 89 deletions

View File

@@ -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<window>(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<arg_mouse>* 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<window>(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<window>(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<arg_keyboard>* 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<window>(wd));
break;
}
case event_code::expose:
if (!draw_only)
if (bProcess__External_event)
{
auto arg = dynamic_cast<const arg_expose*>(&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<window>(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<window>(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<window>(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<window>(wd));
}
break;
}
case event_code::unload:
if (!draw_only)
if (bProcess__External_event)
{
auto arg = dynamic_cast<const arg_unload*>(&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<const arg_destroy*>(&event_arg);
if (arg)

View File

@@ -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<typename Arg>
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;
}

View File

@@ -755,7 +755,7 @@ namespace detail
}
template<typename Arg>
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))

View File

@@ -128,8 +128,88 @@ namespace nana
return 0 != (overrided_ & (1 << static_cast<int>(evt_code)));
}
void drawer_trigger::filter_event(const event_code evt_code, const bool bDisabled)
{
if (bDisabled)
evt_disabled_ |= 1 << static_cast<int>(evt_code); // set
else
evt_disabled_ &= ~(1 << static_cast<int>(evt_code)); // clear
}
void drawer_trigger::filter_event(const std::vector<event_code> 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<bool>((evt_disabled_ >> static_cast<int>(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<int>(nana::event_code::end); i++)
filter_event(static_cast<nana::event_code>(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<bool>((evt_disabled_ >> static_cast<int>(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

View File

@@ -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)