diff --git a/build/codeblocks/nana.layout b/build/codeblocks/nana.layout
new file mode 100644
index 00000000..593c06ed
--- /dev/null
+++ b/build/codeblocks/nana.layout
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp
index e772a911..2230a422 100644
--- a/include/nana/gui/detail/basic_window.hpp
+++ b/include/nana/gui/detail/basic_window.hpp
@@ -222,9 +222,6 @@ namespace detail
basic_window* focus{nullptr};
basic_window* menubar{nullptr};
bool ime_enabled{false};
-#if defined(NANA_WINDOWS)
- cursor running_cursor{ nana::cursor::arrow };
-#endif
cursor state_cursor{nana::cursor::arrow};
basic_window* state_cursor_window{ nullptr };
diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp
index 1c6f50d0..4caef33e 100644
--- a/include/nana/gui/programming_interface.hpp
+++ b/include/nana/gui/programming_interface.hpp
@@ -64,7 +64,7 @@ namespace API
void affinity_execute(window window_handle, const std::function&);
bool set_events(window, const std::shared_ptr&);
-
+
template
std::unique_ptr make_scheme()
{
@@ -161,7 +161,7 @@ namespace API
}//end namespace detail
void exit(); ///< close all windows in current thread
- void exit_all(); ///< close all windows
+ void exit_all(); ///< close all windows
/// @brief Searchs whether the text contains a '&' and removes the character for transforming.
/// If the text contains more than one '&' charachers, the others are ignored. e.g
@@ -189,7 +189,7 @@ namespace API
void window_icon_default(const paint::image& small_icon, const paint::image& big_icon = {});
void window_icon(window, const paint::image& small_icon, const paint::image& big_icon = {});
-
+
bool empty_window(window); ///< Determines whether a window is existing.
bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window.
bool is_destroying(window); ///< Determines whether a window is destroying
@@ -292,7 +292,7 @@ namespace API
* @param window_handle A handle to the window to be refreshed.
*/
void refresh_window(window window_handle);
- void refresh_window_tree(window); ///< Refreshs the specified window and all it’s children windows, then display it immediately
+ void refresh_window_tree(window); ///< Refreshes the specified window and all its children windows, then display it immediately
void update_window(window); ///< Copies the off-screen buffer to the screen for immediate display.
void window_caption(window, const std::string& title_utf8);
@@ -304,7 +304,7 @@ namespace API
void activate_window(window);
- /// Determines whether the specified window will get the keyboard focus when its root window gets native system focus.
+ /// Determines whether the specified window will get the keyboard focus when its root window gets native system focus.
bool is_focus_ready(window);
/// Returns the current keyboard focus window.
@@ -322,7 +322,7 @@ namespace API
* @param ignore_children Indicates whether to redirect the mouse input to its children if the mouse pointer is over its children.
*/
void set_capture(window window_handle, bool ignore_children);
-
+
/// Disable a window to grab the mouse input.
/**
* @param window handle A handle to a window to release grab of mouse input.
diff --git a/include/nana/gui/widgets/categorize.hpp b/include/nana/gui/widgets/categorize.hpp
index 1e64fa14..dcbdde12 100644
--- a/include/nana/gui/widgets/categorize.hpp
+++ b/include/nana/gui/widgets/categorize.hpp
@@ -1,7 +1,7 @@
/**
* A Categorize Implementation
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/nana/gui/widgets/detail/tree_cont.hpp b/include/nana/gui/widgets/detail/tree_cont.hpp
index c9684ba6..2490ab95 100644
--- a/include/nana/gui/widgets/detail/tree_cont.hpp
+++ b/include/nana/gui/widgets/detail/tree_cont.hpp
@@ -1,6 +1,6 @@
/*
* A Tree Container class implementation
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -58,6 +58,31 @@ namespace detail
t = t_next;
}
}
+
+ bool is_ancestor_of(const tree_node* child) const
+ {
+ while (child)
+ {
+ if (child->owner == this)
+ return true;
+
+ child = child->owner;
+ }
+ return false;
+ }
+
+ tree_node * front() const
+ {
+ if (this->owner && (this != this->owner->child))
+ {
+ auto i = this->owner->child;
+ while (i->next != this)
+ i = i->next;
+
+ return i;
+ }
+ return nullptr;
+ }
};
template
@@ -76,12 +101,17 @@ namespace detail
~tree_cont()
{
- clear();
+ clear(&root_);
}
- void clear()
+ void clear(node_type* node)
{
- remove(root_.child);
+ while (node->child)
+ {
+ //If there is a sibling of child, the root_.child
+ //will be assigned with the sibling.
+ remove(node->child);
+ }
}
bool verify(const node_type* node) const
diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp
index dbbb6452..c4e39981 100644
--- a/include/nana/gui/widgets/scroll.hpp
+++ b/include/nana/gui/widgets/scroll.hpp
@@ -122,7 +122,9 @@ namespace nana
void value(size_type s)
{
- if (s + metrics_.range > metrics_.peak)
+ if (metrics_.range > metrics_.peak)
+ s = 0;
+ else if (s + metrics_.range > metrics_.peak)
s = metrics_.peak - metrics_.range;
if (graph_ && (metrics_.value != s))
diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp
index e090426a..5b9b5a02 100644
--- a/include/nana/gui/widgets/spinbox.hpp
+++ b/include/nana/gui/widgets/spinbox.hpp
@@ -1,7 +1,7 @@
/**
* A Spin box widget
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp
index 2f4fe7d7..a7e1bc77 100644
--- a/include/nana/gui/widgets/treebox.hpp
+++ b/include/nana/gui/widgets/treebox.hpp
@@ -37,7 +37,7 @@ namespace nana
{
enum class component
{
- begin, expender = begin, crook, icon, text, bground, end
+ begin, expander = begin, crook, icon, text, bground, end
};
struct node_image_tag
@@ -119,27 +119,17 @@ namespace nana
implement * impl() const;
void check(node_type*, checkstate);
- bool draw();
-
- const tree_cont_type & tree() const;
- tree_cont_type & tree();
void renderer(::nana::pat::cloneable&&);
const ::nana::pat::cloneable& renderer() const;
void placer(::nana::pat::cloneable&&);
const ::nana::pat::cloneable& placer() const;
- nana::any & value(node_type*) const;
node_type* insert(node_type*, const std::string& key, std::string&&);
node_type* insert(const std::string& path, std::string&&);
- bool verify_kinship(node_type* parent, node_type* child) const;
-
- void remove(node_type*);
node_type * selected() const;
void selected(node_type*);
- void set_expand(node_type*, bool);
- void set_expand(const ::std::string& path, bool);
node_image_tag& icon(const ::std::string&) const;
void icon_erase(const ::std::string&);
@@ -201,6 +191,9 @@ namespace nana
/// Set the check state, and it returns itself.
item_proxy& check(bool);
+ /// Clears the child nodes
+ item_proxy& clear();
+
/// Return true when the node is expanded \todo change to expanded ??
bool expanded() const;
diff --git a/include/nana/system/dataexch.hpp b/include/nana/system/dataexch.hpp
index 226515b6..7ce6be72 100644
--- a/include/nana/system/dataexch.hpp
+++ b/include/nana/system/dataexch.hpp
@@ -38,6 +38,8 @@ namespace system{
void get(std::string& text_utf8);
void get(std::wstring& text);
+
+ std::wstring wget();
private:
bool _m_set(format, const void* buf, std::size_t size, native_window_type);
void* _m_get(format, size_t& size);
diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp
index a8bf2d7b..b4804546 100644
--- a/include/nana/verbose_preprocessor.hpp
+++ b/include/nana/verbose_preprocessor.hpp
@@ -30,9 +30,9 @@
- #define STRING2(x) #x
+ #define STRING2(...) #__VA_ARGS__
#define STRING(x) STRING2(x)
- #define SHOW_VALUE(x) " " #x " = " STRING2(x)
+ #define SHOW_VALUE(x) " " #x " = " STRING2(x)
#pragma message ( "\n -----> Verbose preprocessor" )
#pragma message ( SHOW_VALUE(VERBOSE_PREPROCESSOR) )
@@ -124,7 +124,7 @@
#pragma message ( SHOW_VALUE(USE_LIBJPEG_FROM_OS) )
#pragma message ( SHOW_VALUE(NANA_LIBJPEG) )
-
+
// #pragma message ( "\n =" STRING() ", \n =" STRING()" , \n =" STRING() )
#if defined(STOP_VERBOSE_PREPROCESSOR)
diff --git a/source/detail/platform_spec_posix.cpp b/source/detail/platform_spec_posix.cpp
index 7dd11333..cce9028f 100644
--- a/source/detail/platform_spec_posix.cpp
+++ b/source/detail/platform_spec_posix.cpp
@@ -1,7 +1,7 @@
/*
* Platform Specification Implementation
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Nana Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -1163,8 +1163,16 @@ namespace detail
// 2 = msg_dispatcher should ignore the msg, because the XEvent is processed by _m_msg_filter
int platform_spec::_m_msg_filter(XEvent& evt, msg_packet_tag& msg)
{
+ auto & bedrock = detail::bedrock::instance();
+
platform_spec & self = instance();
- if(SelectionNotify == evt.type)
+ if(KeyPress == evt.type || KeyRelease == evt.type)
+ {
+ auto menu_wd = bedrock.get_menu(reinterpret_cast(evt.xkey.window), true);
+ if(menu_wd)
+ evt.xkey.window = reinterpret_cast(menu_wd);
+ }
+ else if(SelectionNotify == evt.type)
{
if(evt.xselection.property)
{
@@ -1197,7 +1205,6 @@ namespace detail
}
}
-
self.selection_.items.erase(self.selection_.items.begin());
std::lock_guardcond_mutex)> lock(im->cond_mutex);
@@ -1373,9 +1380,8 @@ namespace detail
{
Window child;
::XTranslateCoordinates(self.display_, self.root_window(), evt.xclient.window, x, y, &self.xdnd_.pos.x, &self.xdnd_.pos.y, &child);
- typedef detail::bedrock bedrock;
- auto wd = bedrock::instance().wd_manager().find_window(reinterpret_cast(evt.xclient.window), self.xdnd_.pos.x, self.xdnd_.pos.y);
+ auto wd = bedrock.wd_manager().find_window(reinterpret_cast(evt.xclient.window), self.xdnd_.pos.x, self.xdnd_.pos.y);
if(wd && wd->flags.dropable)
{
accepted = true;
diff --git a/source/detail/x11/msg_dispatcher.hpp b/source/detail/x11/msg_dispatcher.hpp
index 77f43a18..b6fddcce 100644
--- a/source/detail/x11/msg_dispatcher.hpp
+++ b/source/detail/x11/msg_dispatcher.hpp
@@ -1,6 +1,6 @@
/*
* Message Dispatcher Implementation
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -51,7 +51,7 @@ namespace detail
typedef std::list msg_queue_type;
msg_dispatcher(Display* disp)
- : display_(disp), is_work_(false)
+ : display_(disp)
{
proc_.event_proc = 0;
proc_.timer_proc = 0;
@@ -338,7 +338,7 @@ namespace detail
private:
Display * display_;
- volatile bool is_work_;
+ volatile bool is_work_{ false };
std::unique_ptr thrd_;
struct table_tag
diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp
index 5a3a4abe..f47ca96a 100644
--- a/source/gui/detail/bedrock_posix.cpp
+++ b/source/gui/detail/bedrock_posix.cpp
@@ -611,11 +611,18 @@ namespace detail
//If a root window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event.
if (msgwnd->root != native_interface::get_focus_window())
{
- //call the drawer mouse up event for restoring the surface graphics
- msgwnd->set_action(mouse_action::normal);
+ auto pos = native_interface::cursor_position();
+ auto rootwd = native_interface::find_window(pos.x, pos.y);
+ native_interface::calc_window_point(rootwd, pos);
+ if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y))
+ {
+ //call the drawer mouse up event for restoring the surface graphics
+ msgwnd->set_action(mouse_action::normal);
- draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
- wd_manager.do_lazy_refresh(msgwnd, false);
+ arg.evt_code = event_code::mouse_up;
+ draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
+ wd_manager.do_lazy_refresh(msgwnd, false);
+ }
}
}
else
@@ -1147,7 +1154,7 @@ namespace detail
}
}
- void bedrock::pump_event(window modal_window, bool /*is_modal*/)
+ void bedrock::pump_event(window condition_wd, bool is_modal)
{
thread_context * context = open_thread_context();
if(0 == context->window_count)
@@ -1162,11 +1169,11 @@ namespace detail
auto & lock = wd_manager().internal_lock();
lock.revert();
- native_window_type owner_native = 0;
+ native_window_type owner_native{};
core_window_t * owner = 0;
- if(modal_window)
+ if(condition_wd && is_modal)
{
- native_window_type modal = reinterpret_cast(modal_window)->root;
+ native_window_type modal = reinterpret_cast(condition_wd)->root;
owner_native = native_interface::get_owner_window(modal);
if(owner_native)
{
@@ -1177,7 +1184,7 @@ namespace detail
}
}
- nana::detail::platform_spec::instance().msg_dispatch(modal_window ? reinterpret_cast(modal_window)->root : 0);
+ nana::detail::platform_spec::instance().msg_dispatch(condition_wd ? reinterpret_cast(condition_wd)->root : 0);
if(owner_native)
{
@@ -1190,7 +1197,7 @@ namespace detail
if(0 == --(context->event_pump_ref_count))
{
- if(0 == modal_window || 0 == context->window_count)
+ if(0 == condition_wd || 0 == context->window_count)
remove_thread_context();
}
diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp
index 11ef721a..80a8fd12 100644
--- a/source/gui/detail/bedrock_windows.cpp
+++ b/source/gui/detail/bedrock_windows.cpp
@@ -1,7 +1,7 @@
/**
* A Bedrock Implementation
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -345,7 +345,7 @@ namespace detail
}
}
- void bedrock::pump_event(window modal_window, bool is_modal)
+ void bedrock::pump_event(window condition_wd, bool is_modal)
{
const unsigned tid = ::GetCurrentThreadId();
auto context = this->open_thread_context(tid);
@@ -365,9 +365,9 @@ namespace detail
try
{
MSG msg;
- if(modal_window)
+ if (condition_wd)
{
- HWND native_handle = reinterpret_cast(reinterpret_cast(modal_window)->root);
+ HWND native_handle = reinterpret_cast(reinterpret_cast(condition_wd)->root);
if (is_modal)
{
HWND owner = ::GetWindow(native_handle, GW_OWNER);
@@ -437,27 +437,27 @@ namespace detail
}
catch(std::exception& e)
{
- (msgbox(modal_window, "An uncaptured std::exception during message pumping: ").icon(msgbox::icon_information)
- <<"\n in form: "<< API::window_caption(modal_window)
- <<"\n exception : "<< e.what()
- ).show();
+ (msgbox(condition_wd, "An uncaptured std::exception during message pumping: ").icon(msgbox::icon_information)
+ << "\n in form: " << API::window_caption(condition_wd)
+ <<"\n exception : "<< e.what()
+ ).show();
- internal_scope_guard lock;
- _m_except_handler();
+ internal_scope_guard lock;
+ _m_except_handler();
- intr_locker.forward();
- if (0 == --(context->event_pump_ref_count))
- {
- if ((nullptr == modal_window) || (0 == context->window_count))
- remove_thread_context();
- }
- throw;
+ intr_locker.forward();
+ if (0 == --(context->event_pump_ref_count))
+ {
+ if ((nullptr == condition_wd) || (0 == context->window_count))
+ remove_thread_context();
+ }
+ throw;
}
catch(...)
{
- (msgbox(modal_window, "An exception during message pumping!").icon(msgbox::icon_information)
+ (msgbox(condition_wd, "An exception during message pumping!").icon(msgbox::icon_information)
<<"An uncaptured non-std exception during message pumping!"
- << "\n in form: " << API::window_caption(modal_window)
+ << "\n in form: " << API::window_caption(condition_wd)
).show();
internal_scope_guard lock;
_m_except_handler();
@@ -465,7 +465,7 @@ namespace detail
intr_locker.forward();
if(0 == --(context->event_pump_ref_count))
{
- if((nullptr == modal_window) || (0 == context->window_count))
+ if ((nullptr == condition_wd) || (0 == context->window_count))
remove_thread_context();
}
throw;
@@ -474,7 +474,7 @@ namespace detail
intr_locker.forward();
if(0 == --(context->event_pump_ref_count))
{
- if((nullptr == modal_window) || (0 == context->window_count))
+ if ((nullptr == condition_wd) || (0 == context->window_count))
remove_thread_context();
}
}//end pump_event
@@ -784,7 +784,7 @@ namespace detail
static auto& brock = bedrock::instance();
static restrict::TRACKMOUSEEVENT track = {sizeof track, 0x00000002};
- auto native_window = reinterpret_cast(root_window);
+ auto const native_window = reinterpret_cast(root_window);
auto & wd_manager = brock.wd_manager();
auto* root_runtime = wd_manager.root_runtime(native_window);
@@ -1720,9 +1720,16 @@ namespace detail
thrd->cursor.handle = ::LoadCursor(nullptr, translate(cur));
}
- if (wd->root_widget->other.attribute.root->running_cursor != cur)
+ auto this_cur = reinterpret_cast(
+#ifdef _WIN64
+ ::GetClassLongPtr(reinterpret_cast(wd->root), GCLP_HCURSOR)
+#else
+ ::GetClassLong(reinterpret_cast(wd->root), GCL_HCURSOR)
+#endif
+ );
+
+ if(this_cur != thrd->cursor.handle)
{
- wd->root_widget->other.attribute.root->running_cursor = cur;
#ifdef _WIN64
::SetClassLongPtr(reinterpret_cast(wd->root), GCLP_HCURSOR,
reinterpret_cast(thrd->cursor.handle));
@@ -1731,6 +1738,7 @@ namespace detail
static_cast(reinterpret_cast(thrd->cursor.handle)));
#endif
}
+
if (cursor::arrow == thrd->cursor.predef_cursor)
{
thrd->cursor.window = nullptr;
@@ -1804,10 +1812,7 @@ namespace detail
undefine_state_cursor(wd, thrd);
if(wd == thrd->cursor.window)
- {
set_cursor(wd, cursor::arrow, thrd);
- wd->root_widget->other.attribute.root->running_cursor = cursor::arrow;
- }
break;
default:
break;
diff --git a/source/gui/detail/events_operation.cpp b/source/gui/detail/events_operation.cpp
index bcafd688..40fe338e 100644
--- a/source/gui/detail/events_operation.cpp
+++ b/source/gui/detail/events_operation.cpp
@@ -80,19 +80,22 @@ namespace nana
internal_scope_guard lock;
if (dockers_)
{
-
for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i)
{
if (reinterpret_cast(evt) == *i)
{
//Checks whether this event is working now.
- if (emitting_count_ > 1)
+ if (emitting_count_)
{
static_cast(*i)->flag_deleted = true;
deleted_flags_ = true;
}
else
+ {
+ bedrock::instance().evt_operation().cancel(evt);
dockers_->erase(i);
+ delete reinterpret_cast(evt);
+ }
break;
}
}
@@ -131,7 +134,11 @@ namespace nana
for (auto i = evt_->dockers_->begin(); i != evt_->dockers_->end();)
{
if (static_cast(*i)->flag_deleted)
+ {
+ bedrock::instance().evt_operation().cancel(reinterpret_cast(*i));
+ delete (*i);
i = evt_->dockers_->erase(i);
+ }
else
++i;
}
diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp
index 0657dd14..bdf75823 100644
--- a/source/gui/detail/native_window_interface.cpp
+++ b/source/gui/detail/native_window_interface.cpp
@@ -1,7 +1,7 @@
/*
* Platform Implementation
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -197,6 +197,13 @@ namespace nana{
return rectangle{ primary_monitor_size() };
}
+#ifdef NANA_X11
+ //The XMoveWindow and XMoveResizeWindow don't take effect if the specified window is
+ //unmapped, and the members x and y of XSetSizeHints is obsoluted. So the position that
+ //set to a unmapped windows should be kept and use the position when the window is mapped.
+ std::map exposed_positions; //locked by platform_scope_guard
+#endif
+
//platform-dependent
native_interface::window_result native_interface::create_window(native_window_type owner, bool nested, const rectangle& r, const appearance& app)
{
@@ -289,6 +296,7 @@ namespace nana{
{
win_attr.save_under = True;
attr_mask |= CWSaveUnder;
+
parent = restrict::spec.root_window();
calc_screen_point(owner, pos);
}
@@ -303,7 +311,12 @@ namespace nana{
{
//make owner if it is a popup window
if((!nested) && owner)
+ {
restrict::spec.make_owner(owner, reinterpret_cast(handle));
+ exposed_positions[handle] = pos;
+ }
+
+ XChangeWindowAttributes(disp, handle, attr_mask, &win_attr);
XTextProperty name;
char text[] = "Nana Window";
@@ -655,6 +668,14 @@ namespace nana{
if(show)
{
::XMapWindow(disp, reinterpret_cast(wd));
+
+ auto i = exposed_positions.find(reinterpret_cast(wd));
+ if(i != exposed_positions.end())
+ {
+ ::XMoveWindow(disp, reinterpret_cast(wd), i->second.x, i->second.y);
+ exposed_positions.erase(i);
+ }
+
Window grab = restrict::spec.grab(0);
if(grab == reinterpret_cast(wd))
capture_window(wd, true);
@@ -882,13 +903,7 @@ namespace nana{
XWindowAttributes attr;
::XGetWindowAttributes(disp, reinterpret_cast(wd), &attr);
if(attr.map_state == IsUnmapped)
- {
- XSizeHints hints;
- hints.flags = USPosition;
- hints.x = x;
- hints.y = y;
- ::XSetWMNormalHints(disp, reinterpret_cast(wd), &hints);
- }
+ exposed_positions[reinterpret_cast(wd)] = ::nana::point{x, y};
::XMoveWindow(disp, reinterpret_cast(wd), x, y);
#endif
@@ -959,11 +974,11 @@ namespace nana{
::XGetWindowAttributes(disp, reinterpret_cast(wd), &attr);
if(attr.map_state == IsUnmapped)
{
- hints.flags |= (USPosition | USSize);
- hints.x = x;
- hints.y = y;
+ hints.flags |= USSize;
hints.width = r.width;
hints.height = r.height;
+
+ exposed_positions[reinterpret_cast(wd)] = point{x, y};
}
if(hints.flags)
diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp
index e301ca5e..affd3abd 100644
--- a/source/gui/detail/window_manager.cpp
+++ b/source/gui/detail/window_manager.cpp
@@ -1,7 +1,7 @@
/*
* Window Manager Implementation
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -685,6 +685,30 @@ namespace detail
}
}
+ void sync_child_root_display(window_manager::core_window_t* wd)
+ {
+ for (auto & child : wd->children)
+ {
+ if (category::flags::root != child->other.category)
+ {
+ sync_child_root_display(child);
+ continue;
+ }
+
+ auto const vs_parents = child->visible_parents();
+
+ if (vs_parents != child->visible)
+ {
+ native_interface::show_window(child->root, vs_parents, false);
+ }
+ else
+ {
+ if (child->visible != native_interface::is_window_visible(child->root))
+ native_interface::show_window(child->root, child->visible, false);
+ }
+ }
+ }
+
//show
//@brief: show or hide a window
bool window_manager::show(core_window_t* wd, bool visible)
@@ -719,8 +743,15 @@ namespace detail
if(category::flags::root != wd->other.category)
bedrock::instance().event_expose(wd, visible);
- if(nv)
+ if (nv)
+ {
+ if (visible && !wd->visible_parents())
+ return true;
+
native_interface::show_window(nv, visible, wd->flags.take_active);
+ }
+
+ sync_child_root_display(wd);
}
return true;
}
@@ -1386,6 +1417,8 @@ namespace detail
void window_manager::remove_trash_handle(unsigned tid)
{
+ //Thread-Safe Required!
+ std::lock_guard lock(mutex_);
impl_->wd_register.delete_trash(tid);
}
diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp
index 6b3b9510..6560fe93 100644
--- a/source/gui/msgbox.cpp
+++ b/source/gui/msgbox.cpp
@@ -618,7 +618,7 @@ namespace nana
place_.field_display(img_fields[i], false);
}
- size({desc_extent.width, height });
+ move(API::make_center(this->owner(), desc_extent.width, height));
caption(title);
}
diff --git a/source/gui/widgets/categorize.cpp b/source/gui/widgets/categorize.cpp
index cf29e267..0ce7646c 100644
--- a/source/gui/widgets/categorize.cpp
+++ b/source/gui/widgets/categorize.cpp
@@ -1,7 +1,7 @@
/*
* A Categorize Implementation
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -343,7 +343,7 @@ namespace nana
{
if(tree_.get_root()->child)
{
- tree_.clear();
+ tree_.clear(tree_.get_root());
return true;
}
return false;
diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp
index 02ba5649..78f842bc 100644
--- a/source/gui/widgets/menu.cpp
+++ b/source/gui/widgets/menu.cpp
@@ -747,7 +747,7 @@ namespace nana
//add a is_wd_parent_menu to determine whether the menu wants the focus.
//if a submenu gets the focus, the program may cause a crash error when the submenu is being destroyed
: base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald()),
- want_focus_{ (!wd) || ((!is_wd_parent_menu) && (API::focus_window() != wd)) },
+ want_focus_{ (!wd) || ((!is_wd_parent_menu) && (API::root(API::focus_window()) != API::root(wd))) },
event_focus_{ nullptr }
{
caption("nana menu window");
@@ -991,6 +991,12 @@ namespace nana
case keyboard::enter:
this->pick();
break;
+ case keyboard::escape:
+ //Leave sub menu. But if the sub menu doesn't exist,
+ //close the menu.
+ if (!this->submenu(false))
+ close();
+ break;
default:
if (2 != send_shortkey(arg.key))
{
@@ -1141,7 +1147,14 @@ namespace nana
throw std::out_of_range("menu: a new item inserted to an invalid position");
std::unique_ptr item{ new item_type{ std::move(text_utf8), handler } };
- impl_->mbuilder.data().items.emplace(impl_->mbuilder.data().items.cbegin() + pos, item.get());
+
+ items.emplace(
+#ifdef _MSC_VER
+ items.cbegin() + pos,
+#else
+ items.begin() + pos,
+#endif
+ item.get());
return item_proxy{ pos, *item.release() };
}
diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp
index ad85bd42..f77ec32c 100644
--- a/source/gui/widgets/skeletons/text_editor.cpp
+++ b/source/gui/widgets/skeletons/text_editor.cpp
@@ -2050,24 +2050,29 @@ namespace nana{ namespace widgets
void text_editor::paste()
{
- std::wstring text;
- nana::system::dataexch().get(text);
+ auto text = system::dataexch{}.wget();
//If it is required check the acceptable
- if (accepts::no_restrict != impl_->capacities.acceptive)
+ if ((accepts::no_restrict != impl_->capacities.acceptive) || impl_->capacities.pred_acceptive)
{
for (auto i = text.begin(); i != text.end(); ++i)
{
- if (!_m_accepts(*i))
+ if (_m_accepts(*i))
+ {
+ if (accepts::no_restrict == impl_->capacities.acceptive)
+ put(*i);
+
+ continue;
+ }
+
+ if (accepts::no_restrict != impl_->capacities.acceptive)
{
text.erase(i, text.end());
- break;
+ put(std::move(text));
}
+ break;
}
}
-
- if (!text.empty())
- put(std::move(text));
}
void text_editor::enter(bool record_undo)
@@ -2794,8 +2799,12 @@ namespace nana{ namespace widgets
bool text_editor::_m_accepts(char_type ch) const
{
- if(accepts::no_restrict == impl_->capacities.acceptive)
+ if (accepts::no_restrict == impl_->capacities.acceptive)
+ {
+ if (impl_->capacities.pred_acceptive)
+ return impl_->capacities.pred_acceptive(ch);
return true;
+ }
//Checks the input whether it meets the requirement for a numeric.
auto str = text();
diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp
index 9f63baa2..ca87855a 100644
--- a/source/gui/widgets/spinbox.cpp
+++ b/source/gui/widgets/spinbox.cpp
@@ -1,7 +1,7 @@
/*
* A Spin box widget
* Nana C++ Library(http://www.nanapro.org)
- * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
+ * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -295,13 +295,13 @@ namespace nana
return range_->value();
}
- bool value(const ::std::string& value_str)
+ bool value(const ::std::string& value_str, bool reset_editor)
{
bool diff;
if (!range_->value(value_str, diff))
return false;
- if (diff)
+ if (diff && reset_editor)
reset_text();
return true;
}
@@ -572,7 +572,7 @@ namespace nana
{
if (impl_->editor()->respond_char(arg))
{
- if (!impl_->value(to_utf8(impl_->editor()->text())))
+ if (!impl_->value(to_utf8(impl_->editor()->text()), false))
impl_->draw_spins();
API::dev::lazy_refresh();
@@ -657,7 +657,7 @@ namespace nana
internal_scope_guard lock;
if (handle())
{
- if (get_drawer_trigger().impl()->value(s))
+ if (get_drawer_trigger().impl()->value(s, true))
API::refresh_window(handle());
}
}
diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp
index c7aeba61..350a4210 100644
--- a/source/gui/widgets/treebox.cpp
+++ b/source/gui/widgets/treebox.cpp
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include