Merge remote-tracking branch 'cnjinhao/hotfix-1.3' into geometric_scheme

This commit is contained in:
qPCR4vir 2016-04-08 20:20:03 +02:00
commit 5b574d74e6
10 changed files with 182 additions and 82 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Platform Specification Implementation * Platform Specification Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -25,6 +25,7 @@
#include <windows.h> #include <windows.h>
#include <map> #include <map>
#include <memory> #include <memory>
#include <functional>
namespace nana namespace nana
{ {
@ -63,9 +64,15 @@ namespace detail
bool forced; bool forced;
}; };
struct arg_affinity_execute
{
const std::function<void()> * function_ptr;
};
enum enum
{ {
tray = 0x501, tray = 0x501,
async_activate, async_activate,
async_set_focus, async_set_focus,
map_thread_root_buffer, map_thread_root_buffer,
@ -74,6 +81,10 @@ namespace detail
operate_caret, //wParam: 1=Destroy, 2=SetPos operate_caret, //wParam: 1=Destroy, 2=SetPos
remote_thread_set_window_pos, remote_thread_set_window_pos,
remote_thread_set_window_text, remote_thread_set_window_text,
//Execute a function in a thread with is associated with a specified native window
affinity_execute,
user, user,
}; };
}; };

View File

@ -1,7 +1,7 @@
/* /*
* Forward Declaration of Internal Scope Guard * Forward Declaration of Internal Scope Guard
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -26,6 +26,18 @@ namespace nana
internal_scope_guard(); internal_scope_guard();
~internal_scope_guard(); ~internal_scope_guard();
}; };
class internal_revert_guard
{
internal_revert_guard(const internal_revert_guard&) = delete;
internal_revert_guard(internal_revert_guard&&) = delete;
internal_revert_guard& operator=(const internal_revert_guard&) = delete;
internal_revert_guard& operator=(internal_revert_guard&&) = delete;
public:
internal_revert_guard();
~internal_revert_guard();
};
} }
#endif #endif

View File

@ -1,7 +1,7 @@
/* /*
* Platform Implementation * Platform Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -36,6 +36,9 @@ namespace detail
using native_string_type = ::nana::detail::native_string_type; using native_string_type = ::nana::detail::native_string_type;
//Execute a function in a thread which is associated with the specified native window.
static void affinity_execute(native_window_type, const std::function<void()>&);
static nana::size primary_monitor_size(); static nana::size primary_monitor_size();
static rectangle screen_area_from_point(const point&); static rectangle screen_area_from_point(const point&);
static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&); static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&);

View File

@ -60,6 +60,8 @@ namespace API
//@brief: The interfaces defined in namespace dev are used for developing the nana.gui //@brief: The interfaces defined in namespace dev are used for developing the nana.gui
namespace dev namespace dev
{ {
void affinity_execute(window window_handle, const std::function<void()>&);
bool set_events(window, const std::shared_ptr<general_events>&); bool set_events(window, const std::shared_ptr<general_events>&);
template<typename Scheme> template<typename Scheme>

View File

@ -97,13 +97,6 @@ namespace nana{ namespace pat{
typedef int inner_bool::* operator_bool_t; typedef int inner_bool::* operator_bool_t;
/*
template<typename U>
struct member_enabled //deprecated
: public std::enable_if<(!std::is_base_of<cloneable, typename std::remove_reference<U>::type>::value) && std::is_base_of<base_t, typename std::remove_reference<U>::type>::value, int>
{};
*/
template<typename U> template<typename U>
using member_enabled = std::enable_if<(!std::is_base_of<cloneable, typename std::remove_reference<U>::type>::value) && std::is_base_of<base_t, typename std::remove_reference<U>::type>::value, int>; using member_enabled = std::enable_if<(!std::is_base_of<cloneable, typename std::remove_reference<U>::type>::value) && std::is_base_of<base_t, typename std::remove_reference<U>::type>::value, int>;
public: public:

View File

@ -1,7 +1,7 @@
/* /*
* A Bedrock Platform-Independent Implementation * A Bedrock Platform-Independent Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -36,6 +36,18 @@ namespace nana
detail::bedrock::instance().wd_manager().internal_lock().unlock(); detail::bedrock::instance().wd_manager().internal_lock().unlock();
} }
//end class internal_scope_guard //end class internal_scope_guard
//class internal_revert_guard
internal_revert_guard::internal_revert_guard()
{
detail::bedrock::instance().wd_manager().internal_lock().revert();
}
internal_revert_guard::~internal_revert_guard()
{
detail::bedrock::instance().wd_manager().internal_lock().forward();
}
//end class internal_revert_guard
//class event_arg //class event_arg
void event_arg::stop_propagation() const void event_arg::stop_propagation() const

View File

@ -669,6 +669,14 @@ namespace detail
case nana::detail::messages::tray: case nana::detail::messages::tray:
notifications_window_proc(wd, wParam, lParam); notifications_window_proc(wd, wParam, lParam);
return true; return true;
case nana::detail::messages::affinity_execute:
if (wParam)
{
auto arg = reinterpret_cast<detail::messages::arg_affinity_execute*>(wParam);
if (arg->function_ptr)
(*arg->function_ptr)();
}
break;
default: default:
break; break;
} }

View File

@ -1,7 +1,7 @@
/* /*
* Platform Implementation * Platform Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -13,6 +13,9 @@
#include <nana/detail/platform_spec_selector.hpp> #include <nana/detail/platform_spec_selector.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/screen.hpp> #include <nana/gui/screen.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/window_manager.hpp>
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#if defined(STD_THREAD_NOT_SUPPORTED) #if defined(STD_THREAD_NOT_SUPPORTED)
#include <nana/std_mutex.hpp> #include <nana/std_mutex.hpp>
@ -23,8 +26,6 @@
#include "../../paint/detail/image_ico.hpp" #include "../../paint/detail/image_ico.hpp"
#elif defined(NANA_X11) #elif defined(NANA_X11)
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/window_manager.hpp>
#endif #endif
namespace nana{ namespace nana{
@ -131,9 +132,13 @@ namespace nana{
} }
} }
if (async) if (async)
{
::ShowWindowAsync(wd, cmd); ::ShowWindowAsync(wd, cmd);
else return;
::ShowWindow(wd, cmd); }
internal_revert_guard revert;
::ShowWindow(wd, cmd);
} }
#elif defined(NANA_X11) #elif defined(NANA_X11)
namespace restrict namespace restrict
@ -143,6 +148,33 @@ namespace nana{
#endif #endif
//struct native_interface //struct native_interface
void native_interface::affinity_execute(native_window_type native_handle, const std::function<void()>& fn)
{
if (!fn)
return;
#if defined(NANA_WINDOWS)
auto mswin = reinterpret_cast<HWND>(native_handle);
if (::IsWindow(mswin))
{
if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(mswin, nullptr))
{
detail::messages::arg_affinity_execute arg;
arg.function_ptr = &fn;
internal_revert_guard revert;
::SendMessage(mswin, detail::messages::affinity_execute, reinterpret_cast<WPARAM>(&arg), 0);
return;
}
}
fn();
#else
fn();
#endif
}
nana::size native_interface::primary_monitor_size() nana::size native_interface::primary_monitor_size()
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
@ -1119,11 +1151,18 @@ namespace nana{
auto native_interface::window_caption(native_window_type wd) -> native_string_type auto native_interface::window_caption(native_window_type wd) -> native_string_type
{ {
native_string_type str;
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
auto & lock = bedrock::instance().wd_manager().internal_lock();
bool is_current_thread = (::GetCurrentThreadId() == ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr));
if (!is_current_thread)
lock.revert();
int length = ::GetWindowTextLength(reinterpret_cast<HWND>(wd)); int length = ::GetWindowTextLength(reinterpret_cast<HWND>(wd));
if(length > 0) if(length > 0)
{ {
native_string_type str;
//One for NULL terminator which GetWindowText will write. //One for NULL terminator which GetWindowText will write.
str.resize(length+1); str.resize(length+1);
@ -1131,9 +1170,11 @@ namespace nana{
//Remove the null terminator writtien by GetWindowText //Remove the null terminator writtien by GetWindowText
str.resize(length); str.resize(length);
return str;
} }
if (!is_current_thread)
lock.forward();
#elif defined(NANA_X11) #elif defined(NANA_X11)
nana::detail::platform_scope_guard psg; nana::detail::platform_scope_guard psg;
::XTextProperty txtpro; ::XTextProperty txtpro;
@ -1145,14 +1186,13 @@ namespace nana{
{ {
if(size > 1) if(size > 1)
{ {
std::string text = *strlist; str = *strlist;
::XFreeStringList(strlist); ::XFreeStringList(strlist);
return text;
} }
} }
} }
#endif #endif
return native_string_type(); return str;
} }
void native_interface::capture_window(native_window_type wd, bool cap) void native_interface::capture_window(native_window_type wd, bool cap)
@ -1314,7 +1354,10 @@ namespace nana{
if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr)) if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr))
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::async_set_focus, 0, 0); ::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::async_set_focus, 0, 0);
else else
{
internal_revert_guard revert;
::SetFocus(reinterpret_cast<HWND>(wd)); ::SetFocus(reinterpret_cast<HWND>(wd));
}
} }
#elif defined(NANA_X11) #elif defined(NANA_X11)
nana::detail::platform_scope_guard lock; nana::detail::platform_scope_guard lock;

View File

@ -1,7 +1,7 @@
/* /*
* Parts of Class Place * Parts of Class Place
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -277,66 +277,11 @@ namespace nana
void add_pane(factory & fn) void add_pane(factory & fn)
{ {
rectangle r{ point(), this->size()}; auto fn_ptr = &fn;
API::dev::affinity_execute(*this, [this, fn_ptr]
//get a rectangle excluding caption
r.y = 20;
if (r.height > 20)
r.height -= 20;
else
r.height = 0;
if (!tabbar_)
{ {
if (panels_.size() > 0) _m_add_pane(*fn_ptr);
{ });
tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear();
tabbar_->events().selected([this]
{
auto handle = tabbar_->attach(tabbar_->selected());
if (handle)
caption_.caption(API::window_caption(handle));
else
caption_.caption(::std::string());
});
tabbar_->move({ 0, r.bottom() - 20, r.width, 20 });
r.height -= 20;
std::size_t pos = 0;
for (auto & pn : panels_)
{
tabbar_->push_back(::nana::charset(pn.widget_ptr->caption()));
tabbar_->attach(pos++, *pn.widget_ptr);
}
}
}
else
r.height -= 20;
auto wdg = fn(*this);
if (tabbar_)
{
tabbar_->push_back(::nana::charset(wdg->caption()));
tabbar_->attach(panels_.size(), wdg->handle());
}
if (panels_.empty())
{
caption_.caption(wdg->caption());
}
panels_.emplace_back();
panels_.back().widget_ptr.swap(wdg);
for (auto & pn : panels_)
{
if (pn.widget_ptr)
pn.widget_ptr->move(r);
}
} }
void float_away(const ::nana::point& move_pos) void float_away(const ::nana::point& move_pos)
@ -382,6 +327,72 @@ namespace nana
{ {
return (nullptr != container_); return (nullptr != container_);
} }
private:
void _m_add_pane(factory & fn)
{
rectangle r{ point(), this->size() };
//get a rectangle excluding caption
r.y = 20;
if (r.height > 20)
r.height -= 20;
else
r.height = 0;
if (!tabbar_)
{
if (panels_.size() > 0)
{
tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear();
tabbar_->events().selected([this]
{
auto handle = tabbar_->attach(tabbar_->selected());
if (handle)
caption_.caption(API::window_caption(handle));
else
caption_.caption(::std::string());
});
tabbar_->move({ 0, r.bottom() - 20, r.width, 20 });
r.height -= 20;
std::size_t pos = 0;
for (auto & pn : panels_)
{
tabbar_->push_back(::nana::charset(pn.widget_ptr->caption()));
tabbar_->attach(pos++, *pn.widget_ptr);
}
}
}
else
r.height -= 20;
auto wdg = fn(*this);
if (wdg)
{
if (tabbar_)
{
tabbar_->push_back(::nana::charset(wdg->caption()));
tabbar_->attach(panels_.size(), wdg->handle());
}
if (panels_.empty())
{
caption_.caption(wdg->caption());
}
panels_.emplace_back();
panels_.back().widget_ptr.swap(wdg);
for (auto & pn : panels_)
{
if (pn.widget_ptr)
pn.widget_ptr->move(r);
}
}
}
private: private:
window host_window_{nullptr}; window host_window_{nullptr};
place_parts::dock_notifier_interface* notifier_{ nullptr }; place_parts::dock_notifier_interface* notifier_{ nullptr };

View File

@ -179,6 +179,11 @@ namespace API
namespace dev namespace dev
{ {
void affinity_execute(window window_handle, const std::function<void()>& fn)
{
interface_type::affinity_execute(root(window_handle), fn);
}
bool set_events(window wd, const std::shared_ptr<general_events>& gep) bool set_events(window wd, const std::shared_ptr<general_events>& gep)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);