From 7dae0861629dac1f87a077a1c88e0ca89588809a Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 15 Jun 2015 22:31:03 +0800 Subject: [PATCH 1/2] fix caret and tab switch on invisible widgets(#62) --- include/nana/gui/detail/window_manager.hpp | 10 +- source/gui/detail/bedrock_pi.cpp | 11 +++ source/gui/detail/drawer.cpp | 2 +- source/gui/detail/win32/bedrock.cpp | 2 +- source/gui/detail/window_manager.cpp | 101 ++++++++++++--------- source/gui/programming_interface.cpp | 2 +- 6 files changed, 77 insertions(+), 51 deletions(-) diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index ba6aa451..2d3a217c 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -87,13 +87,11 @@ namespace detail std::vector stack_; }; public: - typedef native_window_type native_window; - typedef revertible_mutex mutex_type; + using native_window = native_window_type; + using mutex_type = revertible_mutex; - typedef basic_window core_window_t; - typedef std::vector cont_type; - - typedef window_layout wndlayout_type; + using core_window_t = basic_window; + using window_layer = window_layout; window_manager(); ~window_manager(); diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 7843fbaa..e76b0686 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -63,6 +63,17 @@ namespace nana arg.window_handle = reinterpret_cast(wd); if (emit(event_code::expose, wd, arg, false, get_thread_context())) { + if (wd->together.caret) + { + if (exposed) + { + if (wd->root_widget->other.attribute.root->focus == wd) + wd->together.caret->visible(true); + } + else + wd->together.caret->visible(false); + } + if (!exposed) { if (category::flags::root != wd->other.category) diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index 8c176b4b..0170ec0d 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -265,7 +265,7 @@ namespace nana if (false == edge_nimbus_renderer_t::instance().render(iwd, forced, update_area)) { rectangle vr; - if (bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr)) + if (bedrock_type::window_manager_t::window_layer::read_visual_rectangle(iwd, vr)) { if (update_area) ::nana::overlap(*update_area, rectangle(vr), vr); diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 1bb25cc9..daeb369d 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -1400,7 +1400,7 @@ namespace detail if(msgwnd) { - if((wParam == 9) && (false == (msgwnd->flags.tab & tab_type::eating))) //Tab + if((wParam == 9) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab { auto the_next = brock.wd_manager.tabstop(msgwnd, (::GetKeyState(VK_SHIFT) >= 0)); if(the_next) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 7f8da08b..44444659 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -428,35 +428,34 @@ namespace detail { //Thread-Safe Required! std::lock_guard lock(mutex_); - if (impl_->wd_register.available(wd)) + if (!impl_->wd_register.available(wd)) + return false; + + if(visible != wd->visible) { - if(visible != wd->visible) + native_window_type nv = nullptr; + switch(wd->other.category) { - native_window_type nv = nullptr; - switch(wd->other.category) - { - case category::root_tag::value: - nv = wd->root; break; - case category::frame_tag::value: - nv = wd->other.attribute.frame->container; break; - default: //category::widget_tag, category::lite_widget_tag - break; - } - - if(visible && wd->effect.bground) - wndlayout_type::make_bground(wd); - - //Don't set the visible attr of a window if it is a root. - //The visible attr of a root will be set in the expose event. - if(category::root_tag::value != wd->other.category) - bedrock::instance().event_expose(wd, visible); - - if(nv) - native_interface::show_window(nv, visible, wd->flags.take_active); + case category::root_tag::value: + nv = wd->root; break; + case category::frame_tag::value: + nv = wd->other.attribute.frame->container; break; + default: //category::widget_tag, category::lite_widget_tag + break; } - return true; + + if(visible && wd->effect.bground) + window_layer::make_bground(wd); + + //Don't set the visible attr of a window if it is a root. + //The visible attr of a root will be set in the expose event. + if(category::flags::root != wd->other.category) + bedrock::instance().event_expose(wd, visible); + + if(nv) + native_interface::show_window(nv, visible, wd->flags.take_active); } - return false; + return true; } window_manager::core_window_t* window_manager::find_window(native_window_type root, int x, int y) @@ -645,7 +644,7 @@ namespace detail if(wd->effect.bground && wd->parent) { wd->other.glass_buffer.make(sz); - wndlayout_type::make_bground(wd); + window_layer::make_bground(wd); } } } @@ -709,13 +708,13 @@ namespace detail { if(forced || (false == wd->belong_to_lazy())) { - wndlayout_type::paint(wd, redraw, false); + window_layer::paint(wd, redraw, false); this->map(wd, forced, update_area); } else { if(redraw) - wndlayout_type::paint(wd, true, false); + window_layer::paint(wd, true, false); if(wd->other.upd_state == core_window_t::update_state::lazy) wd->other.upd_state = core_window_t::update_state::refresh; } @@ -730,7 +729,7 @@ namespace detail //It's not worthy to redraw if visible is false if (impl_->wd_register.available(wd) && wd->visible && wd->visible_parents()) - wndlayout_type::paint(wd, true, true); + window_layer::paint(wd, true, true); } //do_lazy_refresh @@ -751,7 +750,7 @@ namespace detail { if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen) { - wndlayout_type::paint(wd, false, false); + window_layer::paint(wd, false, false); this->map(wd, force_copy_to_screen); } else if (effects::edge_nimbus::none != wd->effect.edge_nimbus) @@ -762,7 +761,7 @@ namespace detail } } else - wndlayout_type::paint(wd, true, false); //only refreshing if it has an invisible parent + window_layer::paint(wd, true, false); //only refreshing if it has an invisible parent } wd->other.upd_state = core_window_t::update_state::none; return true; @@ -782,7 +781,7 @@ namespace detail result.make(wd->drawer.graphics.size()); result.bitblt(0, 0, wd->drawer.graphics); - wndlayout_type::paste_children_to_graphics(wd, result); + window_layer::paste_children_to_graphics(wd, result); return true; } @@ -791,7 +790,7 @@ namespace detail //Thread-Safe Required! std::lock_guard lock(mutex_); return (impl_->wd_register.available(wd) ? - wndlayout_type::read_visual_rectangle(wd, r) : + window_layer::read_visual_rectangle(wd, r) : false); } @@ -1020,13 +1019,8 @@ namespace detail } } - auto window_manager::tabstop(core_window_t* wd, bool forward) const -> core_window_t* + window_manager::core_window_t* get_tabstop(window_manager::core_window_t* wd, bool forward) { - //Thread-Safe Required! - std::lock_guard lock(mutex_); - if (!impl_->wd_register.available(wd)) - return nullptr; - auto & tabs = wd->root_widget->other.attribute.root->tabstop; if (tabs.size()) { @@ -1041,7 +1035,7 @@ namespace detail if (i != end) { ++i; - core_window_t* ts = (i != end ? (*i) : tabs.front()); + window_manager::core_window_t* ts = (i != end ? (*i) : tabs.front()); return (ts != wd ? ts : 0); } else @@ -1058,6 +1052,29 @@ namespace detail return nullptr; } + auto window_manager::tabstop(core_window_t* wd, bool forward) const -> core_window_t* + { + //Thread-Safe Required! + std::lock_guard lock(mutex_); + if (!impl_->wd_register.available(wd)) + return nullptr; + + auto new_stop = get_tabstop(wd, forward); + + while (new_stop) + { + if (wd == new_stop) + break; + + if (new_stop->flags.enabled && new_stop->visible) + return new_stop; + + new_stop = get_tabstop(new_stop, forward); + } + + return nullptr; + } + void window_manager::remove_trash_handle(unsigned tid) { impl_->wd_register.delete_trash(tid); @@ -1068,7 +1085,7 @@ namespace detail //Thread-Safe Required! std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd)) - return wndlayout_type::enable_effects_bground(wd, enabled); + return window_layer::enable_effects_bground(wd, enabled); return false; } @@ -1369,7 +1386,7 @@ namespace detail brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context()); _m_disengage(wd, nullptr); - wndlayout_type::enable_effects_bground(wd, false); + window_layer::enable_effects_bground(wd, false); wd->drawer.detached(); impl_->signal.call_signal(wd, signals::code::destroy, signals_); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index d6f8b483..254b8619 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -721,7 +721,7 @@ namespace API if(restrict::window_manager.available(iwd) && (iwd->flags.enabled != enabled)) { iwd->flags.enabled = enabled; - restrict::window_manager.update(iwd, true, false); + restrict::window_manager.update(iwd, true, true); if(category::flags::root == iwd->other.category) restrict::interface_type::enable_window(iwd->root, enabled); } From 5982f8c7bfcb29748aaf1eb509d289dbde85ebf8 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 16 Jun 2015 00:12:09 +0800 Subject: [PATCH 2/2] fix a crash error when click on an empty category of listbox --- source/gui/widgets/listbox.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 9c8eccf7..8b2af38f 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1591,7 +1591,7 @@ namespace nana } /// set all items in cat to selection sel, emiting events, actualizing last_selected_abs, but not check for single_selection_ - bool categ_selected(size_type cat, bool sel); + void categ_selected(size_type cat, bool sel); void reverse_categ_selected(size_type categ) { @@ -2481,21 +2481,16 @@ namespace nana return list_str ; } - bool es_lister::categ_selected(size_type cat, bool sel) + void es_lister::categ_selected(size_type cat, bool sel) { - bool changed = false; // we need this?? - cat_proxy cpx{ess_,cat}; for (item_proxy &it : cpx ) { if (it.selected() != sel) - changed = true; - it.select(sel); + it.select(sel); } last_selected_abs = last_selected_dpl = index_pair {cat, npos}; - - return changed; // we need this?? } class drawer_header_impl @@ -3823,6 +3818,11 @@ namespace nana //Behavior of a container item_proxy cat_proxy::begin() const { + auto i = ess_->lister.cat_container().begin(); + std::advance(i, pos_); + if (i->items.empty()) + return end(); + return item_proxy(ess_, index_pair(pos_, 0)); }