From ca1fce932a69cc68e3d4a69f5906f9599ddbc70b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 12 Apr 2016 22:17:07 +0800 Subject: [PATCH] minor changes --- include/nana/detail/win32/platform_spec.hpp | 2 +- include/nana/gui/detail/bedrock.hpp | 9 +- include/nana/gui/detail/bedrock_pi_data.hpp | 10 ++ source/gui/detail/bedrock_pi.cpp | 109 ++++++++++++ source/gui/detail/bedrock_posix.cpp | 151 +--------------- source/gui/detail/bedrock_windows.cpp | 185 +++----------------- source/gui/detail/window_manager.cpp | 10 +- 7 files changed, 158 insertions(+), 318 deletions(-) diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index dc6329fe..9e868e0b 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -68,7 +68,7 @@ namespace detail tray = 0x501, async_activate, async_set_focus, - map_thread_root_buffer, + remote_flush_surface, remote_thread_destroy_window, remote_thread_move_window, operate_caret, //wParam: 1=Destroy, 2=SetPos diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 92328361..88973217 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -14,7 +14,6 @@ #define NANA_GUI_DETAIL_BEDROCK_HPP #include "general_events.hpp" #include "color_schemes.hpp" -#include "internal_scope_guard.hpp" namespace nana { @@ -41,14 +40,13 @@ namespace detail ~bedrock(); void pump_event(window, bool is_modal); - void map_thread_root_buffer(core_window_t*, bool forced, const rectangle* update_area = nullptr); + void flush_surface(core_window_t*, bool forced, const rectangle* update_area = nullptr); static int inc_window(unsigned tid = 0); thread_context* open_thread_context(unsigned tid = 0); thread_context* get_thread_context(unsigned tid = 0); void remove_thread_context(unsigned tid = 0); static bedrock& instance(); - ::nana::category::flags category(core_window_t*); core_window_t* focus(); void set_menubar_taken(core_window_t*); @@ -62,8 +60,9 @@ namespace detail void erase_menu(bool try_destroy); void get_key_state(arg_keyboard&); - bool set_keyboard_shortkey(bool yes); - bool whether_keyboard_shortkey() const; + + bool shortkey_occurred(bool status); + bool shortkey_occurred() const; element_store& get_element_store() const; void map_through_widgets(core_window_t*, native_drawable_type); diff --git a/include/nana/gui/detail/bedrock_pi_data.hpp b/include/nana/gui/detail/bedrock_pi_data.hpp index 3154a6b3..309a7930 100644 --- a/include/nana/gui/detail/bedrock_pi_data.hpp +++ b/include/nana/gui/detail/bedrock_pi_data.hpp @@ -17,6 +17,16 @@ namespace nana events_operation evt_operation; window_manager wd_manager; std::set auto_form_set; + bool shortkey_occurred{ false }; + + struct menu_rep + { + core_window_t* taken_window{ nullptr }; + bool delay_restore{ false }; + native_window_type window{ nullptr }; + native_window_type owner{ nullptr }; + bool has_keyboard{ false }; + }menu; }; } } diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 09a5f555..928c422a 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -233,6 +233,115 @@ namespace nana } } + void bedrock::set_menubar_taken(core_window_t* wd) + { + auto pre = pi_data_->menu.taken_window; + pi_data_->menu.taken_window = wd; + + //assigning of a nullptr taken window is to restore the focus of pre taken + //don't restore the focus if pre is a menu. + if ((!wd) && pre && (pre->root != get_menu())) + { + internal_scope_guard lock; + wd_manager().set_focus(pre, false, arg_focus::reason::general); + wd_manager().update(pre, true, false); + } + } + + //0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying + void bedrock::delay_restore(int state) + { + switch (state) + { + case 0: //Enable + break; + case 1: //Cancel + break; + case 2: //Restore if key released + //restores the focus when menu is closed by pressing keyboard + if ((!pi_data_->menu.window) && pi_data_->menu.delay_restore) + set_menubar_taken(nullptr); + break; + case 3: //Restores if destroying + //when the menu is destroying, restores the focus if delay restore is not declared + if (!pi_data_->menu.delay_restore) + set_menubar_taken(nullptr); + } + + pi_data_->menu.delay_restore = (0 == state); + } + + bool bedrock::close_menu_if_focus_other_window(native_window_type wd) + { + if (pi_data_->menu.window && (pi_data_->menu.window != wd)) + { + wd = native_interface::get_owner_window(wd); + while (wd) + { + if (wd != pi_data_->menu.window) + wd = native_interface::get_owner_window(wd); + else + return false; + } + erase_menu(true); + return true; + } + return false; + } + + void bedrock::set_menu(native_window_type menu_wd, bool has_keyboard) + { + if(menu_wd && pi_data_->menu.window != menu_wd) + { + erase_menu(true); + + pi_data_->menu.window = menu_wd; + pi_data_->menu.owner = native_interface::get_owner_window(menu_wd); + pi_data_->menu.has_keyboard = has_keyboard; + } + } + + native_window_type bedrock::get_menu(native_window_type owner, bool is_keyboard_condition) + { + if ((pi_data_->menu.owner == nullptr) || + (owner && (pi_data_->menu.owner == owner)) + ) + { + return (is_keyboard_condition ? (pi_data_->menu.has_keyboard ? pi_data_->menu.window : nullptr) : pi_data_->menu.window); + } + + return 0; + } + + native_window_type bedrock::get_menu() + { + return pi_data_->menu.window; + } + + void bedrock::erase_menu(bool try_destroy) + { + if (pi_data_->menu.window) + { + if (try_destroy) + native_interface::close_window(pi_data_->menu.window); + + pi_data_->menu.window = pi_data_->menu.owner = nullptr; + pi_data_->menu.has_keyboard = false; + } + } + + bool bedrock::shortkey_occurred(bool status) + { + auto last_status = pi_data_->shortkey_occurred; + pi_data_->shortkey_occurred = status; + return last_status; + } + + bool bedrock::shortkey_occurred() const + { + return pi_data_->shortkey_occurred; + } + widget_colors& bedrock::get_scheme_template(scheme_factory_interface&& factory) { return pi_data_->scheme.scheme_template(std::move(factory)); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 45818349..624fa042 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -97,27 +97,6 @@ namespace detail thread_context *object{ nullptr }; }tcontext; }cache; - - struct menu_tag - { - core_window_t* taken_window{ nullptr }; - bool delay_restore{ false }; - native_window_type window{ nullptr }; - native_window_type owner{ nullptr }; - bool has_keyboard{ false }; - }menu; - - struct keyboard_tracking_state_tag - { - keyboard_tracking_state_tag() - :has_shortkey_occured(false), has_keyup(true), alt(0) - {} - - bool has_shortkey_occured; - bool has_keyup; - - unsigned long alt : 2; - }keyboard_tracking_state; }; void timer_proc(unsigned); @@ -153,9 +132,9 @@ namespace detail delete impl_; } - void bedrock::map_thread_root_buffer(core_window_t*, bool forced, const rectangle*) + void bedrock::flush_surface(core_window_t* wd, bool forced, const rectangle* update_area) { - //GUI in X11 is thread-independent, so no implementation. + wd->drawer.map(reinterpret_cast(wd), forced, update_area); } //inc_window @@ -229,118 +208,12 @@ namespace detail return bedrock_object; } - category::flags bedrock::category(bedrock::core_window_t* wd) - { - if(wd) - { - internal_scope_guard lock; - if(wd_manager().available(wd)) - return wd->other.category; - } - return category::flags::super; - } - bedrock::core_window_t* bedrock::focus() { core_window_t* wd = wd_manager().root(native_interface::get_focus_window()); return (wd ? wd->other.attribute.root->focus : 0); } - void bedrock::set_menubar_taken(core_window_t* wd) - { - auto pre = impl_->menu.taken_window; - impl_->menu.taken_window = wd; - - //assigning of a nullptr taken window is to restore the focus of pre taken - if ((!wd) && pre) - { - internal_scope_guard lock; - wd_manager().set_focus(pre, false, arg_focus::reason::general); - wd_manager().update(pre, true, false); - } - } - - //0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying - void bedrock::delay_restore(int state) - { - switch (state) - { - case 0: //Enable - break; - case 1: //Cancel - break; - case 2: //Restore if key released - //restores the focus when menu is closed by pressing keyboard - if ((!impl_->menu.window) && impl_->menu.delay_restore) - set_menubar_taken(nullptr); - break; - case 3: //Restores if destroying - //when the menu is destroying, restores the focus if delay restore is not declared - if (!impl_->menu.delay_restore) - set_menubar_taken(nullptr); - } - - impl_->menu.delay_restore = (0 == state); - } - - bool bedrock::close_menu_if_focus_other_window(native_window_type wd) - { - if(impl_->menu.window && (impl_->menu.window != wd)) - { - wd = native_interface::get_owner_window(wd); - while(wd) - { - if(wd != impl_->menu.window) - wd = native_interface::get_owner_window(wd); - else - return false; - } - erase_menu(true); - return true; - } - return false; - } - - void bedrock::set_menu(native_window_type menu_window, bool has_keyboard) - { - if(menu_window && impl_->menu.window != menu_window) - { - erase_menu(true); - impl_->menu.window = menu_window; - impl_->menu.owner = native_interface::get_owner_window(menu_window); - impl_->menu.has_keyboard = has_keyboard; - } - } - - native_window_type bedrock::get_menu(native_window_type owner, bool is_keyboard_condition) - { - if( (impl_->menu.owner == nullptr) || - (owner && (impl_->menu.owner == owner)) - ) - { - return ( is_keyboard_condition ? (impl_->menu.has_keyboard ? impl_->menu.window : nullptr) : impl_->menu.window); - } - - return 0; - } - - native_window_type bedrock::get_menu() - { - return impl_->menu.window; - } - - void bedrock::erase_menu(bool try_destroy) - { - if (impl_->menu.window) - { - if (try_destroy) - native_interface::close_window(impl_->menu.window); - - impl_->menu.window = impl_->menu.owner = nullptr; - impl_->menu.has_keyboard = false; - } - } - void bedrock::get_key_state(arg_keyboard& arg) { XKeyEvent xkey; @@ -349,18 +222,6 @@ namespace detail arg.shift = (xkey.state & ShiftMask); } - bool bedrock::set_keyboard_shortkey(bool yes) - { - bool ret = impl_->keyboard_tracking_state.has_shortkey_occured; - impl_->keyboard_tracking_state.has_shortkey_occured = yes; - return ret; - } - - bool bedrock::whether_keyboard_shortkey() const - { - return impl_->keyboard_tracking_state.has_shortkey_occured; - } - element_store& bedrock::get_element_store() const { return impl_->estore; @@ -1038,7 +899,7 @@ namespace detail else if(keyboard::alt == os_code) { context.is_alt_pressed = true; - if (brock.whether_keyboard_shortkey() == false) + if (brock.shortkey_occurred() == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if (msgwnd) @@ -1109,7 +970,7 @@ namespace detail { arg.ctrl = arg.shift = false; arg.evt_code = event_code::shortkey; - brock.set_keyboard_shortkey(true); + brock.shortkey_occurred(true); auto shr_wd = wd_manager.find_shortkey(native_window, arg.key); if(shr_wd) { @@ -1126,7 +987,7 @@ namespace detail draw_invoker(&drawer::key_char, msgwnd, arg, &context); } - if(brock.set_keyboard_shortkey(false)) + if(brock.shortkey_occurred(false)) context.is_alt_pressed = false; } break; @@ -1204,7 +1065,7 @@ namespace detail else { context.is_alt_pressed = false; - if (brock.set_keyboard_shortkey(false) == false) + if (brock.shortkey_occurred(false) == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if (msgwnd) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 143b00ef..d0bb0d82 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -177,26 +177,6 @@ namespace detail thread_context *object{ nullptr }; }tcontext; }cache; - - struct menu_tag - { - core_window_t* taken_window{ nullptr }; - bool delay_restore{ false }; - native_window_type window{ nullptr }; - native_window_type owner{ nullptr }; - bool has_keyboard{false}; - }menu; - - struct keyboard_tracking_state_tag - { - keyboard_tracking_state_tag() - :alt(0) - {} - - bool has_shortkey_occured = false; - bool has_keyup = true; - unsigned long alt : 2; - }keyboard_tracking_state; }; //class bedrock defines a static object itself to implement a static singleton @@ -325,14 +305,28 @@ namespace detail return bedrock_object; } - void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced, const rectangle* update_area) + void bedrock::flush_surface(core_window_t* wd, bool forced, const rectangle* update_area) { - auto stru = reinterpret_cast(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread))); - if (stru) + if (nana::system::this_thread_id() != wd->thread_id) { - if (FALSE == ::PostMessage(reinterpret_cast(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast(wd), reinterpret_cast(stru))) - ::HeapFree(::GetProcessHeap(), 0, stru); + auto stru = reinterpret_cast(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread))); + if (stru) + { + stru->forced = forced; + stru->ignore_update_area = true; + + if (update_area) + { + stru->ignore_update_area = false; + stru->update_area = *update_area; + } + + if (FALSE == ::PostMessage(reinterpret_cast(wd->root), nana::detail::messages::remote_flush_surface, reinterpret_cast(wd), reinterpret_cast(stru))) + ::HeapFree(::GetProcessHeap(), 0, stru); + } } + else + wd->drawer.map(reinterpret_cast(wd), forced, update_area); } void interior_helper_for_menu(MSG& msg, native_window_type menu_window) @@ -544,14 +538,6 @@ namespace detail } } - void assign_arg(arg_focus& arg, basic_window* wd, native_window_type recv, bool getting) - { - arg.window_handle = reinterpret_cast(wd); - arg.receiver = recv; - arg.getting = getting; - arg.focus_reason = arg_focus::reason::general; - } - void assign_arg(arg_wheel& arg, basic_window* wd, const parameter_decoder& pmdec) { arg.window_handle = reinterpret_cast(wd); @@ -602,7 +588,7 @@ namespace detail break; } return true; - case nana::detail::messages::map_thread_root_buffer: + case nana::detail::messages::remote_flush_surface: { auto stru = reinterpret_cast(lParam); bedrock.wd_manager().map(reinterpret_cast(wParam), stru->forced, (stru->ignore_update_area ? nullptr : &stru->update_area)); @@ -858,10 +844,9 @@ namespace detail } break; case WM_SHOWWINDOW: - if (msgwnd->visible && (wParam == FALSE)) - brock.event_expose(msgwnd, false); - else if ((!msgwnd->visible) && (wParam != FALSE)) - brock.event_expose(msgwnd, true); + if (msgwnd->visible == (FALSE == wParam)) + brock.event_expose(msgwnd, !msgwnd->visible); + def_window_proc = true; break; case WM_WINDOWPOSCHANGED: @@ -1312,7 +1297,7 @@ namespace detail break; case WM_SYSCHAR: def_window_proc = true; - brock.set_keyboard_shortkey(true); + brock.shortkey_occurred(true); msgwnd = brock.wd_manager().find_shortkey(native_window, static_cast(wParam)); if(msgwnd) { @@ -1328,7 +1313,7 @@ namespace detail break; case WM_SYSKEYDOWN: def_window_proc = true; - if (brock.whether_keyboard_shortkey() == false) + if (brock.shortkey_occurred() == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if (msgwnd) @@ -1350,7 +1335,7 @@ namespace detail break; case WM_SYSKEYUP: def_window_proc = true; - if(brock.set_keyboard_shortkey(false) == false) + if (brock.shortkey_occurred(false) == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if(msgwnd) @@ -1531,7 +1516,7 @@ namespace detail } } else - brock.set_keyboard_shortkey(false); + brock.shortkey_occurred(false); //Do delay restore if key is not arrow_left/right/up/down, otherwise //A menubar will be restored if the item is empty(not have a menu item) @@ -1591,132 +1576,18 @@ namespace detail return ::DefWindowProc(root_window, message, wParam, lParam); } - ::nana::category::flags bedrock::category(core_window_t* wd) - { - internal_scope_guard lock; - return (wd_manager().available(wd) ? wd->other.category : ::nana::category::flags::super); - } - auto bedrock::focus() ->core_window_t* { core_window_t* wd = wd_manager().root(native_interface::get_focus_window()); return (wd ? wd->other.attribute.root->focus : nullptr); } - void bedrock::set_menubar_taken(core_window_t* wd) - { - auto pre = impl_->menu.taken_window; - impl_->menu.taken_window = wd; - - //assigning of a nullptr taken window is to restore the focus of pre taken - //don't restore the focus if pre is a menu. - if ((!wd) && pre && (pre->root != get_menu())) - { - internal_scope_guard lock; - wd_manager().set_focus(pre, false, arg_focus::reason::general); - wd_manager().update(pre, true, false); - } - } - - //0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying - void bedrock::delay_restore(int state) - { - switch (state) - { - case 0: //Enable - break; - case 1: //Cancel - break; - case 2: //Restore if key released - //restores the focus when menu is closed by pressing keyboard - if ((!impl_->menu.window) && impl_->menu.delay_restore) - set_menubar_taken(nullptr); - break; - case 3: //Restores if destroying - //when the menu is destroying, restores the focus if delay restore is not declared - if (!impl_->menu.delay_restore) - set_menubar_taken(nullptr); - } - - impl_->menu.delay_restore = (0 == state); - } - - bool bedrock::close_menu_if_focus_other_window(native_window_type wd) - { - if(impl_->menu.window && (impl_->menu.window != wd)) - { - wd = native_interface::get_owner_window(wd); - while(wd) - { - if(wd != impl_->menu.window) - wd = native_interface::get_owner_window(wd); - else - return false; - } - erase_menu(true); - return true; - } - return false; - } - - void bedrock::set_menu(native_window_type menu_wd, bool has_keyboard) - { - if(menu_wd && impl_->menu.window != menu_wd) - { - erase_menu(true); - - impl_->menu.window = menu_wd; - impl_->menu.owner = native_interface::get_owner_window(menu_wd); - impl_->menu.has_keyboard = has_keyboard; - } - } - - native_window_type bedrock::get_menu(native_window_type owner, bool is_keyboard_condition) - { - if( (impl_->menu.owner == nullptr) || - (owner && (impl_->menu.owner == owner)) - ) - { - return ((!is_keyboard_condition) || impl_->menu.has_keyboard ? impl_->menu.window : nullptr); - } - return nullptr; - } - - native_window_type bedrock::get_menu() - { - return impl_->menu.window; - } - - void bedrock::erase_menu(bool try_destroy) - { - if (impl_->menu.window) - { - if (try_destroy) - native_interface::close_window(impl_->menu.window); - - impl_->menu.window = impl_->menu.owner = nullptr; - impl_->menu.has_keyboard = false; - } - } - void bedrock::get_key_state(arg_keyboard& kb) { kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 0x80)); kb.shift = (0 != (::GetKeyState(VK_SHIFT) & 0x80)); } - bool bedrock::set_keyboard_shortkey(bool yes) - { - bool ret = impl_->keyboard_tracking_state.has_shortkey_occured; - impl_->keyboard_tracking_state.has_shortkey_occured = yes; - return ret; - } - - bool bedrock::whether_keyboard_shortkey() const - { - return impl_->keyboard_tracking_state.has_shortkey_occured; - } - element_store& bedrock::get_element_store() const { return impl_->estore; @@ -1724,7 +1595,6 @@ namespace detail void bedrock::map_through_widgets(core_window_t* wd, native_drawable_type drawable) { -#if defined(NANA_WINDOWS) auto graph_context = reinterpret_cast(wd->root_graph->handle()->context); for (auto child : wd->children) @@ -1739,7 +1609,6 @@ namespace detail else if (::nana::category::flags::lite_widget == child->other.category) map_through_widgets(child, drawable); } -#endif } bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 5e1ee247..39e88c87 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -777,15 +777,7 @@ namespace detail parent = parent->parent; } - //Copy the root buffer that wd specified into DeviceContext -#if defined(NANA_LINUX) || defined(NANA_MACOS) - wd->drawer.map(reinterpret_cast(wd), forced, update_area); -#elif defined(NANA_WINDOWS) - if(nana::system::this_thread_id() == wd->thread_id) - wd->drawer.map(reinterpret_cast(wd), forced, update_area); - else - bedrock::instance().map_thread_root_buffer(wd, forced, update_area); -#endif + bedrock::instance().flush_surface(wd, forced, update_area); } }