Merge branch 'develop'
This commit is contained in:
		
						commit
						719bceb616
					
				@ -36,9 +36,14 @@
 | 
				
			|||||||
 *	- STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8)
 | 
					 *	- STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8)
 | 
				
			||||||
 *	- STD_FILESYSTEM_NOT_SUPPORTED (GCC < 5.3) ....
 | 
					 *	- STD_FILESYSTEM_NOT_SUPPORTED (GCC < 5.3) ....
 | 
				
			||||||
 *	- CXX_NO_INLINE_NAMESPACE (Visual C++ < 2015)
 | 
					 *	- CXX_NO_INLINE_NAMESPACE (Visual C++ < 2015)
 | 
				
			||||||
 *	- _enable_std_make_unique (__cpluscplus < 201402)
 | 
					 *
 | 
				
			||||||
 *	- _enable_std_put_time (GCC < 5)
 | 
					 *	There are two kinds of flags:
 | 
				
			||||||
 *  - _enable_std_clamp (Visual C++ < 2017)
 | 
					 *	* _nana_std_xxx indicates that nana provides a standard-like class for workaround of lack of C++ support.
 | 
				
			||||||
 | 
					 *  * _nana_std_has_xxx indicates that nana detects whether a C++ feature is supported. Nana doesn't provide a standard-like class for this missing feature.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *	- _nana_std_make_unique (__cpluscplus < 201402)
 | 
				
			||||||
 | 
					 *	- _nana_std_put_time (GCC < 5)
 | 
				
			||||||
 | 
					 *  - _nana_std_clamp (Visual C++ < 2017)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef NANA_CXX_DEFINES_INCLUDED
 | 
					#ifndef NANA_CXX_DEFINES_INCLUDED
 | 
				
			||||||
@ -145,7 +150,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#	if ((__GNUC__ < 5)   )
 | 
					#	if ((__GNUC__ < 5)   )
 | 
				
			||||||
#		define _enable_std_put_time
 | 
					#		define _nana_std_put_time
 | 
				
			||||||
#	endif
 | 
					#	endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#   if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
 | 
					#   if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
 | 
				
			||||||
@ -189,20 +194,38 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//Detects the feature std::make_unique
 | 
					//Detects the feature std::make_unique
 | 
				
			||||||
//std::make_unique has been provided by Visual C++ 2013 and later
 | 
					//std::make_unique has been provided by Visual C++ 2013 and later
 | 
				
			||||||
#undef _enable_std_make_unique
 | 
					#undef _nana_std_make_unique
 | 
				
			||||||
#if (defined(__clang__) && (__cplusplus < 201305L || (__cplusplus == 201305L && (__clang_major__ * 100 + __clang_minor__ < 304 )))) \
 | 
					#if (defined(__clang__) && (__cplusplus < 201305L || (__cplusplus == 201305L && (__clang_major__ * 100 + __clang_minor__ < 304 )))) \
 | 
				
			||||||
	|| ((!defined(__clang__)) && defined(__GNUC__) && __cplusplus < 201300L)
 | 
						|| ((!defined(__clang__)) && defined(__GNUC__) && __cplusplus < 201300L)
 | 
				
			||||||
#	define _enable_std_make_unique
 | 
					#	define _nana_std_make_unique
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
//Detects the feature std::clamp
 | 
					//Detects the feature std::clamp
 | 
				
			||||||
//Visual C++ 2017 with /std:c++latest provides the std::clamp
 | 
					//Visual C++ 2017 with /std:c++latest provides the std::clamp
 | 
				
			||||||
#undef _enable_std_clamp
 | 
					#undef _nana_std_clamp
 | 
				
			||||||
#if (defined(_MSC_VER) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201403L))	\
 | 
					#if (defined(_MSC_VER) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201403L))	\
 | 
				
			||||||
	|| (defined(__clang__) && (__cplusplus < 201406L))						\
 | 
						|| (defined(__clang__) && (__cplusplus < 201406L))						\
 | 
				
			||||||
	|| (defined(__GNUC__) && (!defined(__clang__)) && (__cplusplus < 201703))
 | 
						|| (defined(__GNUC__) && (!defined(__clang__)) && (__cplusplus < 201703))
 | 
				
			||||||
#	define _enable_std_clamp
 | 
					#	define _nana_std_clamp
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef _nana_std_optional
 | 
				
			||||||
 | 
					#if ((defined(_MSC_VER) && (_MSC_VER >= 1912) && ((!defined(_MSVC_LANG)) || _MSVC_LANG < 201703))) ||	\
 | 
				
			||||||
 | 
						((__cplusplus < 201703L) || \
 | 
				
			||||||
 | 
							(defined(__clang__) && (__clang_major__ * 100 + __clang_minor__ < 400)) ||				\
 | 
				
			||||||
 | 
							(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 701))	\
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					#	define _nana_std_optional
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef _nana_std_has_string_view
 | 
				
			||||||
 | 
					#if ((defined(_MSC_VER) && (_MSC_VER >= 1912) && defined(_MSVC_LANG) && _MSVC_LANG >= 201703)) ||				\
 | 
				
			||||||
 | 
						((__cplusplus >= 201703L) && \
 | 
				
			||||||
 | 
							(defined(__clang__) && (__clang_major__ * 100 + __clang_minor__ >= 400) ||		\
 | 
				
			||||||
 | 
							(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 701))) \
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					#	define _nana_std_has_string_view
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	The Deploy Implementation
 | 
					 *	The Deploy Implementation
 | 
				
			||||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
					 *	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
 *	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -23,6 +23,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <stdexcept>
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
					#include <string_view>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nana
 | 
					namespace nana
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// move to *.h ??
 | 
						/// move to *.h ??
 | 
				
			||||||
@ -44,10 +48,15 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/// Checks whether a specified text is utf8 encoding
 | 
						/// Checks whether a specified text is utf8 encoding
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
						bool is_utf8(std::string_view str);
 | 
				
			||||||
 | 
						void throw_not_utf8(std::string_view str);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	bool is_utf8(const char* str, std::size_t len);
 | 
						bool is_utf8(const char* str, std::size_t len);
 | 
				
			||||||
	void throw_not_utf8(const std::string& text);
 | 
						void throw_not_utf8(const std::string& text);
 | 
				
			||||||
	void throw_not_utf8(const char*, std::size_t len);
 | 
						void throw_not_utf8(const char*, std::size_t len);
 | 
				
			||||||
	void throw_not_utf8(const char*);
 | 
						void throw_not_utf8(const char*);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// this text needed change, it needed review ??
 | 
						/// this text needed change, it needed review ??
 | 
				
			||||||
	bool review_utf8(const std::string& text);
 | 
						bool review_utf8(const std::string& text);
 | 
				
			||||||
@ -58,7 +67,12 @@ namespace nana
 | 
				
			|||||||
	const std::string& to_utf8(const std::string&);
 | 
						const std::string& to_utf8(const std::string&);
 | 
				
			||||||
	std::string to_utf8(const std::wstring&);
 | 
						std::string to_utf8(const std::wstring&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
						std::wstring to_wstring(std::string_view utf8_str);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	std::wstring to_wstring(const std::string& utf8_str);
 | 
						std::wstring to_wstring(const std::string& utf8_str);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const std::wstring& to_wstring(const std::wstring& wstr);
 | 
						const std::wstring& to_wstring(const std::wstring& wstr);
 | 
				
			||||||
	std::wstring&& to_wstring(std::wstring&& wstr);
 | 
						std::wstring&& to_wstring(std::wstring&& wstr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -134,10 +134,24 @@ namespace nana
 | 
				
			|||||||
		template<typename Function>
 | 
							template<typename Function>
 | 
				
			||||||
		event_handle connect_front(Function && fn)
 | 
							event_handle connect_front(Function && fn)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
					#ifdef __cpp_if_constexpr
 | 
				
			||||||
 | 
								if constexpr(std::is_invocable_v<Function, arg_reference>)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return _m_emplace(new docker{ this, fn, false }, true);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if constexpr(std::is_invocable_v<Function>)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return _m_emplace(new docker{ this, [fn](arg_reference) {
 | 
				
			||||||
 | 
										fn();
 | 
				
			||||||
 | 
									}, false }, true);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			using prototype = typename std::remove_reference<Function>::type;
 | 
								using prototype = typename std::remove_reference<Function>::type;
 | 
				
			||||||
			return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true);
 | 
								return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __cpp_if_constexpr
 | 
				
			||||||
		/// It will not get called if stop_propagation() was called.
 | 
							/// It will not get called if stop_propagation() was called.
 | 
				
			||||||
		event_handle connect(void (*fn)(arg_reference))
 | 
							event_handle connect(void (*fn)(arg_reference))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -145,13 +159,27 @@ namespace nana
 | 
				
			|||||||
				fn(arg);
 | 
									fn(arg);
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// It will not get called if stop_propagation() was called, because it is set at the end of the chain..
 | 
							/// It will not get called if stop_propagation() was called, because it is set at the end of the chain..
 | 
				
			||||||
		template<typename Function>
 | 
							template<typename Function>
 | 
				
			||||||
		event_handle connect(Function && fn)
 | 
							event_handle connect(Function && fn)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
					#ifdef __cpp_if_constexpr
 | 
				
			||||||
 | 
								if constexpr(std::is_invocable_v<Function, arg_reference>)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return _m_emplace(new docker{ this, fn, false }, false);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if constexpr(std::is_invocable_v<Function>)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return _m_emplace(new docker{ this, [fn](arg_reference){
 | 
				
			||||||
 | 
										fn();
 | 
				
			||||||
 | 
									}, false }, false);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			using prototype = typename std::remove_reference<Function>::type;
 | 
								using prototype = typename std::remove_reference<Function>::type;
 | 
				
			||||||
			return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false);
 | 
								return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// It will not get called if stop_propagation() was called.
 | 
							/// It will not get called if stop_propagation() was called.
 | 
				
			||||||
@ -165,9 +193,21 @@ namespace nana
 | 
				
			|||||||
        template<typename Function>
 | 
					        template<typename Function>
 | 
				
			||||||
		event_handle connect_unignorable(Function && fn, bool in_front = false)
 | 
							event_handle connect_unignorable(Function && fn, bool in_front = false)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
					#ifdef __cpp_if_constexpr
 | 
				
			||||||
 | 
								if constexpr(std::is_invocable_v<Function, arg_reference>)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return _m_emplace(new docker{ this, fn, true }, in_front);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if constexpr(std::is_invocable_v<Function>)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return _m_emplace(new docker{ this, [fn](arg_reference) {
 | 
				
			||||||
 | 
										fn();
 | 
				
			||||||
 | 
									}, true }, in_front);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			using prototype = typename std::remove_reference<Function>::type;
 | 
								using prototype = typename std::remove_reference<Function>::type;
 | 
				
			||||||
 | 
					 | 
				
			||||||
			return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), true), in_front);
 | 
								return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), true), in_front);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void emit(arg_reference& arg, window window_handle)
 | 
							void emit(arg_reference& arg, window window_handle)
 | 
				
			||||||
@ -210,6 +250,8 @@ namespace nana
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __cpp_if_constexpr
 | 
				
			||||||
		template<typename Fn, bool IsBind>
 | 
							template<typename Fn, bool IsBind>
 | 
				
			||||||
		struct factory
 | 
							struct factory
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -385,6 +427,7 @@ namespace nana
 | 
				
			|||||||
				};
 | 
									};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
	struct arg_mouse
 | 
						struct arg_mouse
 | 
				
			||||||
 | 
				
			|||||||
@ -35,7 +35,7 @@ namespace nana
 | 
				
			|||||||
			 * @param limit_width True if limits the width, false if limits the height.
 | 
								 * @param limit_width True if limits the width, false if limits the height.
 | 
				
			||||||
			 * @return the size of content.
 | 
								 * @return the size of content.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			virtual optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const = 0;
 | 
								virtual ::std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/// Returns the extension to the size of widget from content extent
 | 
								/// Returns the extension to the size of widget from content extent
 | 
				
			||||||
			/**
 | 
								/**
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 *	Filebox
 | 
					 *	Filebox
 | 
				
			||||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
					 *	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
 *	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -15,6 +15,7 @@
 | 
				
			|||||||
#ifndef NANA_GUI_FILEBOX_HPP
 | 
					#ifndef NANA_GUI_FILEBOX_HPP
 | 
				
			||||||
#define NANA_GUI_FILEBOX_HPP
 | 
					#define NANA_GUI_FILEBOX_HPP
 | 
				
			||||||
#include <nana/gui/basis.hpp>
 | 
					#include <nana/gui/basis.hpp>
 | 
				
			||||||
 | 
					#include <nana/filesystem/filesystem.hpp>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,5 +81,29 @@ namespace nana
 | 
				
			|||||||
	private:
 | 
						private:
 | 
				
			||||||
		implement * impl_;
 | 
							implement * impl_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						class folderbox
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct implement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							folderbox(const folderbox&) = delete;
 | 
				
			||||||
 | 
							folderbox& operator=(const folderbox&) = delete;
 | 
				
			||||||
 | 
							folderbox(folderbox&&) = delete;
 | 
				
			||||||
 | 
							folderbox& operator=(folderbox&&) = delete;
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							using path_type = std::experimental::filesystem::path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							folderbox(window owner = nullptr, const path_type& init_path = {});
 | 
				
			||||||
 | 
							~folderbox();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::optional<path_type> show() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::optional<path_type> operator()() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return show();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							implement* impl_;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
}//end namespace nana
 | 
					}//end namespace nana
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -240,7 +240,11 @@ namespace nana
 | 
				
			|||||||
		bool show(Args&& ... args)
 | 
							bool show(Args&& ... args)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			std::vector<abstract_content*> contents;
 | 
								std::vector<abstract_content*> contents;
 | 
				
			||||||
 | 
					#ifdef __cpp_fold_expressions
 | 
				
			||||||
 | 
								(contents.emplace_back(&args), ...);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			_m_fetch_args(contents, std::forward<Args>(args)...);
 | 
								_m_fetch_args(contents, std::forward<Args>(args)...);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			if (contents.empty())
 | 
								if (contents.empty())
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -270,6 +274,7 @@ namespace nana
 | 
				
			|||||||
		void min_width_entry_field( unsigned pixels );
 | 
							void min_width_entry_field( unsigned pixels );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
 | 
					#ifndef __cpp_fold_expressions
 | 
				
			||||||
		void _m_fetch_args(std::vector<abstract_content*>&);
 | 
							void _m_fetch_args(std::vector<abstract_content*>&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename ...Args>
 | 
							template<typename ...Args>
 | 
				
			||||||
@ -278,6 +283,7 @@ namespace nana
 | 
				
			|||||||
			contents.push_back(&content);
 | 
								contents.push_back(&content);
 | 
				
			||||||
			_m_fetch_args(contents, std::forward<Args>(args)...);
 | 
								_m_fetch_args(contents, std::forward<Args>(args)...);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool _m_open(std::vector<abstract_content*>&, bool modal);
 | 
							bool _m_open(std::vector<abstract_content*>&, bool modal);
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	An Implementation of Place for Layout
 | 
					 *	An Implementation of Place for Layout
 | 
				
			||||||
 *	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-2018 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
 | 
				
			||||||
@ -119,7 +119,7 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		void splitter_renderer(std::function<void(window, paint::graphics&, mouse_action)> fn);
 | 
							void splitter_renderer(std::function<void(window, paint::graphics&, mouse_action)> fn);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
		void div(const char* s);			///< Divides the attached widget into fields.
 | 
							void div(std::string div_text);			///< Divides the attached widget into fields.
 | 
				
			||||||
		const std::string& div() const noexcept;	///< Returns div-text that depends on fields status.
 | 
							const std::string& div() const noexcept;	///< Returns div-text that depends on fields status.
 | 
				
			||||||
		void modify(const char* field_name, const char* div_text);	///< Modifies a specified field.
 | 
							void modify(const char* field_name, const char* div_text);	///< Modifies a specified field.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -45,6 +45,15 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace API
 | 
					namespace API
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef NANA_X11
 | 
				
			||||||
 | 
						//Some platform specific functions for X11
 | 
				
			||||||
 | 
						namespace x11
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/// Returns the connection to the X server
 | 
				
			||||||
 | 
							const void* get_display();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	namespace detail
 | 
						namespace detail
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&&);
 | 
							::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&&);
 | 
				
			||||||
@ -80,7 +89,7 @@ namespace API
 | 
				
			|||||||
		void set_measurer(window, ::nana::dev::widget_content_measurer_interface*);
 | 
							void set_measurer(window, ::nana::dev::widget_content_measurer_interface*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void attach_drawer(widget&, drawer_trigger&);
 | 
							void attach_drawer(widget&, drawer_trigger&);
 | 
				
			||||||
		::nana::detail::native_string_type window_caption(window) throw();
 | 
							::nana::detail::native_string_type window_caption(window) noexcept;
 | 
				
			||||||
		void window_caption(window, ::nana::detail::native_string_type);
 | 
							void window_caption(window, ::nana::detail::native_string_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached);
 | 
							window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached);
 | 
				
			||||||
@ -110,6 +119,7 @@ namespace API
 | 
				
			|||||||
		void draw_shortkey_underline(paint::graphics&, const std::string& text, wchar_t shortkey, std::size_t shortkey_position, const point& text_pos, const color&);
 | 
							void draw_shortkey_underline(paint::graphics&, const std::string& text, wchar_t shortkey, std::size_t shortkey_position, const point& text_pos, const color&);
 | 
				
			||||||
	}//end namespace dev
 | 
						}//end namespace dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Returns the widget pointer of the specified window.
 | 
						/// Returns the widget pointer of the specified window.
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * @param window_handle A handle to a window owning the widget.
 | 
						 * @param window_handle A handle to a window owning the widget.
 | 
				
			||||||
@ -245,6 +255,19 @@ namespace API
 | 
				
			|||||||
		if (nullptr == general_evt)
 | 
							if (nullptr == general_evt)
 | 
				
			||||||
			throw std::invalid_argument("API::events(): bad parameter window handle, no events object or invalid window handle.");
 | 
								throw std::invalid_argument("API::events(): bad parameter window handle, no events object or invalid window handle.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cpp_if_constexpr
 | 
				
			||||||
 | 
							if constexpr(std::is_same_v<event_type, ::nana::general_events>)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return *general_evt;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto * widget_evt = dynamic_cast<event_type*>(general_evt);
 | 
				
			||||||
 | 
								if (nullptr == widget_evt)
 | 
				
			||||||
 | 
									throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match.");
 | 
				
			||||||
 | 
								return *widget_evt;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if (std::is_same<::nana::general_events, event_type>::value)
 | 
							if (std::is_same<::nana::general_events, event_type>::value)
 | 
				
			||||||
			return *static_cast<event_type*>(general_evt);
 | 
								return *static_cast<event_type*>(general_evt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -252,6 +275,7 @@ namespace API
 | 
				
			|||||||
		if (nullptr == widget_evt)
 | 
							if (nullptr == widget_evt)
 | 
				
			||||||
			throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match.");
 | 
								throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match.");
 | 
				
			||||||
		return *widget_evt;
 | 
							return *widget_evt;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::event_arg, EventArg>::value>::type* = nullptr>
 | 
						template<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::event_arg, EventArg>::value>::type* = nullptr>
 | 
				
			||||||
@ -278,6 +302,19 @@ namespace API
 | 
				
			|||||||
		if (nullptr == wdg_colors)
 | 
							if (nullptr == wdg_colors)
 | 
				
			||||||
			throw std::invalid_argument("API::scheme(): bad parameter window handle, no events object or invalid window handle.");
 | 
								throw std::invalid_argument("API::scheme(): bad parameter window handle, no events object or invalid window handle.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cpp_if_constexpr
 | 
				
			||||||
 | 
							if constexpr(std::is_same<::nana::widget_geometrics, scheme_type>::value)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return *static_cast<scheme_type*>(wdg_colors);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto * comp_wdg_colors = dynamic_cast<scheme_type*>(wdg_colors);
 | 
				
			||||||
 | 
								if (nullptr == comp_wdg_colors)
 | 
				
			||||||
 | 
									throw std::invalid_argument("API::scheme(): bad template parameter Widget, the widget type and window handle do not match.");
 | 
				
			||||||
 | 
								return *comp_wdg_colors;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if (std::is_same<::nana::widget_geometrics, scheme_type>::value)
 | 
							if (std::is_same<::nana::widget_geometrics, scheme_type>::value)
 | 
				
			||||||
			return *static_cast<scheme_type*>(wdg_colors);
 | 
								return *static_cast<scheme_type*>(wdg_colors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -285,6 +322,7 @@ namespace API
 | 
				
			|||||||
		if (nullptr == comp_wdg_colors)
 | 
							if (nullptr == comp_wdg_colors)
 | 
				
			||||||
			throw std::invalid_argument("API::scheme(): bad template parameter Widget, the widget type and window handle do not match.");
 | 
								throw std::invalid_argument("API::scheme(): bad template parameter Widget, the widget type and window handle do not match.");
 | 
				
			||||||
		return *comp_wdg_colors;
 | 
							return *comp_wdg_colors;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	point window_position(window);
 | 
						point window_position(window);
 | 
				
			||||||
@ -302,7 +340,7 @@ namespace API
 | 
				
			|||||||
	size window_outline_size(window);
 | 
						size window_outline_size(window);
 | 
				
			||||||
	void window_outline_size(window, const size&);
 | 
						void window_outline_size(window, const size&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nana::optional<rectangle> window_rectangle(window);
 | 
						::std::optional<rectangle> window_rectangle(window);
 | 
				
			||||||
	bool get_window_rectangle(window, rectangle&);
 | 
						bool get_window_rectangle(window, rectangle&);
 | 
				
			||||||
	bool track_window_size(window, const size&, bool true_for_max);   ///< Sets the minimum or maximum tracking size of a window.
 | 
						bool track_window_size(window, const size&, bool true_for_max);   ///< Sets the minimum or maximum tracking size of a window.
 | 
				
			||||||
	void window_enabled(window, bool);
 | 
						void window_enabled(window, bool);
 | 
				
			||||||
@ -424,7 +462,7 @@ namespace API
 | 
				
			|||||||
	bool ignore_mouse_focus(window, bool ignore);	///< Enables/disables the mouse focus, it returns the previous state
 | 
						bool ignore_mouse_focus(window, bool ignore);	///< Enables/disables the mouse focus, it returns the previous state
 | 
				
			||||||
	bool ignore_mouse_focus(window);				///< Determines whether the mouse focus is enabled
 | 
						bool ignore_mouse_focus(window);				///< Determines whether the mouse focus is enabled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void at_safe_place(window, std::function<void()>);
 | 
						void at_safe_place(window, ::std::function<void()>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Returns a widget content extent size
 | 
						/// Returns a widget content extent size
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@ -435,7 +473,7 @@ namespace API
 | 
				
			|||||||
	 * @return if optional has a value, the first size indicates the content extent, the second size indicates the size of
 | 
						 * @return if optional has a value, the first size indicates the content extent, the second size indicates the size of
 | 
				
			||||||
	 * widget by the content extent. 
 | 
						 * widget by the content extent. 
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width);
 | 
						::std::optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned screen_dpi(bool x_requested);
 | 
						unsigned screen_dpi(bool x_requested);
 | 
				
			||||||
}//end namespace API
 | 
					}//end namespace API
 | 
				
			||||||
 | 
				
			|||||||
@ -79,7 +79,9 @@ namespace drawerbase
 | 
				
			|||||||
		void element_set(const char* name);
 | 
							void element_set(const char* name);
 | 
				
			||||||
		void react(bool want);		///< Enables the reverse check while clicking on the checkbox.
 | 
							void react(bool want);		///< Enables the reverse check while clicking on the checkbox.
 | 
				
			||||||
		bool checked() const;
 | 
							bool checked() const;
 | 
				
			||||||
		void check(bool chk);
 | 
					
 | 
				
			||||||
 | 
							/// Checks/unchecks the checkbox
 | 
				
			||||||
 | 
							void check(bool state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// \brief With the radio mode, users make a choice among a set of mutually exclusive, 
 | 
							/// \brief With the radio mode, users make a choice among a set of mutually exclusive, 
 | 
				
			||||||
		/// related options. Users can choose one and only one option. 
 | 
							/// related options. Users can choose one and only one option. 
 | 
				
			||||||
 | 
				
			|||||||
@ -223,7 +223,7 @@ namespace nana
 | 
				
			|||||||
		const drawerbase::combox::drawer_impl& _m_impl() const;
 | 
							const drawerbase::combox::drawer_impl& _m_impl() const;
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		//Overrides widget's virtual functions
 | 
							//Overrides widget's virtual functions
 | 
				
			||||||
		native_string_type _m_caption() const throw() override;
 | 
							native_string_type _m_caption() const noexcept override;
 | 
				
			||||||
		void _m_caption(native_string_type&&) override;
 | 
							void _m_caption(native_string_type&&) override;
 | 
				
			||||||
		nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override;
 | 
							nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										36
									
								
								include/nana/gui/widgets/detail/widget_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								include/nana/gui/widgets/detail/widget_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *	A Widget Iterator Template
 | 
				
			||||||
 | 
					 *	Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *	Distributed under the Boost Software License, Version 1.0.
 | 
				
			||||||
 | 
					 *	(See accompanying file LICENSE_1_0.txt or copy at
 | 
				
			||||||
 | 
					 *	http://www.boost.org/LICENSE_1_0.txt)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *	@file: nana/gui/widgets/detail/widget_iterator.hpp
 | 
				
			||||||
 | 
					 *  @description: widget_iterator is the base class provided to simplify definitions of the required types for widget iterators.
 | 
				
			||||||
 | 
					 *	It is provided because of deprecation of std::iterator in C++17
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef NANA_GUI_WIDGET_ITERATOR_INCLUDED
 | 
				
			||||||
 | 
					#define NANA_GUI_WIDGET_ITERATOR_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef>	//provides std::ptrdiff_t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nana {
 | 
				
			||||||
 | 
						namespace widgets {
 | 
				
			||||||
 | 
							namespace detail
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								template<typename Category, typename T>
 | 
				
			||||||
 | 
								class widget_iterator
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									using iterator_category = Category;
 | 
				
			||||||
 | 
									using value_type = T;
 | 
				
			||||||
 | 
									using difference_type = std::ptrdiff_t;
 | 
				
			||||||
 | 
									using pointer = T * ;
 | 
				
			||||||
 | 
									using reference = T & ;
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@ -22,8 +22,20 @@
 | 
				
			|||||||
#include <nana/gui/widgets/checkbox.hpp>
 | 
					#include <nana/gui/widgets/checkbox.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nana{
 | 
					namespace nana{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						namespace drawerbase
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							namespace group
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								struct scheme : public nana::widget_geometrics
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									color_proxy border{ colors::gray_border };
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							}// end namespace panel
 | 
				
			||||||
 | 
						}//end namespace drawerbase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class group
 | 
						class group
 | 
				
			||||||
		: public panel<true>
 | 
							: public widget_object<category::widget_tag, drawerbase::panel::drawer, general_events, drawerbase::group::scheme>
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct implement;
 | 
							struct implement;
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
@ -53,6 +65,9 @@ namespace nana{
 | 
				
			|||||||
		/// Adds an option for user selection
 | 
							/// Adds an option for user selection
 | 
				
			||||||
		checkbox& add_option(::std::string);
 | 
							checkbox& add_option(::std::string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// Modifies the alignment of the title
 | 
				
			||||||
 | 
							void caption_align(align position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// Enables/disables the radio mode which is single selection
 | 
							/// Enables/disables the radio mode which is single selection
 | 
				
			||||||
		group& radio_mode(bool);
 | 
							group& radio_mode(bool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -83,7 +98,7 @@ namespace nana{
 | 
				
			|||||||
		void _m_add_child(const char* field, widget*);
 | 
							void _m_add_child(const char* field, widget*);
 | 
				
			||||||
		void _m_init();
 | 
							void _m_init();
 | 
				
			||||||
		void _m_complete_creation() override;
 | 
							void _m_complete_creation() override;
 | 
				
			||||||
		native_string_type _m_caption() const throw() override;
 | 
							native_string_type _m_caption() const noexcept override;
 | 
				
			||||||
		void _m_caption(native_string_type&&) override;
 | 
							void _m_caption(native_string_type&&) override;
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		std::unique_ptr<implement> impl_;
 | 
							std::unique_ptr<implement> impl_;
 | 
				
			||||||
 | 
				
			|||||||
@ -62,12 +62,12 @@ namespace nana
 | 
				
			|||||||
		label(window parent, const char* text, bool visible = true) :label(parent, std::string(text),visible) {};
 | 
							label(window parent, const char* text, bool visible = true) :label(parent, std::string(text),visible) {};
 | 
				
			||||||
		label(window, const rectangle& = {}, bool visible = true);
 | 
							label(window, const rectangle& = {}, bool visible = true);
 | 
				
			||||||
		label& transparent(bool);		///< Switchs the label widget to the transparent background mode.
 | 
							label& transparent(bool);		///< Switchs the label widget to the transparent background mode.
 | 
				
			||||||
		bool transparent() const throw();
 | 
							bool transparent() const noexcept;
 | 
				
			||||||
		label& format(bool);		///< Switches the format mode of the widget.
 | 
							label& format(bool);		///< Switches the format mode of the widget.
 | 
				
			||||||
		label& add_format_listener(std::function<void(command, const std::string&)>);
 | 
							label& add_format_listener(std::function<void(command, const std::string&)>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// as same as the HTML "for" attribute of a label
 | 
							/// as same as the HTML "for" attribute of a label
 | 
				
			||||||
		label& click_for(window associated_window) throw();
 | 
							label& click_for(window associated_window) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// Returns the size of the text. If *allowed_width_in_pixel* is not zero, returns a 
 | 
							/// Returns the size of the text. If *allowed_width_in_pixel* is not zero, returns a 
 | 
				
			||||||
		/// "corrected" size that changes lines to fit the text into the specified width
 | 
							/// "corrected" size that changes lines to fit the text into the specified width
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "widget.hpp"
 | 
					#include "widget.hpp"
 | 
				
			||||||
#include "detail/inline_widget.hpp"
 | 
					#include "detail/inline_widget.hpp"
 | 
				
			||||||
 | 
					#include "detail/widget_iterator.hpp"
 | 
				
			||||||
#include <nana/pat/abstract_factory.hpp>
 | 
					#include <nana/pat/abstract_factory.hpp>
 | 
				
			||||||
#include <nana/concepts.hpp>
 | 
					#include <nana/concepts.hpp>
 | 
				
			||||||
#include <nana/key_type.hpp>
 | 
					#include <nana/key_type.hpp>
 | 
				
			||||||
@ -808,7 +809,8 @@ namespace nana
 | 
				
			|||||||
			/// operate with absolute positions and contain only the position but montain pointers to parts of the real items 
 | 
								/// operate with absolute positions and contain only the position but montain pointers to parts of the real items 
 | 
				
			||||||
			/// item_proxy self, it references and iterators are not invalidated by sort()
 | 
								/// item_proxy self, it references and iterators are not invalidated by sort()
 | 
				
			||||||
			class item_proxy
 | 
								class item_proxy
 | 
				
			||||||
				: public std::iterator<std::input_iterator_tag, item_proxy>
 | 
									//: public std::iterator<std::input_iterator_tag, item_proxy>	//deprecated
 | 
				
			||||||
 | 
									: public ::nana::widgets::detail::widget_iterator<std::input_iterator_tag, item_proxy>
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			public:
 | 
								public:
 | 
				
			||||||
				item_proxy(essence*, const index_pair& = index_pair{npos, npos});
 | 
									item_proxy(essence*, const index_pair& = index_pair{npos, npos});
 | 
				
			||||||
@ -982,7 +984,8 @@ namespace nana
 | 
				
			|||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			class cat_proxy
 | 
								class cat_proxy
 | 
				
			||||||
				: public std::iterator < std::input_iterator_tag, cat_proxy >
 | 
									//: public std::iterator<std::input_iterator_tag, cat_proxy>	//deprecated
 | 
				
			||||||
 | 
									: public ::nana::widgets::detail::widget_iterator<std::input_iterator_tag, cat_proxy>
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			public:
 | 
								public:
 | 
				
			||||||
				using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;
 | 
									using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;
 | 
				
			||||||
@ -1215,9 +1218,6 @@ namespace nana
 | 
				
			|||||||
				unsigned suspension_width{ 8 };  ///<  def= . the trigger will set this to the width if ("...")
 | 
									unsigned suspension_width{ 8 };  ///<  def= . the trigger will set this to the width if ("...")
 | 
				
			||||||
				unsigned text_margin{ 5 };  ///<  def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1
 | 
									unsigned text_margin{ 5 };  ///<  def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//deprecated
 | 
					 | 
				
			||||||
				//unsigned header_height		{ 25   };  ///<  def=25 . header height   header_size
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				unsigned item_height_ex{ 6 };  ///< Set !=0 !!!!  def=6. item_height = text_height + item_height_ex
 | 
									unsigned item_height_ex{ 6 };  ///< Set !=0 !!!!  def=6. item_height = text_height + item_height_ex
 | 
				
			||||||
				unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO
 | 
									unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO
 | 
				
			||||||
				unsigned header_splitter_area_after{ 3 }; ///< def=3. But 4 is better...
 | 
									unsigned header_splitter_area_after{ 3 }; ///< def=3. But 4 is better...
 | 
				
			||||||
 | 
				
			|||||||
@ -116,7 +116,7 @@ namespace nana
 | 
				
			|||||||
		void modifier(std::string prefix_utf8, std::string suffix_utf8);
 | 
							void modifier(std::string prefix_utf8, std::string suffix_utf8);
 | 
				
			||||||
		void modifier(const std::wstring & prefix, const std::wstring& suffix);
 | 
							void modifier(const std::wstring & prefix, const std::wstring& suffix);
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		native_string_type _m_caption() const throw();
 | 
							native_string_type _m_caption() const noexcept;
 | 
				
			||||||
		void _m_caption(native_string_type&&);
 | 
							void _m_caption(native_string_type&&);
 | 
				
			||||||
	}; //end class spinbox
 | 
						}; //end class spinbox
 | 
				
			||||||
}//end namespace nana
 | 
					}//end namespace nana
 | 
				
			||||||
 | 
				
			|||||||
@ -383,7 +383,7 @@ namespace nana
 | 
				
			|||||||
					driver();
 | 
										driver();
 | 
				
			||||||
					~driver();
 | 
										~driver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					model* get_model() const throw();
 | 
										model* get_model() const noexcept;
 | 
				
			||||||
				private:
 | 
									private:
 | 
				
			||||||
					//Overrides drawer_trigger's method
 | 
										//Overrides drawer_trigger's method
 | 
				
			||||||
					void attached(widget_reference, graph_reference)	override;
 | 
										void attached(widget_reference, graph_reference)	override;
 | 
				
			||||||
 | 
				
			|||||||
@ -276,7 +276,7 @@ namespace nana
 | 
				
			|||||||
		std::size_t text_line_count() const noexcept;
 | 
							std::size_t text_line_count() const noexcept;
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		//Overrides widget's virtual functions
 | 
							//Overrides widget's virtual functions
 | 
				
			||||||
		native_string_type _m_caption() const throw() override;
 | 
							native_string_type _m_caption() const noexcept override;
 | 
				
			||||||
		void _m_caption(native_string_type&&) override;
 | 
							void _m_caption(native_string_type&&) override;
 | 
				
			||||||
		void _m_typeface(const paint::font&) override;
 | 
							void _m_typeface(const paint::font&) override;
 | 
				
			||||||
		std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override;
 | 
							std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override;
 | 
				
			||||||
 | 
				
			|||||||
@ -54,9 +54,9 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		window parent() const;
 | 
							window parent() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		::std::string caption() const throw();
 | 
							::std::string caption() const noexcept;
 | 
				
			||||||
		::std::wstring caption_wstring() const throw();
 | 
							::std::wstring caption_wstring() const noexcept;
 | 
				
			||||||
		native_string_type caption_native() const throw();
 | 
							native_string_type caption_native() const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		widget& caption(std::string utf8);
 | 
							widget& caption(std::string utf8);
 | 
				
			||||||
		widget& caption(std::wstring);
 | 
							widget& caption(std::wstring);
 | 
				
			||||||
@ -132,7 +132,7 @@ namespace nana
 | 
				
			|||||||
		virtual void _m_complete_creation();
 | 
							virtual void _m_complete_creation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual general_events& _m_get_general_events() const = 0;
 | 
							virtual general_events& _m_get_general_events() const = 0;
 | 
				
			||||||
		virtual native_string_type _m_caption() const throw();
 | 
							virtual native_string_type _m_caption() const noexcept;
 | 
				
			||||||
		virtual void _m_caption(native_string_type&&);
 | 
							virtual void _m_caption(native_string_type&&);
 | 
				
			||||||
		virtual nana::cursor _m_cursor() const;
 | 
							virtual nana::cursor _m_cursor() const;
 | 
				
			||||||
		virtual void _m_cursor(nana::cursor);
 | 
							virtual void _m_cursor(nana::cursor);
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,12 @@ namespace nana
 | 
				
			|||||||
		::std::string get(std::string msgid_utf8, Args&&... args) const
 | 
							::std::string get(std::string msgid_utf8, Args&&... args) const
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			std::vector<std::string> arg_strs;
 | 
								std::vector<std::string> arg_strs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cpp_fold_expressions
 | 
				
			||||||
 | 
								(_m_fetch_args(arg_strs, std::forward<Args>(args)),...);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			_m_fetch_args(arg_strs, std::forward<Args>(args)...);
 | 
								_m_fetch_args(arg_strs, std::forward<Args>(args)...);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			auto msgstr = _m_get(std::move(msgid_utf8));
 | 
								auto msgstr = _m_get(std::move(msgid_utf8));
 | 
				
			||||||
			_m_replace_args(msgstr, &arg_strs);
 | 
								_m_replace_args(msgstr, &arg_strs);
 | 
				
			||||||
@ -53,25 +58,28 @@ namespace nana
 | 
				
			|||||||
		std::string _m_get(std::string&& msgid) const;
 | 
							std::string _m_get(std::string&& msgid) const;
 | 
				
			||||||
		void _m_replace_args(::std::string& str, std::vector<::std::string> * arg_strs) const;
 | 
							void _m_replace_args(::std::string& str, std::vector<::std::string> * arg_strs) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>&) const; //Termination of _m_fetch_args
 | 
					#ifndef __cpp_fold_expressions
 | 
				
			||||||
 | 
							static void _m_fetch_args(std::vector<std::string>&); //Termination of _m_fetch_args
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, const char* arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, const char* arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, const std::string& arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, const std::string& arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, std::string& arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, std::string& arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, std::string&& arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, std::string&& arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, const wchar_t* arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, const wchar_t* arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, const std::wstring& arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, const std::wstring& arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, std::wstring& arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, std::wstring& arg);
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, std::wstring&& arg) const;
 | 
							static void _m_fetch_args(std::vector<std::string>& v, std::wstring&& arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename Arg>
 | 
							template<typename Arg>
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, Arg&& arg) const
 | 
							static void _m_fetch_args(std::vector<std::string>& v, Arg&& arg)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			std::stringstream ss;
 | 
								std::stringstream ss;
 | 
				
			||||||
			ss << arg;
 | 
								ss << arg;
 | 
				
			||||||
			v.emplace_back(ss.str());
 | 
								v.emplace_back(ss.str());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __cpp_fold_expressions
 | 
				
			||||||
		template<typename ...Args>
 | 
							template<typename ...Args>
 | 
				
			||||||
		void _m_fetch_args(std::vector<std::string>& v, const char* arg, Args&&... args) const
 | 
							void _m_fetch_args(std::vector<std::string>& v, const char* arg, Args&&... args) const
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -136,6 +144,7 @@ namespace nana
 | 
				
			|||||||
			v.emplace_back(ss.str());
 | 
								v.emplace_back(ss.str());
 | 
				
			||||||
			_m_fetch_args(v, std::forward<Args>(args)...);
 | 
								_m_fetch_args(v, std::forward<Args>(args)...);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	};//end class internationalization
 | 
						};//end class internationalization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class i18n_eval
 | 
						class i18n_eval
 | 
				
			||||||
@ -180,7 +189,11 @@ namespace nana
 | 
				
			|||||||
		i18n_eval(std::string msgid_utf8, Args&&... args)
 | 
							i18n_eval(std::string msgid_utf8, Args&&... args)
 | 
				
			||||||
			: msgid_(std::move(msgid_utf8))
 | 
								: msgid_(std::move(msgid_utf8))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
					#ifdef __cpp_fold_expressions
 | 
				
			||||||
 | 
								(_m_fetch_args(std::forward<Args>(args)), ...);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			_m_fetch_args(std::forward<Args>(args)...);
 | 
								_m_fetch_args(std::forward<Args>(args)...);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		i18n_eval(const i18n_eval&);
 | 
							i18n_eval(const i18n_eval&);
 | 
				
			||||||
@ -193,6 +206,7 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		std::string operator()() const;
 | 
							std::string operator()() const;
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
 | 
					#ifndef __cpp_fold_expressions
 | 
				
			||||||
		void _m_fetch_args(){}	//Termination of _m_fetch_args
 | 
							void _m_fetch_args(){}	//Termination of _m_fetch_args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename Arg, typename ...Args>
 | 
							template<typename Arg, typename ...Args>
 | 
				
			||||||
@ -201,6 +215,7 @@ namespace nana
 | 
				
			|||||||
			_m_add_args(std::forward<Arg>(arg));
 | 
								_m_add_args(std::forward<Arg>(arg));
 | 
				
			||||||
			_m_fetch_args(std::forward<Args>(args)...);
 | 
								_m_fetch_args(std::forward<Args>(args)...);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename Arg>
 | 
							template<typename Arg>
 | 
				
			||||||
		void _m_add_args(Arg&& arg)
 | 
							void _m_add_args(Arg&& arg)
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,13 @@
 | 
				
			|||||||
#ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED
 | 
					#ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED
 | 
				
			||||||
#define NANA_STD_OPTIONAL_HEADER_INCLUDED
 | 
					#define NANA_STD_OPTIONAL_HEADER_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdexcept>
 | 
					 | 
				
			||||||
#include <nana/c++defines.hpp>
 | 
					#include <nana/c++defines.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _nana_std_optional
 | 
				
			||||||
 | 
					#include <optional>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nana
 | 
					namespace nana
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	namespace detail
 | 
						namespace detail
 | 
				
			||||||
@ -361,4 +366,10 @@ namespace nana
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace std
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						using nana::optional;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif	//_nana_std_optional
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	Platform Implementation
 | 
					 *	Platform Implementation
 | 
				
			||||||
 *	Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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 
 | 
				
			||||||
@ -32,8 +32,11 @@ namespace detail
 | 
				
			|||||||
	//dw color = dw color * fade_rate + bdcolor * (1 - fade_rate)
 | 
						//dw color = dw color * fade_rate + bdcolor * (1 - fade_rate)
 | 
				
			||||||
	void blend(drawable_type dw, const nana::rectangle& r, pixel_color_t bdcolor, double fade_rate);
 | 
						void blend(drawable_type dw, const nana::rectangle& r, pixel_color_t bdcolor, double fade_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nana::size raw_text_extent_size(drawable_type, const wchar_t*, std::size_t len);
 | 
						nana::size real_text_extent_size(drawable_type, const char*, std::size_t len);
 | 
				
			||||||
 | 
						nana::size real_text_extent_size(drawable_type, const wchar_t*, std::size_t len);
 | 
				
			||||||
 | 
						nana::size text_extent_size(drawable_type, const char*, std::size_t len);
 | 
				
			||||||
	nana::size text_extent_size(drawable_type, const wchar_t*, std::size_t len);
 | 
						nana::size text_extent_size(drawable_type, const wchar_t*, std::size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void draw_string(drawable_type, const nana::point&, const wchar_t *, std::size_t len);
 | 
						void draw_string(drawable_type, const nana::point&, const wchar_t *, std::size_t len);
 | 
				
			||||||
}//end namespace detail
 | 
					}//end namespace detail
 | 
				
			||||||
}//end namespace paint
 | 
					}//end namespace paint
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	Paint Graphics Implementation
 | 
					 *	Paint Graphics Implementation
 | 
				
			||||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
					 *	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
 *	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -21,6 +21,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "detail/ptdefs.hpp"
 | 
					#include "detail/ptdefs.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
					#include <string_view>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nana
 | 
					namespace nana
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	namespace paint
 | 
						namespace paint
 | 
				
			||||||
@ -108,17 +112,40 @@ namespace nana
 | 
				
			|||||||
			void resize(const ::nana::size&);
 | 
								void resize(const ::nana::size&);
 | 
				
			||||||
			void typeface(const font&);						///< Selects a specified font type into the graphics object.
 | 
								void typeface(const font&);						///< Selects a specified font type into the graphics object.
 | 
				
			||||||
			font typeface() const;
 | 
								font typeface() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								::nana::size text_extent_size(std::string_view text) const;
 | 
				
			||||||
 | 
								::nana::size text_extent_size(std::wstring_view text) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								///Only supports the wide string, because it is very hard to specify the begin and end position in a UTF-8 string.
 | 
				
			||||||
 | 
								::nana::size glyph_extent_size(std::wstring_view text, std::size_t begin, std::size_t end) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/// Returns a buffer which stores the pixel of each charater stored in text.
 | 
				
			||||||
 | 
								/**
 | 
				
			||||||
 | 
								 * @param text The text to be requested.
 | 
				
			||||||
 | 
								 * @return A buffer which stores the pixel of each character stored in text, its length is same with text's length. If text is empty, it returns a buffer with a senseless value.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								std::unique_ptr<unsigned[]> glyph_pixels(std::wstring_view text) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								::nana::size	bidi_extent_size(std::string_view utf8_text) const;
 | 
				
			||||||
 | 
								::nana::size	bidi_extent_size(std::wstring_view text) const;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			::nana::size	text_extent_size(const ::std::string&) const;
 | 
								::nana::size	text_extent_size(const ::std::string&) const;
 | 
				
			||||||
			::nana::size	text_extent_size(const char*, std::size_t len) const;
 | 
								::nana::size	text_extent_size(const char*, std::size_t len) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			::nana::size	text_extent_size(const wchar_t*) const;    ///< Computes the width and height of the specified string of text.
 | 
								::nana::size	text_extent_size(const wchar_t*) const;    ///< Computes the width and height of the specified string of text.
 | 
				
			||||||
			::nana::size	text_extent_size(const ::std::wstring&) const;    ///< Computes the width and height of the specified string of text.
 | 
								::nana::size	text_extent_size(const ::std::wstring&) const;    ///< Computes the width and height of the specified string of text.
 | 
				
			||||||
			::nana::size	text_extent_size(const wchar_t*, std::size_t length) const;    ///< Computes the width and height of the specified string of text with the specified length.
 | 
								::nana::size	text_extent_size(const wchar_t*, std::size_t length) const;    ///< Computes the width and height of the specified string of text with the specified length.
 | 
				
			||||||
			::nana::size	text_extent_size(const ::std::wstring&, std::size_t length) const;    ///< Computes the width and height of the specified string of text with the specified length.
 | 
								::nana::size	text_extent_size(const ::std::wstring&, std::size_t length) const;    ///< Computes the width and height of the specified string of text with the specified length.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			::nana::size	glyph_extent_size(const wchar_t*, std::size_t length, std::size_t begin, std::size_t end) const;
 | 
								::nana::size	glyph_extent_size(const wchar_t*, std::size_t length, std::size_t begin, std::size_t end) const;
 | 
				
			||||||
			::nana::size	glyph_extent_size(const ::std::wstring&, std::size_t length, std::size_t begin, std::size_t end) const;
 | 
								::nana::size	glyph_extent_size(const ::std::wstring&, std::size_t length, std::size_t begin, std::size_t end) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool glyph_pixels(const wchar_t *, std::size_t length, unsigned* pxbuf) const;
 | 
								bool glyph_pixels(const wchar_t *, std::size_t length, unsigned* pxbuf) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			::nana::size	bidi_extent_size(const std::wstring&) const;
 | 
								::nana::size	bidi_extent_size(const std::wstring&) const;
 | 
				
			||||||
			::nana::size	bidi_extent_size(const std::string&) const;
 | 
								::nana::size	bidi_extent_size(const std::string&) const;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool text_metrics(unsigned & ascent, unsigned& descent, unsigned& internal_leading) const;
 | 
								bool text_metrics(unsigned & ascent, unsigned& descent, unsigned& internal_leading) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -156,17 +183,27 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			/// Saves images as a windows bitmap file
 | 
								/// Saves images as a windows bitmap file
 | 
				
			||||||
			/// @param file_utf8 A UTF-8 string to a filename
 | 
								/// @param file_utf8 A UTF-8 string to a filename
 | 
				
			||||||
			void save_as_file(const char* file_utf8) const throw();
 | 
								void save_as_file(const char* file_utf8) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			::nana::color	palette(bool for_text) const;
 | 
								::nana::color	palette(bool for_text) const;
 | 
				
			||||||
			graphics&		palette(bool for_text, const ::nana::color&);
 | 
								graphics&		palette(bool for_text, const ::nana::color&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			unsigned bidi_string(const nana::point&, const wchar_t *, std::size_t len);
 | 
					 | 
				
			||||||
			unsigned bidi_string(const point& pos, const char*, std::size_t len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			void set_pixel(int x, int y, const ::nana::color&);
 | 
								void set_pixel(int x, int y, const ::nana::color&);
 | 
				
			||||||
			void set_pixel(int x, int y);
 | 
								void set_pixel(int x, int y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								unsigned bidi_string(const point&, std::string_view utf8str);
 | 
				
			||||||
 | 
								unsigned bidi_string(const point& pos, std::wstring_view str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								void string(const point&, std::string_view utf8str);
 | 
				
			||||||
 | 
								void string(const point&, std::string_view utf8str, const nana::color&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								void string(const point&, std::wstring_view str);
 | 
				
			||||||
 | 
								void string(const point&, std::wstring_view str, const nana::color&);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
								unsigned bidi_string(const nana::point&, const wchar_t *, std::size_t len);
 | 
				
			||||||
 | 
								unsigned bidi_string(const point& pos, const char*, std::size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			void string(const point&, const std::string& text_utf8);
 | 
								void string(const point&, const std::string& text_utf8);
 | 
				
			||||||
			void string(const point&, const std::string& text_utf8, const color&);
 | 
								void string(const point&, const std::string& text_utf8, const color&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -174,6 +211,7 @@ namespace nana
 | 
				
			|||||||
			void string(const point&, const wchar_t*);
 | 
								void string(const point&, const wchar_t*);
 | 
				
			||||||
			void string(const point&, const ::std::wstring&);
 | 
								void string(const point&, const ::std::wstring&);
 | 
				
			||||||
			void string(const point&, const ::std::wstring&, const color&);
 | 
								void string(const point&, const ::std::wstring&, const color&);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			void line(const point&, const point&);
 | 
								void line(const point&, const point&);
 | 
				
			||||||
			void line(const point&, const point&, const color&);
 | 
								void line(const point&, const point&, const color&);
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,7 @@ namespace std
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _enable_std_make_unique
 | 
					#ifdef _nana_std_make_unique
 | 
				
			||||||
	// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
 | 
						// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstddef>
 | 
					#include <cstddef>
 | 
				
			||||||
@ -124,9 +124,9 @@ namespace std {
 | 
				
			|||||||
	typename _Unique_if<T>::_Known_bound
 | 
						typename _Unique_if<T>::_Known_bound
 | 
				
			||||||
		make_unique(Args&&...) = delete;
 | 
							make_unique(Args&&...) = delete;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif //_enable_std_make_unique
 | 
					#endif //_nana_std_make_unique
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _enable_std_put_time
 | 
					#ifdef _nana_std_put_time
 | 
				
			||||||
#include <ctime>
 | 
					#include <ctime>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
namespace std
 | 
					namespace std
 | 
				
			||||||
@ -144,9 +144,9 @@ namespace std
 | 
				
			|||||||
	//template<>
 | 
						//template<>
 | 
				
			||||||
	//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
 | 
						//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif  // _enable_std_put_time
 | 
					#endif  // _nana_std_put_time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_enable_std_clamp)
 | 
					#if defined(_nana_std_clamp)
 | 
				
			||||||
namespace std
 | 
					namespace std
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	//<algorithm> since C++17
 | 
						//<algorithm> since C++17
 | 
				
			||||||
 | 
				
			|||||||
@ -80,7 +80,7 @@
 | 
				
			|||||||
	#pragma message (  SHOW_VALUE(USE_github_com_meganz_mingw_std_threads)  )
 | 
						#pragma message (  SHOW_VALUE(USE_github_com_meganz_mingw_std_threads)  )
 | 
				
			||||||
	#pragma message (  SHOW_VALUE(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)  )
 | 
						#pragma message (  SHOW_VALUE(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)  )
 | 
				
			||||||
	#pragma message (  SHOW_VALUE(STD_THREAD_NOT_SUPPORTED)  )
 | 
						#pragma message (  SHOW_VALUE(STD_THREAD_NOT_SUPPORTED)  )
 | 
				
			||||||
	#pragma message (  SHOW_VALUE(_enable_std_put_time)  )
 | 
						#pragma message (  SHOW_VALUE(_nana_std_put_time)  )
 | 
				
			||||||
	#pragma message (  SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED)  )
 | 
						#pragma message (  SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED)  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#pragma message (  SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED)  )
 | 
						#pragma message (  SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED)  )
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ namespace nana{namespace audio
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			bool audio_device::empty() const
 | 
								bool audio_device::empty() const
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
#if defined(NANA_POSIX) && not defined(NANA_LINUX)
 | 
					#if defined(NANA_POSIX) && !defined(NANA_LINUX)
 | 
				
			||||||
				return (-1 == handle_);
 | 
									return (-1 == handle_);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
				return (nullptr == handle_);
 | 
									return (nullptr == handle_);
 | 
				
			||||||
@ -305,7 +305,7 @@ namespace nana{namespace audio
 | 
				
			|||||||
}//end namespace audio
 | 
					}//end namespace audio
 | 
				
			||||||
}//end namespace nana
 | 
					}//end namespace nana
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(NANA_POSIX) && not defined(NANA_LINUX)
 | 
					#if defined(NANA_POSIX) && !defined(NANA_LINUX)
 | 
				
			||||||
// parse input securely, no-overruns or overflows.
 | 
					// parse input securely, no-overruns or overflows.
 | 
				
			||||||
static bool match(char *&cursor, const char *pattern, const char *tail)
 | 
					static bool match(char *&cursor, const char *pattern, const char *tail)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,42 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace nana
 | 
					namespace nana
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
						bool is_utf8(std::string_view str)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto ustr = reinterpret_cast<const unsigned char*>(str.data());
 | 
				
			||||||
 | 
							auto end = ustr + str.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while (ustr < end)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								const auto uv = *ustr;
 | 
				
			||||||
 | 
								if (uv < 0x80)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									++ustr;
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (uv < 0xC0)
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((uv < 0xE0) && (end - ustr > 1))
 | 
				
			||||||
 | 
									ustr += 2;
 | 
				
			||||||
 | 
								else if ((uv < 0xF0) && (end - ustr > 2))
 | 
				
			||||||
 | 
									ustr += 3;
 | 
				
			||||||
 | 
								else if ((uv < 0x1F) && (end - ustr > 3))
 | 
				
			||||||
 | 
									ustr += 4;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void throw_not_utf8(std::string_view str)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!is_utf8(str))
 | 
				
			||||||
 | 
								return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(str.data(), str.size())).emit();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	bool is_utf8(const char* str, std::size_t len)
 | 
						bool is_utf8(const char* str, std::size_t len)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto ustr = reinterpret_cast<const unsigned char*>(str);
 | 
							auto ustr = reinterpret_cast<const unsigned char*>(str);
 | 
				
			||||||
@ -57,6 +93,23 @@ namespace nana
 | 
				
			|||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void throw_not_utf8(const std::string& text)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							throw_not_utf8(text.c_str(), text.size());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void throw_not_utf8(const char* text)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							throw_not_utf8(text, std::strlen(text));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void throw_not_utf8(const char* text, std::size_t len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!is_utf8(text, len))
 | 
				
			||||||
 | 
								return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len)).emit();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//class utf8_Error
 | 
						//class utf8_Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_MSC_VER)
 | 
					#if defined(_MSC_VER)
 | 
				
			||||||
@ -79,22 +132,6 @@ namespace nana
 | 
				
			|||||||
	bool utf8_Error::use_throw{ false };
 | 
						bool utf8_Error::use_throw{ false };
 | 
				
			||||||
	//end class utf8_Error
 | 
						//end class utf8_Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void throw_not_utf8(const std::string& text)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		throw_not_utf8(text.c_str(), text.size());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void throw_not_utf8(const char* text)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		throw_not_utf8(text, std::strlen(text));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void throw_not_utf8(const char* text, std::size_t len)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (!is_utf8(text, len))
 | 
					 | 
				
			||||||
			return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	std::string recode_to_utf8(std::string no_utf8)
 | 
						std::string recode_to_utf8(std::string no_utf8)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return nana::charset(std::move(no_utf8)).to_bytes(nana::unicode::utf8);
 | 
							return nana::charset(std::move(no_utf8)).to_bytes(nana::unicode::utf8);
 | 
				
			||||||
@ -103,7 +140,11 @@ namespace nana
 | 
				
			|||||||
	/// this text needed change, it needed review ??
 | 
						/// this text needed change, it needed review ??
 | 
				
			||||||
	bool review_utf8(const std::string& text)
 | 
						bool review_utf8(const std::string& text)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
							if (!is_utf8(text))
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if (!is_utf8(text.c_str(), text.length()))
 | 
							if (!is_utf8(text.c_str(), text.length()))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			utf8_Error(std::string("\nThe const text is not encoded in UTF8: ") + text).emit();
 | 
								utf8_Error(std::string("\nThe const text is not encoded in UTF8: ") + text).emit();
 | 
				
			||||||
			return true;   /// it needed change, it needed review !!
 | 
								return true;   /// it needed change, it needed review !!
 | 
				
			||||||
@ -115,7 +156,11 @@ namespace nana
 | 
				
			|||||||
	/// this text needed change, it needed review ??
 | 
						/// this text needed change, it needed review ??
 | 
				
			||||||
	bool review_utf8(std::string& text)
 | 
						bool review_utf8(std::string& text)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
							if(!is_utf8(text))
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if (!is_utf8(text.c_str(), text.length()))
 | 
							if (!is_utf8(text.c_str(), text.length()))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
 | 
								utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
 | 
				
			||||||
			text=recode_to_utf8(text);
 | 
								text=recode_to_utf8(text);
 | 
				
			||||||
@ -135,10 +180,21 @@ namespace nana
 | 
				
			|||||||
		return ::nana::charset(text).to_bytes(::nana::unicode::utf8);
 | 
							return ::nana::charset(text).to_bytes(::nana::unicode::utf8);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
						std::wstring to_wstring(std::string_view utf8_str)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (utf8_str.empty())
 | 
				
			||||||
 | 
								return{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return ::nana::charset(std::string{ utf8_str.data(), utf8_str.size() }, unicode::utf8);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	std::wstring to_wstring(const std::string& utf8_str)
 | 
						std::wstring to_wstring(const std::string& utf8_str)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return ::nana::charset(utf8_str, ::nana::unicode::utf8);
 | 
							return ::nana::charset(utf8_str, ::nana::unicode::utf8);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const std::wstring& to_wstring(const std::wstring& wstr)
 | 
						const std::wstring& to_wstring(const std::wstring& wstr)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@
 | 
				
			|||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nana/config.hpp>
 | 
					#include <nana/config.hpp>
 | 
				
			||||||
#ifdef _enable_std_put_time
 | 
					#ifdef _nana_std_put_time
 | 
				
			||||||
	#include <nana/stdc++.hpp>
 | 
						#include <nana/stdc++.hpp>
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	#include <iomanip>
 | 
						#include <iomanip>
 | 
				
			||||||
 | 
				
			|||||||
@ -911,12 +911,19 @@ namespace detail
 | 
				
			|||||||
			case Expose:
 | 
								case Expose:
 | 
				
			||||||
				if(msgwnd->visible && (msgwnd->root_graph->empty() == false))
 | 
									if(msgwnd->visible && (msgwnd->root_graph->empty() == false))
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					nana::detail::platform_scope_guard psg;
 | 
										nana::detail::platform_scope_guard lock;
 | 
				
			||||||
 | 
										if(msgwnd->is_draw_through())
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											msgwnd->other.attribute.root->draw_through();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
						//Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed.
 | 
											//Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed.
 | 
				
			||||||
						::nana::rectangle update_area(xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.width, xevent.xexpose.height);
 | 
											::nana::rectangle update_area(xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.width, xevent.xexpose.height);
 | 
				
			||||||
						if (!update_area.empty())
 | 
											if (!update_area.empty())
 | 
				
			||||||
							msgwnd->drawer.map(reinterpret_cast<window>(msgwnd), true, &update_area);
 | 
												msgwnd->drawer.map(reinterpret_cast<window>(msgwnd), true, &update_area);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case KeyPress:
 | 
								case KeyPress:
 | 
				
			||||||
				nana::detail::platform_spec::instance().write_keystate(xevent.xkey);
 | 
									nana::detail::platform_spec::instance().write_keystate(xevent.xkey);
 | 
				
			||||||
@ -1142,13 +1149,12 @@ namespace detail
 | 
				
			|||||||
							    {
 | 
												    {
 | 
				
			||||||
									msgwnd->set_action(mouse_action::normal);
 | 
														msgwnd->set_action(mouse_action::normal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
														auto retain = msgwnd->annex.events_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									arg_click click_arg;
 | 
														arg_click click_arg;
 | 
				
			||||||
									click_arg.mouse_args = nullptr;
 | 
														click_arg.mouse_args = nullptr;
 | 
				
			||||||
									click_arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
														click_arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
								    auto retain = msgwnd->annex.events_ptr;
 | 
					 | 
				
			||||||
								    if (brock.emit(event_code::click, msgwnd, click_arg, true, &context))
 | 
					 | 
				
			||||||
							    	{
 | 
					 | 
				
			||||||
									arg_mouse arg;
 | 
														arg_mouse arg;
 | 
				
			||||||
									arg.alt = false;
 | 
														arg.alt = false;
 | 
				
			||||||
									arg.button = ::nana::mouse::left_button;
 | 
														arg.button = ::nana::mouse::left_button;
 | 
				
			||||||
@ -1161,8 +1167,10 @@ namespace detail
 | 
				
			|||||||
									arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
														arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
 | 
														draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
														if (brock.emit(event_code::click, msgwnd, click_arg, true, &context))
 | 
				
			||||||
										wd_manager.do_lazy_refresh(msgwnd, false);
 | 
															wd_manager.do_lazy_refresh(msgwnd, false);
 | 
				
			||||||
								    }
 | 
														
 | 
				
			||||||
									pressed_wd_space = nullptr;
 | 
														pressed_wd_space = nullptr;
 | 
				
			||||||
							    }
 | 
												    }
 | 
				
			||||||
							    else
 | 
												    else
 | 
				
			||||||
 | 
				
			|||||||
@ -408,16 +408,7 @@ namespace detail
 | 
				
			|||||||
							if (msg.message == WM_QUIT)   break;
 | 
												if (msg.message == WM_QUIT)   break;
 | 
				
			||||||
							if ((WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) || !::IsDialogMessage(native_handle, &msg))
 | 
												if ((WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) || !::IsDialogMessage(native_handle, &msg))
 | 
				
			||||||
							{
 | 
												{
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
								auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
 | 
					 | 
				
			||||||
								if (menu_wd) interior_helper_for_menu(msg, menu_wd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
								::TranslateMessage(&msg);	//deprecated
 | 
					 | 
				
			||||||
								::DispatchMessage(&msg);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
								process_msg(this, msg);
 | 
													process_msg(this, msg);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
								wd_manager().remove_trash_handle(tid);
 | 
													wd_manager().remove_trash_handle(tid);
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
@ -429,15 +420,7 @@ namespace detail
 | 
				
			|||||||
					{
 | 
										{
 | 
				
			||||||
						if (-1 != ::GetMessage(&msg, 0, 0, 0))
 | 
											if (-1 != ::GetMessage(&msg, 0, 0, 0))
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
							auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
 | 
					 | 
				
			||||||
							if (menu_wd) interior_helper_for_menu(msg, menu_wd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							::TranslateMessage(&msg);
 | 
					 | 
				
			||||||
							::DispatchMessage(&msg);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
							process_msg(this, msg);
 | 
												process_msg(this, msg);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						wd_manager().call_safe_place(tid);
 | 
											wd_manager().call_safe_place(tid);
 | 
				
			||||||
@ -452,17 +435,7 @@ namespace detail
 | 
				
			|||||||
				while(context->window_count)
 | 
									while(context->window_count)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					if(-1 != ::GetMessage(&msg, 0, 0, 0))
 | 
										if(-1 != ::GetMessage(&msg, 0, 0, 0))
 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
						auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
 | 
					 | 
				
			||||||
						if(menu_wd) interior_helper_for_menu(msg, menu_wd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						::TranslateMessage(&msg);
 | 
					 | 
				
			||||||
						::DispatchMessage(&msg);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
						process_msg(this, msg);
 | 
											process_msg(this, msg);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					wd_manager().call_safe_place(tid);
 | 
										wd_manager().call_safe_place(tid);
 | 
				
			||||||
					wd_manager().remove_trash_handle(tid);
 | 
										wd_manager().remove_trash_handle(tid);
 | 
				
			||||||
@ -1522,13 +1495,12 @@ namespace detail
 | 
				
			|||||||
							{
 | 
												{
 | 
				
			||||||
								msgwnd->set_action(mouse_action::normal);
 | 
													msgwnd->set_action(mouse_action::normal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
													auto retain = msgwnd->annex.events_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
								arg_click click_arg;
 | 
													arg_click click_arg;
 | 
				
			||||||
								click_arg.mouse_args = nullptr;
 | 
													click_arg.mouse_args = nullptr;
 | 
				
			||||||
								click_arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
													click_arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
								auto retain = msgwnd->annex.events_ptr;
 | 
					 | 
				
			||||||
								if (brock.emit(event_code::click, msgwnd, click_arg, true, &context))
 | 
					 | 
				
			||||||
								{
 | 
					 | 
				
			||||||
								arg_mouse arg;
 | 
													arg_mouse arg;
 | 
				
			||||||
								arg.alt = false;
 | 
													arg.alt = false;
 | 
				
			||||||
								arg.button = ::nana::mouse::left_button;
 | 
													arg.button = ::nana::mouse::left_button;
 | 
				
			||||||
@ -1541,19 +1513,22 @@ namespace detail
 | 
				
			|||||||
								arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
													arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
								draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
 | 
													draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
													if (brock.emit(event_code::click, msgwnd, click_arg, true, &context))
 | 
				
			||||||
									wd_manager.do_lazy_refresh(msgwnd, false);
 | 
														wd_manager.do_lazy_refresh(msgwnd, false);
 | 
				
			||||||
								}
 | 
													
 | 
				
			||||||
								pressed_wd_space = nullptr;
 | 
													pressed_wd_space = nullptr;
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							else
 | 
												else
 | 
				
			||||||
							{
 | 
												{
 | 
				
			||||||
								arg_keyboard arg;
 | 
													arg_keyboard keyboard_arg;
 | 
				
			||||||
								arg.evt_code = event_code::key_release;
 | 
													keyboard_arg.evt_code = event_code::key_release;
 | 
				
			||||||
								arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
													keyboard_arg.window_handle = reinterpret_cast<window>(msgwnd);
 | 
				
			||||||
								arg.key = translate_virtual_key(wParam);
 | 
													keyboard_arg.key = translate_virtual_key(wParam);
 | 
				
			||||||
								brock.get_key_state(arg);
 | 
													brock.get_key_state(keyboard_arg);
 | 
				
			||||||
								arg.ignore = false;
 | 
													keyboard_arg.ignore = false;
 | 
				
			||||||
								brock.emit(event_code::key_release, msgwnd, arg, true, &context);
 | 
					
 | 
				
			||||||
 | 
													brock.emit(event_code::key_release, msgwnd, keyboard_arg, true, &context);
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
*	Filebox
 | 
					*	Filebox
 | 
				
			||||||
*	Nana C++ Library(http://www.nanapro.org)
 | 
					*	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
*	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					*	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -16,6 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if defined(NANA_WINDOWS)
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
#	include <windows.h>
 | 
					#	include <windows.h>
 | 
				
			||||||
 | 
					#	include <Shobjidl.h>
 | 
				
			||||||
#elif defined(NANA_POSIX)
 | 
					#elif defined(NANA_POSIX)
 | 
				
			||||||
#	include <nana/gui/widgets/label.hpp>
 | 
					#	include <nana/gui/widgets/label.hpp>
 | 
				
			||||||
#	include <nana/gui/widgets/button.hpp>
 | 
					#	include <nana/gui/widgets/button.hpp>
 | 
				
			||||||
@ -130,6 +131,13 @@ namespace nana
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
 | 
							enum class mode
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								open_file,	//choose an existing file.
 | 
				
			||||||
 | 
								write_file, //choose a filename, it can be specified a new filename which doesn't exist.
 | 
				
			||||||
 | 
								open_directory, //choose an existing directory.
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct kind
 | 
							struct kind
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			enum t{none, filesystem};
 | 
								enum t{none, filesystem};
 | 
				
			||||||
@ -138,8 +146,10 @@ namespace nana
 | 
				
			|||||||
		typedef treebox::item_proxy item_proxy;
 | 
							typedef treebox::item_proxy item_proxy;
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		filebox_implement(window owner, bool io_read, const std::string& title)
 | 
							filebox_implement(window owner, mode dialog_mode, const std::string& title, bool pick_directory = false):
 | 
				
			||||||
			: form(owner, API::make_center(owner, 630, 440)), io_read_(io_read)
 | 
								form(owner, API::make_center(owner, 630, 440)),
 | 
				
			||||||
 | 
								pick_directory_(pick_directory),
 | 
				
			||||||
 | 
								mode_(dialog_mode)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			internationalization i18n;
 | 
								internationalization i18n;
 | 
				
			||||||
			path_.create(*this);
 | 
								path_.create(*this);
 | 
				
			||||||
@ -159,6 +169,7 @@ namespace nana
 | 
				
			|||||||
				_m_load_cat_path(path);
 | 
									_m_load_cat_path(path);
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			filter_.create(*this);
 | 
								filter_.create(*this);
 | 
				
			||||||
			filter_.multi_lines(false);
 | 
								filter_.multi_lines(false);
 | 
				
			||||||
			filter_.tip_string(i18n("NANA_FILEBOX_FILTER"));
 | 
								filter_.tip_string(i18n("NANA_FILEBOX_FILTER"));
 | 
				
			||||||
@ -203,7 +214,7 @@ namespace nana
 | 
				
			|||||||
			ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_SIZE"), 70);
 | 
								ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_SIZE"), 70);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto fn_sel_file = [this](const arg_mouse& arg){
 | 
								auto fn_sel_file = [this](const arg_mouse& arg){
 | 
				
			||||||
				_m_sel_file(arg);
 | 
									_m_select_file(arg);
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			ls_file_.events().dbl_click.connect_unignorable(fn_sel_file);
 | 
								ls_file_.events().dbl_click.connect_unignorable(fn_sel_file);
 | 
				
			||||||
			ls_file_.events().mouse_down.connect_unignorable(fn_sel_file);
 | 
								ls_file_.events().mouse_down.connect_unignorable(fn_sel_file);
 | 
				
			||||||
@ -278,7 +289,11 @@ namespace nana
 | 
				
			|||||||
				});
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			lb_file_.create(*this);
 | 
								lb_file_.create(*this);
 | 
				
			||||||
			lb_file_.i18n(i18n_eval("NANA_FILEBOX_FILE_COLON"));
 | 
					
 | 
				
			||||||
 | 
								const char* idstr = (mode::open_directory == dialog_mode? "NANA_FILEBOX_DIRECTORY_COLON" : "NANA_FILEBOX_FILE_COLON");
 | 
				
			||||||
 | 
								lb_file_.i18n(i18n_eval(idstr));
 | 
				
			||||||
 | 
								lb_file_.text_align(align::right, align_v::center);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			tb_file_.create(*this);
 | 
								tb_file_.create(*this);
 | 
				
			||||||
			tb_file_.multi_lines(false);
 | 
								tb_file_.multi_lines(false);
 | 
				
			||||||
@ -289,9 +304,13 @@ namespace nana
 | 
				
			|||||||
					_m_ok();
 | 
										_m_ok();
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//Don't create the combox for choose a file extension if the dialog is used for picking a directory.
 | 
				
			||||||
 | 
								if(!pick_directory)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
				cb_types_.create(*this);
 | 
									cb_types_.create(*this);
 | 
				
			||||||
				cb_types_.editable(false);
 | 
									cb_types_.editable(false);
 | 
				
			||||||
				cb_types_.events().selected.connect_unignorable([this](const arg_combox&){ _m_list_fs(); });
 | 
									cb_types_.events().selected.connect_unignorable([this](const arg_combox&){ _m_list_fs(); });
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			btn_ok_.create(*this);
 | 
								btn_ok_.create(*this);
 | 
				
			||||||
			btn_ok_.i18n(i18n_eval("NANA_BUTTON_OK_SHORTKEY"));
 | 
								btn_ok_.i18n(i18n_eval("NANA_BUTTON_OK_SHORTKEY"));
 | 
				
			||||||
@ -313,8 +332,23 @@ namespace nana
 | 
				
			|||||||
			_m_layout();
 | 
								_m_layout();
 | 
				
			||||||
			_m_init_tree();
 | 
								_m_init_tree();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if(0 == title.size())
 | 
								if(title.empty())
 | 
				
			||||||
				this->i18n(i18n_eval(io_read ? "NANA_FILEBOX_OPEN" : "NANA_FILEBOX_SAVE_AS"));
 | 
								{
 | 
				
			||||||
 | 
									const char* idstr{ nullptr };
 | 
				
			||||||
 | 
									switch(dialog_mode)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
									case mode::open_file:
 | 
				
			||||||
 | 
										idstr = "NANA_FILEBOX_OPEN";
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									case mode::write_file:
 | 
				
			||||||
 | 
										idstr = "NANA_FILEBOX_SAVE_AS";
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									case mode::open_directory:
 | 
				
			||||||
 | 
										idstr = "NANA_FILEBOX_OPEN_DIRECTORY";
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									this->i18n(i18n_eval(idstr));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				caption(title);			
 | 
									caption(title);			
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -412,16 +446,21 @@ namespace nana
 | 
				
			|||||||
					"<weight=34 margin=5 path arrange=[variable,200] gap=5>"
 | 
										"<weight=34 margin=5 path arrange=[variable,200] gap=5>"
 | 
				
			||||||
					"<weight=30 margin=[0,0,5,10] new_folder arrange=[100]>"
 | 
										"<weight=30 margin=[0,0,5,10] new_folder arrange=[100]>"
 | 
				
			||||||
					"<content arrange=[180] gap=[5]><weight=8>"
 | 
										"<content arrange=[180] gap=[5]><weight=8>"
 | 
				
			||||||
					"<weight=26<weight=100><vert weight=60 label margin=[0,0,0,5]>"
 | 
										"<weight=26<weight=100><vert weight=80 label margin=[0,5,0,0]>"
 | 
				
			||||||
					"<file margin=[0,18,0,5] arrange=[variable,variable,190] gap=[10]>>"
 | 
										"<file margin=[0,18,0,5] arrange=[variable,variable,190] gap=[10]>>"
 | 
				
			||||||
					"<weight=48 margin=[8,0,14]<>"
 | 
										"<weight=48 margin=[8,0,14]<>"
 | 
				
			||||||
					"<buttons weight=208 margin=[0,18,0] gap=[14]>>");
 | 
										"<buttons weight=208 margin=[0,18,0] gap=[14]>>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			place_.field("path")<<path_<<filter_;
 | 
								place_.field("path")<<path_<<filter_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			place_.field("new_folder")<<btn_folder_;
 | 
								place_.field("new_folder")<<btn_folder_;
 | 
				
			||||||
			place_.field("content")<<tree_<<ls_file_;
 | 
								place_.field("content")<<tree_<<ls_file_;
 | 
				
			||||||
			place_.field("label")<<lb_file_;
 | 
								place_.field("label")<<lb_file_;
 | 
				
			||||||
			place_.field("file")<<tb_file_<<cb_types_;
 | 
								place_.field("file")<<tb_file_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if(!pick_directory_)
 | 
				
			||||||
 | 
									place_.field("file")<<cb_types_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			place_.field("buttons")<<btn_ok_<<btn_cancel_;
 | 
								place_.field("buttons")<<btn_ok_<<btn_cancel_;
 | 
				
			||||||
			place_.collocate();
 | 
								place_.collocate();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -630,6 +669,9 @@ namespace nana
 | 
				
			|||||||
			if(filter.size() && (name.find(filter) == filter.npos))
 | 
								if(filter.size() && (name.find(filter) == filter.npos))
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if(pick_directory_)
 | 
				
			||||||
 | 
									return is_dir;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if((is_dir || 0 == extension) || (0 == extension->size())) return true;
 | 
								if((is_dir || 0 == extension) || (0 == extension->size())) return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for(auto & extstr : *extension)
 | 
								for(auto & extstr : *extension)
 | 
				
			||||||
@ -744,7 +786,7 @@ namespace nana
 | 
				
			|||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		void _m_sel_file(const arg_mouse& arg)
 | 
							void _m_select_file(const arg_mouse& arg)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto sel = ls_file_.selected();
 | 
								auto sel = ls_file_.selected();
 | 
				
			||||||
			if(sel.empty())
 | 
								if(sel.empty())
 | 
				
			||||||
@ -763,7 +805,7 @@ namespace nana
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if(false == m.directory)
 | 
									if((mode::open_directory == mode_) || (false == m.directory))
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					selection_.target = addr_.filesystem + m.name;
 | 
										selection_.target = addr_.filesystem + m.name;
 | 
				
			||||||
					tb_file_.caption(m.name);
 | 
										tb_file_.caption(m.name);
 | 
				
			||||||
@ -816,13 +858,16 @@ namespace nana
 | 
				
			|||||||
						return;
 | 
											return;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if(io_read_)
 | 
										if(mode::write_file != mode_)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						if(fs::file_type::not_found == ftype)
 | 
											if(fs::file_type::not_found == ftype)
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							msgbox mb(*this, caption());
 | 
												msgbox mb(*this, caption());
 | 
				
			||||||
							mb.icon(msgbox::icon_information);
 | 
												mb.icon(msgbox::icon_information);
 | 
				
			||||||
 | 
												if(mode::open_file != mode_)
 | 
				
			||||||
								mb << i18n("NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY", tar);
 | 
													mb << i18n("NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY", tar);
 | 
				
			||||||
 | 
												else
 | 
				
			||||||
 | 
													mb << i18n("NANA_FILEBOX_ERROR_DIRECTORY_NOT_EXISTING_AND_RETRY", tar);
 | 
				
			||||||
							mb();
 | 
												mb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							return;
 | 
												return;
 | 
				
			||||||
@ -892,7 +937,8 @@ namespace nana
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		bool io_read_;
 | 
							bool const pick_directory_;
 | 
				
			||||||
 | 
							mode mode_;
 | 
				
			||||||
		std::string def_ext_;
 | 
							std::string def_ext_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		place	place_;
 | 
							place	place_;
 | 
				
			||||||
@ -1118,7 +1164,8 @@ namespace nana
 | 
				
			|||||||
		wfile.resize(std::wcslen(wfile.data()));
 | 
							wfile.resize(std::wcslen(wfile.data()));
 | 
				
			||||||
		impl_->file = to_utf8(wfile);
 | 
							impl_->file = to_utf8(wfile);
 | 
				
			||||||
#elif defined(NANA_POSIX)
 | 
					#elif defined(NANA_POSIX)
 | 
				
			||||||
			filebox_implement fb(impl_->owner, impl_->open_or_save, impl_->title);
 | 
							using mode = filebox_implement::mode;
 | 
				
			||||||
 | 
							filebox_implement fb(impl_->owner, (impl_->open_or_save ? mode::open_file : mode::write_file), impl_->title);
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		if(impl_->filters.size())
 | 
							if(impl_->filters.size())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -1153,4 +1200,77 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}//end class filebox
 | 
						}//end class filebox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//class directory_picker
 | 
				
			||||||
 | 
						struct folderbox::implement
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							window owner;
 | 
				
			||||||
 | 
							path_type init_path;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						folderbox::folderbox(window owner, const path_type& init_path)
 | 
				
			||||||
 | 
							: impl_(new implement)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							impl_->owner = owner;
 | 
				
			||||||
 | 
							impl_->init_path = init_path;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						folderbox::~folderbox()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete impl_;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::optional<folderbox::path_type> folderbox::show() const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					#ifdef NANA_WINDOWS
 | 
				
			||||||
 | 
							path_type target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							CoInitialize(NULL);
 | 
				
			||||||
 | 
							IFileDialog *fd(nullptr);
 | 
				
			||||||
 | 
							HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fd));
 | 
				
			||||||
 | 
							if (SUCCEEDED(hr))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								IShellItem *init_path{ nullptr };
 | 
				
			||||||
 | 
								hr = SHCreateItemFromParsingName(impl_->init_path.wstring().c_str(), nullptr, IID_PPV_ARGS(&init_path));
 | 
				
			||||||
 | 
								if (SUCCEEDED(hr))
 | 
				
			||||||
 | 
									fd->SetDefaultFolder(init_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fd->SetOptions(FOS_PICKFOLDERS);
 | 
				
			||||||
 | 
								fd->Show(reinterpret_cast<HWND>(API::root(impl_->owner))); // the native handle of the parent nana form goes here
 | 
				
			||||||
 | 
								IShellItem *si;
 | 
				
			||||||
 | 
								hr = fd->GetResult(&si); // fails if user cancelled
 | 
				
			||||||
 | 
								if (SUCCEEDED(hr))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									PWSTR pwstr(nullptr);
 | 
				
			||||||
 | 
									hr = si->GetDisplayName(SIGDN_FILESYSPATH, &pwstr);
 | 
				
			||||||
 | 
									if (SUCCEEDED(hr))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										target = pwstr;
 | 
				
			||||||
 | 
										// use the c-string pointed to by pwstr here
 | 
				
			||||||
 | 
										CoTaskMemFree(pwstr);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									si->Release();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								fd->Release();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							CoUninitialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(NANA_POSIX)
 | 
				
			||||||
 | 
							using mode = filebox_implement::mode;
 | 
				
			||||||
 | 
							filebox_implement fb(impl_->owner, mode::open_directory, {}, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fb.load_fs(impl_->init_path, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							API::modal_window(fb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::string path_directory;
 | 
				
			||||||
 | 
							if(false == fb.file(path_directory))
 | 
				
			||||||
 | 
								return {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return path_type{path_directory};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}//end namespace nana
 | 
					}//end namespace nana
 | 
				
			||||||
 | 
				
			|||||||
@ -1294,8 +1294,10 @@ namespace nana
 | 
				
			|||||||
        min_width_entry_field_pixels_ = pixels;
 | 
					        min_width_entry_field_pixels_ = pixels;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _nana_cxx_folding_expression
 | 
				
			||||||
	void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
 | 
						void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
 | 
						bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
				
			|||||||
@ -64,8 +64,8 @@ namespace nana
 | 
				
			|||||||
				eof, error
 | 
									eof, error
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			tokenizer(const char* p) noexcept
 | 
								tokenizer(const char* div_text) noexcept
 | 
				
			||||||
				: divstr_(p), sp_(p)
 | 
									: divstr_(div_text), sp_(div_text)
 | 
				
			||||||
			{}
 | 
								{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const std::string& idstr() const noexcept
 | 
								const std::string& idstr() const noexcept
 | 
				
			||||||
@ -2583,9 +2583,8 @@ namespace nana
 | 
				
			|||||||
		: public division
 | 
							: public division
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		div_switchable(std::string && name, implement* /*impl*/) noexcept:
 | 
							div_switchable(std::string && name, implement*) noexcept:
 | 
				
			||||||
			division(kind::switchable, std::move(name))//,
 | 
								division(kind::switchable, std::move(name))
 | 
				
			||||||
			//impl_(impl) 	//deprecated
 | 
					 | 
				
			||||||
		{}
 | 
							{}
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		void collocate(window wd) override
 | 
							void collocate(window wd) override
 | 
				
			||||||
@ -2613,8 +2612,6 @@ namespace nana
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	private:
 | 
					 | 
				
			||||||
		//implement * const impl_; //deprecated
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	place::implement::~implement()
 | 
						place::implement::~implement()
 | 
				
			||||||
@ -3183,9 +3180,9 @@ namespace nana
 | 
				
			|||||||
			sp->set_renderer(impl_->split_renderer, true);
 | 
								sp->set_renderer(impl_->split_renderer, true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void place::div(const char* s)
 | 
						void place::div(std::string div_text)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		place_parts::tokenizer tknizer(s);
 | 
							place_parts::tokenizer tknizer(div_text.c_str());
 | 
				
			||||||
		impl_->disconnect();
 | 
							impl_->disconnect();
 | 
				
			||||||
		auto div = impl_->scan_div(tknizer);
 | 
							auto div = impl_->scan_div(tknizer);
 | 
				
			||||||
		try
 | 
							try
 | 
				
			||||||
@ -3193,7 +3190,7 @@ namespace nana
 | 
				
			|||||||
			impl_->connect(div.get());		//throws if there is a redefined name of field.
 | 
								impl_->connect(div.get());		//throws if there is a redefined name of field.
 | 
				
			||||||
			impl_->root_division.reset();	//clear atachments div-fields
 | 
								impl_->root_division.reset();	//clear atachments div-fields
 | 
				
			||||||
			impl_->root_division.swap(div);
 | 
								impl_->root_division.swap(div);
 | 
				
			||||||
			impl_->div_text.assign(s);
 | 
								impl_->div_text.swap(div_text);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (...)
 | 
							catch (...)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -3210,7 +3207,7 @@ namespace nana
 | 
				
			|||||||
	//Contributed by dankan1890(PR#156)
 | 
						//Contributed by dankan1890(PR#156)
 | 
				
			||||||
	enum class update_operation { erase = 0, insert, replace };
 | 
						enum class update_operation { erase = 0, insert, replace };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void update_div(std::string& div, const char* field, const char* attr, update_operation operation);
 | 
						static void update_div(std::string& div, const char* field, const char* attr, update_operation operation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void place::modify(const char* name, const char* div_text)
 | 
						void place::modify(const char* name, const char* div_text)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -3324,7 +3321,7 @@ namespace nana
 | 
				
			|||||||
		return *p;
 | 
							return *p;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void update_div(std::string& div, const char* field, const char* attr, update_operation operation)
 | 
						static void update_div(std::string& div, const char* field, const char* attr, update_operation operation)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const auto fieldname_pos = find_idstr(div, field);
 | 
							const auto fieldname_pos = find_idstr(div, field);
 | 
				
			||||||
		if (div.npos == fieldname_pos)
 | 
							if (div.npos == fieldname_pos)
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,9 @@
 | 
				
			|||||||
#include <nana/gui/detail/events_operation.hpp>
 | 
					#include <nana/gui/detail/events_operation.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../../source/detail/platform_abstraction.hpp"
 | 
					#include "../../source/detail/platform_abstraction.hpp"
 | 
				
			||||||
 | 
					#ifdef NANA_X11
 | 
				
			||||||
 | 
					#	include "../../source/detail/posix/platform_spec.hpp"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nana
 | 
					namespace nana
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -52,6 +55,19 @@ namespace nana
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
namespace API
 | 
					namespace API
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef NANA_X11
 | 
				
			||||||
 | 
						//Some platform specific functions for X11
 | 
				
			||||||
 | 
						namespace x11
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/// Returns the connection to the X server
 | 
				
			||||||
 | 
							const void* get_display()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto & spec = nana::detail::platform_spec::instance();
 | 
				
			||||||
 | 
								return spec.open_display();			
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	using basic_window = ::nana::detail::basic_window;
 | 
						using basic_window = ::nana::detail::basic_window;
 | 
				
			||||||
	using interface_type = ::nana::detail::native_interface;
 | 
						using interface_type = ::nana::detail::native_interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -244,7 +260,7 @@ namespace API
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		::nana::detail::native_string_type window_caption(window wd) throw()
 | 
							::nana::detail::native_string_type window_caption(window wd) noexcept
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto const iwd = reinterpret_cast<basic_window*>(wd);
 | 
								auto const iwd = reinterpret_cast<basic_window*>(wd);
 | 
				
			||||||
			internal_scope_guard isg;
 | 
								internal_scope_guard isg;
 | 
				
			||||||
@ -377,8 +393,13 @@ namespace API
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if (shortkey)
 | 
								if (shortkey)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									auto off_x = (shortkey_position ? graph.text_extent_size(std::string_view{ text.c_str(), shortkey_position }).width : 0);
 | 
				
			||||||
 | 
									auto key_px = static_cast<int>(graph.text_extent_size(std::wstring_view{ &shortkey, 1 }).width);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				auto off_x = (shortkey_position ? graph.text_extent_size(text.c_str(), shortkey_position).width : 0);
 | 
									auto off_x = (shortkey_position ? graph.text_extent_size(text.c_str(), shortkey_position).width : 0);
 | 
				
			||||||
				auto key_px = static_cast<int>(graph.text_extent_size(&shortkey, 1).width);
 | 
									auto key_px = static_cast<int>(graph.text_extent_size(&shortkey, 1).width);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				unsigned ascent, descent, inleading;
 | 
									unsigned ascent, descent, inleading;
 | 
				
			||||||
				graph.text_metrics(ascent, descent, inleading);
 | 
									graph.text_metrics(ascent, descent, inleading);
 | 
				
			||||||
@ -392,7 +413,6 @@ namespace API
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}//end namespace dev
 | 
						}//end namespace dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	widget* get_widget(window wd)
 | 
						widget* get_widget(window wd)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		internal_scope_guard lock;
 | 
							internal_scope_guard lock;
 | 
				
			||||||
@ -823,7 +843,7 @@ namespace API
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nana::optional<rectangle> window_rectangle(window wd)
 | 
						std::optional<rectangle> window_rectangle(window wd)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto iwd = reinterpret_cast<basic_window*>(wd);
 | 
							auto iwd = reinterpret_cast<basic_window*>(wd);
 | 
				
			||||||
		internal_scope_guard lock;
 | 
							internal_scope_guard lock;
 | 
				
			||||||
@ -1461,7 +1481,7 @@ namespace API
 | 
				
			|||||||
		restrict::wd_manager().set_safe_place(reinterpret_cast<basic_window*>(wd), std::move(fn));
 | 
							restrict::wd_manager().set_safe_place(reinterpret_cast<basic_window*>(wd), std::move(fn));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	optional<std::pair<size, size>> content_extent(window wd, unsigned limited_px, bool limit_width)
 | 
						std::optional<std::pair<size, size>> content_extent(window wd, unsigned limited_px, bool limit_width)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto iwd = reinterpret_cast<basic_window*>(wd);
 | 
							auto iwd = reinterpret_cast<basic_window*>(wd);
 | 
				
			||||||
		internal_scope_guard lock;
 | 
							internal_scope_guard lock;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	A Button Implementation
 | 
					 *	A Button Implementation
 | 
				
			||||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
					 *	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
 *	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -27,7 +27,7 @@ namespace nana{	namespace drawerbase
 | 
				
			|||||||
				: trigger_{ t }
 | 
									: trigger_{ t }
 | 
				
			||||||
			{}
 | 
								{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override
 | 
								std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				//Button doesn't provide a support of vfit and hfit
 | 
									//Button doesn't provide a support of vfit and hfit
 | 
				
			||||||
				if (limit_pixels)
 | 
									if (limit_pixels)
 | 
				
			||||||
@ -262,7 +262,11 @@ namespace nana{	namespace drawerbase
 | 
				
			|||||||
					if (attr_.omitted)
 | 
										if (attr_.omitted)
 | 
				
			||||||
						tr.render(pos, txtptr, txtlen, omitted_pixels, true);
 | 
											tr.render(pos, txtptr, txtlen, omitted_pixels, true);
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
											graph.bidi_string(pos, { txtptr, txtlen });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
						graph.bidi_string(pos, txtptr, txtlen);
 | 
											graph.bidi_string(pos, txtptr, txtlen);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					API::dev::draw_shortkey_underline(graph, mbstr, shortkey, shortkey_pos, pos, text_color);
 | 
										API::dev::draw_shortkey_underline(graph, mbstr, shortkey, shortkey_pos, pos, text_color);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -277,9 +281,15 @@ namespace nana{	namespace drawerbase
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
											graph.bidi_string(point{ pos.x + 1, pos.y + 1 }, { txtptr, txtlen });
 | 
				
			||||||
 | 
											graph.palette(true, color{ colors::gray });
 | 
				
			||||||
 | 
											graph.bidi_string(pos, { txtptr, txtlen });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
						graph.bidi_string(point{ pos.x + 1, pos.y + 1 }, txtptr, txtlen);
 | 
											graph.bidi_string(point{ pos.x + 1, pos.y + 1 }, txtptr, txtlen);
 | 
				
			||||||
						graph.palette(true, color{ colors::gray });
 | 
											graph.palette(true, color{ colors::gray });
 | 
				
			||||||
						graph.bidi_string(pos, txtptr, txtlen);
 | 
											graph.bidi_string(pos, txtptr, txtlen);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -78,7 +78,11 @@ namespace nana{ namespace drawerbase
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//draw crook
 | 
									//draw crook
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									auto txt_px = graph.text_extent_size(std::wstring_view( L"jN", 2 )).height + 2;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				auto txt_px = graph.text_extent_size(L"jN", 2).height + 2;
 | 
									auto txt_px = graph.text_extent_size(L"jN", 2).height + 2;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				impl_->crook.draw(graph, wdg->bgcolor(), wdg->fgcolor(), rectangle(0, txt_px > 16 ? (txt_px - 16) / 2 : 0, 16, 16), API::element_state(*wdg));
 | 
									impl_->crook.draw(graph, wdg->bgcolor(), wdg->fgcolor(), rectangle(0, txt_px > 16 ? (txt_px - 16) / 2 : 0, 16, 16), API::element_state(*wdg));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -163,12 +167,12 @@ namespace nana{ namespace drawerbase
 | 
				
			|||||||
			return (get_drawer_trigger().impl()->crook.checked() != drawerbase::checkbox::crook_state::unchecked);
 | 
								return (get_drawer_trigger().impl()->crook.checked() != drawerbase::checkbox::crook_state::unchecked);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void checkbox::check(bool chk)
 | 
							void checkbox::check(bool state)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			using crook_state = drawerbase::checkbox::crook_state;
 | 
								using crook_state = drawerbase::checkbox::crook_state;
 | 
				
			||||||
			if (checked() != chk)
 | 
								if (checked() != state)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				get_drawer_trigger().impl()->crook.check(chk ? crook_state::checked : crook_state::unchecked);
 | 
									get_drawer_trigger().impl()->crook.check(state ? crook_state::checked : crook_state::unchecked);
 | 
				
			||||||
				API::refresh_window(handle());
 | 
									API::refresh_window(handle());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				arg_checkbox arg(this);
 | 
									arg_checkbox arg(this);
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,7 @@ namespace nana
 | 
				
			|||||||
						: drw_{ drwimpl }
 | 
											: drw_{ drwimpl }
 | 
				
			||||||
					{}
 | 
										{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override
 | 
										std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool /*limit_width*/) const override
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						//Combox doesn't provide a support of vfit and hfit
 | 
											//Combox doesn't provide a support of vfit and hfit
 | 
				
			||||||
						if (limit_pixels)
 | 
											if (limit_pixels)
 | 
				
			||||||
@ -1037,7 +1037,7 @@ namespace nana
 | 
				
			|||||||
				API::refresh_window(*this);
 | 
									API::refresh_window(*this);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto combox::_m_caption() const throw() -> native_string_type
 | 
							auto combox::_m_caption() const noexcept -> native_string_type
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			internal_scope_guard lock;
 | 
								internal_scope_guard lock;
 | 
				
			||||||
			auto editor = _m_impl().editor();
 | 
								auto editor = _m_impl().editor();
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,7 @@ namespace nana{
 | 
				
			|||||||
	struct group::implement
 | 
						struct group::implement
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		label	caption;
 | 
							label	caption;
 | 
				
			||||||
 | 
							align	caption_align{ align::left };
 | 
				
			||||||
		place	place_content;
 | 
							place	place_content;
 | 
				
			||||||
		unsigned gap{2};
 | 
							unsigned gap{2};
 | 
				
			||||||
		std::string usr_div_str;
 | 
							std::string usr_div_str;
 | 
				
			||||||
@ -65,11 +66,27 @@ namespace nana{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		void update_div()
 | 
							void update_div()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								const std::size_t padding = 10;
 | 
				
			||||||
			caption_dimension = caption.measure(1000);
 | 
								caption_dimension = caption.measure(1000);
 | 
				
			||||||
 | 
								caption_dimension.width += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string div = "vert margin=[0," + std::to_string(gap) + "," + std::to_string(gap + 5) + "," + std::to_string(gap) + "]";
 | 
								std::string div = "vert margin=[0," + std::to_string(gap) + "," + std::to_string(gap + 5) + "," + std::to_string(gap) + "]";
 | 
				
			||||||
			div += "<weight=" + std::to_string(caption_dimension.height) + " <weight=5><" + field_title + " weight=" + std::to_string(caption_dimension.width + 1) + ">>";
 | 
					
 | 
				
			||||||
			div += "<<vert margin=5 " + std::string(field_options) + ">";
 | 
								div += "<weight=" + std::to_string(caption_dimension.height) + " ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (align::left == caption_align)
 | 
				
			||||||
 | 
									div += "<weight=" + std::to_string(padding) + ">";
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									div += "<>";	//right or center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								div += "<" + std::string{ field_title } + " weight=" + std::to_string(caption_dimension.width) + ">";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (align::right == caption_align)
 | 
				
			||||||
 | 
									div += "<weight=" + std::to_string(padding) + ">";
 | 
				
			||||||
 | 
								else if (align::center == caption_align)
 | 
				
			||||||
 | 
									div += "<>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								div += "><<vert margin=5 " + std::string(field_options) + ">";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!usr_div_str.empty())
 | 
								if (!usr_div_str.empty())
 | 
				
			||||||
				div += "<" + usr_div_str + ">>";
 | 
									div += "<" + usr_div_str + ">>";
 | 
				
			||||||
@ -97,10 +114,15 @@ namespace nana{
 | 
				
			|||||||
		create(parent, r, vsb);
 | 
							create(parent, r, vsb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						using groupbase_type = widget_object<category::widget_tag, drawerbase::panel::drawer, general_events, drawerbase::group::scheme>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	group::group(window parent, ::std::string titel, bool formatted, unsigned  gap, const rectangle& r, bool vsb)
 | 
						group::group(window parent, ::std::string titel, bool formatted, unsigned  gap, const rectangle& r, bool vsb)
 | 
				
			||||||
		: panel(parent, r, vsb),
 | 
							: group(parent, r, vsb)
 | 
				
			||||||
		  impl_(new implement(*this, std::move(titel), vsb, gap))
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							this->bgcolor(API::bgcolor(parent));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							impl_.reset(new implement(*this, std::move(titel), vsb, gap));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		impl_->caption.format(formatted);
 | 
							impl_->caption.format(formatted);
 | 
				
			||||||
		_m_init();
 | 
							_m_init();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -128,6 +150,17 @@ namespace nana{
 | 
				
			|||||||
		return *impl_->options.back();
 | 
							return *impl_->options.back();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void group::caption_align(align position)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (position != impl_->caption_align)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								impl_->caption_align = position;
 | 
				
			||||||
 | 
								impl_->update_div();
 | 
				
			||||||
 | 
								impl_->place_content.collocate();
 | 
				
			||||||
 | 
								API::refresh_window(*this);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	group& group::radio_mode(bool enable)
 | 
						group& group::radio_mode(bool enable)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		_THROW_IF_EMPTY()
 | 
							_THROW_IF_EMPTY()
 | 
				
			||||||
@ -243,7 +276,7 @@ namespace nana{
 | 
				
			|||||||
			graph.round_rectangle(rectangle(point(gap_px, top_round_line),
 | 
								graph.round_rectangle(rectangle(point(gap_px, top_round_line),
 | 
				
			||||||
				nana::size(graph.width() - 2 * gap_px, graph.height() - top_round_line - gap_px)
 | 
									nana::size(graph.width() - 2 * gap_px, graph.height() - top_round_line - gap_px)
 | 
				
			||||||
				),
 | 
									),
 | 
				
			||||||
				3, 3, colors::gray_border, true, this->bgcolor());
 | 
									3, 3, this->scheme().border, true, this->bgcolor());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto opt_r = API::window_rectangle(impl_->caption);
 | 
								auto opt_r = API::window_rectangle(impl_->caption);
 | 
				
			||||||
			if (opt_r)
 | 
								if (opt_r)
 | 
				
			||||||
@ -263,15 +296,12 @@ namespace nana{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void group::_m_complete_creation()
 | 
						void group::_m_complete_creation()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		panel::_m_complete_creation();
 | 
							widget::_m_complete_creation();
 | 
				
			||||||
 | 
					 | 
				
			||||||
		impl_->create(handle());
 | 
							impl_->create(handle());
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		_m_init();
 | 
							_m_init();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto group::_m_caption() const throw() -> native_string_type
 | 
						auto group::_m_caption() const noexcept -> native_string_type
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return impl_->caption.caption_native();
 | 
							return impl_->caption.caption_native();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	A Label Control Implementation
 | 
					 *	A Label Control Implementation
 | 
				
			||||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
					 *	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
 *	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -83,7 +83,11 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					auto pre_font = graph.typeface();	//used for restoring the font
 | 
										auto pre_font = graph.typeface();	//used for restoring the font
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										const unsigned def_line_pixels = graph.text_extent_size(std::wstring_view{ L" ", 1 }).height;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height;
 | 
										const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					font_ = pre_font;
 | 
										font_ = pre_font;
 | 
				
			||||||
					fblock_ = nullptr;
 | 
										fblock_ = nullptr;
 | 
				
			||||||
@ -170,7 +174,11 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					auto ft = graph.typeface();	//used for restoring the font
 | 
										auto ft = graph.typeface();	//used for restoring the font
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										const unsigned def_line_pixels = graph.text_extent_size(std::wstring_view(L" ", 1)).height;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height;
 | 
										const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					font_ = ft;
 | 
										font_ = ft;
 | 
				
			||||||
					fblock_ = nullptr;
 | 
										fblock_ = nullptr;
 | 
				
			||||||
@ -556,6 +564,16 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
							_m_change_font(graph, fblock_ptr);
 | 
												_m_change_font(graph, fblock_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
												std::wstring_view text_sv{ data_ptr->text() };
 | 
				
			||||||
 | 
												if (text_range.second != text_sv.size())
 | 
				
			||||||
 | 
												{
 | 
				
			||||||
 | 
													text_sv = text_sv.substr(text_range.first, text_range.second);
 | 
				
			||||||
 | 
													sz = graph.text_extent_size(text_sv);
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
												graph.string({ rs.pos.x, y }, text_sv, _m_fgcolor(fblock_ptr));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
							if (text_range.second == data_ptr->text().length())
 | 
												if (text_range.second == data_ptr->text().length())
 | 
				
			||||||
							{
 | 
												{
 | 
				
			||||||
								graph.string({ rs.pos.x, y }, data_ptr->text(), _m_fgcolor(fblock_ptr));
 | 
													graph.string({ rs.pos.x, y }, data_ptr->text(), _m_fgcolor(fblock_ptr));
 | 
				
			||||||
@ -567,6 +585,7 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
								graph.string({ rs.pos.x, y }, str, _m_fgcolor(fblock_ptr));
 | 
													graph.string({ rs.pos.x, y }, str, _m_fgcolor(fblock_ptr));
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							_m_insert_if_traceable(rs.pos.x, y, sz, fblock_ptr);
 | 
												_m_insert_if_traceable(rs.pos.x, y, sz, fblock_ptr);
 | 
				
			||||||
@ -653,7 +672,7 @@ namespace nana
 | 
				
			|||||||
						: impl_{ impl }
 | 
											: impl_{ impl }
 | 
				
			||||||
					{}
 | 
										{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
 | 
										std::optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						//Label now doesn't support to measure content with a specified height.
 | 
											//Label now doesn't support to measure content with a specified height.
 | 
				
			||||||
						if (graph && ((0 == limit_pixels) || limit_width))
 | 
											if (graph && ((0 == limit_pixels) || limit_width))
 | 
				
			||||||
@ -825,7 +844,7 @@ namespace nana
 | 
				
			|||||||
			return *this;
 | 
								return *this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool label::transparent() const throw()
 | 
							bool label::transparent() const noexcept
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return API::is_transparent_background(*this);
 | 
								return API::is_transparent_background(*this);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -849,7 +868,7 @@ namespace nana
 | 
				
			|||||||
			return *this;
 | 
								return *this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		label& label::click_for(window associated_window) throw()
 | 
							label& label::click_for(window associated_window) noexcept
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			get_drawer_trigger().impl()->for_associated_wd = associated_window;
 | 
								get_drawer_trigger().impl()->for_associated_wd = associated_window;
 | 
				
			||||||
			return *this;
 | 
								return *this;
 | 
				
			||||||
 | 
				
			|||||||
@ -2470,10 +2470,10 @@ namespace nana
 | 
				
			|||||||
						x += col.width_px;
 | 
											x += col.width_px;
 | 
				
			||||||
						if (x > 0)
 | 
											if (x > 0)
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
 | 
												seqs.push_back(col.index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							if (x >= static_cast<int>(lister_w))
 | 
												if (x >= static_cast<int>(lister_w))
 | 
				
			||||||
								break;
 | 
													break;
 | 
				
			||||||
 | 
					 | 
				
			||||||
							seqs.push_back(col.index);
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					return seqs;
 | 
										return seqs;
 | 
				
			||||||
@ -2757,6 +2757,17 @@ namespace nana
 | 
				
			|||||||
			unsigned es_lister::column_content_pixels(size_type pos) const
 | 
								unsigned es_lister::column_content_pixels(size_type pos) const
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				unsigned max_px = 0;
 | 
									unsigned max_px = 0;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									std::unique_ptr<paint::graphics> graph_helper;
 | 
				
			||||||
 | 
									auto graph = ess_->graph;
 | 
				
			||||||
 | 
									if (graph->empty())
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										//Creates a helper if widget graph is empty(when its size is 0).
 | 
				
			||||||
 | 
										graph_helper.reset(new paint::graphics{ nana::size{ 5, 5 } });
 | 
				
			||||||
 | 
										graph_helper->typeface(ess_->graph->typeface());
 | 
				
			||||||
 | 
										graph = graph_helper.get();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				for (auto & cat : categories_)
 | 
									for (auto & cat : categories_)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					for (std::size_t i = 0; i < cat.items.size(); ++i)
 | 
										for (std::size_t i = 0; i < cat.items.size(); ++i)
 | 
				
			||||||
@ -2768,14 +2779,14 @@ namespace nana
 | 
				
			|||||||
							if (pos >= model_cells.size())
 | 
												if (pos >= model_cells.size())
 | 
				
			||||||
								continue;
 | 
													continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							content_px = ess_->graph->text_extent_size(model_cells[pos].text).width;
 | 
												content_px = graph->text_extent_size(model_cells[pos].text).width;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						else
 | 
											else
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							if (pos >= cat.items[i].cells->size())
 | 
												if (pos >= cat.items[i].cells->size())
 | 
				
			||||||
								continue;
 | 
													continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							content_px = ess_->graph->text_extent_size((*cat.items[i].cells)[pos].text).width;
 | 
												content_px = graph->text_extent_size((*cat.items[i].cells)[pos].text).width;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if (content_px > max_px)
 | 
											if (content_px > max_px)
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ namespace nana
 | 
				
			|||||||
					: impl_{impl}
 | 
										: impl_{impl}
 | 
				
			||||||
				{}
 | 
									{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				optional<size> measure(graph_reference /*graph*/, unsigned limit_pixels, bool /*limit_width*/) const override
 | 
									std::optional<size> measure(graph_reference /*graph*/, unsigned limit_pixels, bool /*limit_width*/) const override
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					//Picture doesn't provide a support of vfit and hfit
 | 
										//Picture doesn't provide a support of vfit and hfit
 | 
				
			||||||
					if (!limit_pixels)
 | 
										if (!limit_pixels)
 | 
				
			||||||
 | 
				
			|||||||
@ -68,12 +68,6 @@ namespace nana {
 | 
				
			|||||||
				bool	drag_started{ false };
 | 
									bool	drag_started{ false };
 | 
				
			||||||
				point origin;
 | 
									point origin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/*
 | 
					 | 
				
			||||||
				scrolls enabled_scrolls{scrolls::both};	//deprecated
 | 
					 | 
				
			||||||
				nana::scroll<false>	horz;
 | 
					 | 
				
			||||||
				nana::scroll<true>	vert;
 | 
					 | 
				
			||||||
				*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				std::shared_ptr<cv_scroll_rep> cv_scroll;
 | 
									std::shared_ptr<cv_scroll_rep> cv_scroll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				timer tmr;
 | 
									timer tmr;
 | 
				
			||||||
@ -91,27 +85,10 @@ namespace nana {
 | 
				
			|||||||
					cv_scroll(std::make_shared<cv_scroll_rep>())
 | 
										cv_scroll(std::make_shared<cv_scroll_rep>())
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					API::events(handle).mouse_wheel.connect_unignorable([this](const arg_wheel& arg) {
 | 
										API::events(handle).mouse_wheel.connect_unignorable([this](const arg_wheel& arg) {
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
						scroll_interface * scroll = nullptr;
 | 
					 | 
				
			||||||
						switch (arg.which)
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
						case arg_wheel::wheel::vertical:
 | 
					 | 
				
			||||||
							scroll = |
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						case arg_wheel::wheel::horizontal:
 | 
					 | 
				
			||||||
							scroll = &horz;
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						default:
 | 
					 | 
				
			||||||
							//Other button is not unsupported.
 | 
					 | 
				
			||||||
							return;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
						auto const scroll = cv_scroll->scroll(arg.which);
 | 
					 | 
				
			||||||
						if (nullptr == scroll)
 | 
					 | 
				
			||||||
							return;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if (!API::empty_window(arg.window_handle))
 | 
											auto const scroll = cv_scroll->scroll(arg.which);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											if (scroll && (!API::empty_window(arg.window_handle)))
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							auto align_px = (scroll->value() % scroll->step());
 | 
												auto align_px = (scroll->value() % scroll->step());
 | 
				
			||||||
							if (align_px)
 | 
												if (align_px)
 | 
				
			||||||
 | 
				
			|||||||
@ -834,8 +834,12 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
						if (str_w > pixels)	//Indicates the splitting of ts string
 | 
											if (str_w > pixels)	//Indicates the splitting of ts string
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							std::size_t len = ts.end - ts.begin;
 | 
												std::size_t len = ts.end - ts.begin;
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
												auto pxbuf = editor_.graph_.glyph_pixels({ts.begin, len});
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
							std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
 | 
												std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
 | 
				
			||||||
							editor_.graph_.glyph_pixels(ts.begin, len, pxbuf.get());
 | 
												editor_.graph_.glyph_pixels(ts.begin, len, pxbuf.get());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							auto pxptr = pxbuf.get();
 | 
												auto pxptr = pxbuf.get();
 | 
				
			||||||
							auto pxend = pxptr + len;
 | 
												auto pxend = pxptr + len;
 | 
				
			||||||
@ -3147,7 +3151,11 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
				maskstr.append(n, mask_char_);
 | 
									maskstr.append(n, mask_char_);
 | 
				
			||||||
				return graph_.text_extent_size(maskstr);
 | 
									return graph_.text_extent_size(maskstr);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								return graph_.text_extent_size(std::basic_string_view<char_type>(str, n));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			return graph_.text_extent_size(str, static_cast<unsigned>(n));
 | 
								return graph_.text_extent_size(str, static_cast<unsigned>(n));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool text_editor::_m_adjust_view()
 | 
							bool text_editor::_m_adjust_view()
 | 
				
			||||||
@ -3301,13 +3309,21 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		void text_editor::_m_draw_parse_string(const keyword_parser& parser, bool rtl, ::nana::point pos, const ::nana::color& fgcolor, const wchar_t* str, std::size_t len) const
 | 
							void text_editor::_m_draw_parse_string(const keyword_parser& parser, bool rtl, ::nana::point pos, const ::nana::color& fgcolor, const wchar_t* str, std::size_t len) const
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								graph_.string(pos, { str, len }, fgcolor);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			graph_.palette(true, fgcolor);
 | 
								graph_.palette(true, fgcolor);
 | 
				
			||||||
			graph_.string(pos, str, len);
 | 
								graph_.string(pos, str, len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			if (parser.entities().empty())
 | 
								if (parser.entities().empty())
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								auto glyph_px = graph_.glyph_pixels({ str, len });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			std::unique_ptr<unsigned[]> glyph_px(new unsigned[len]);
 | 
								std::unique_ptr<unsigned[]> glyph_px(new unsigned[len]);
 | 
				
			||||||
			graph_.glyph_pixels(str, len, glyph_px.get());
 | 
								graph_.glyph_pixels(str, len, glyph_px.get());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			auto glyphs = glyph_px.get();
 | 
								auto glyphs = glyph_px.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto px_h = line_height();
 | 
								auto px_h = line_height();
 | 
				
			||||||
@ -3347,7 +3363,20 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					ent_pos.x = pos.x + ent_off;
 | 
										ent_pos.x = pos.x + ent_off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										std::wstring_view ent_sv;
 | 
				
			||||||
 | 
										if (rtl)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											//draw the whole text if it is a RTL text, because Arbic language is transformable.
 | 
				
			||||||
 | 
											ent_sv = { str, len };
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											ent_sv = { ent_begin, static_cast<std::wstring_view::size_type>(ent_end - ent_begin) };
 | 
				
			||||||
 | 
											ent_off = 0;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										canvas.string({}, ent_sv);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					if (rtl)
 | 
										if (rtl)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						//draw the whole text if it is a RTL text, because Arbic language is transformable.
 | 
											//draw the whole text if it is a RTL text, because Arbic language is transformable.
 | 
				
			||||||
@ -3358,6 +3387,7 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
						canvas.string({}, ent_begin, ent_end - ent_begin);
 | 
											canvas.string({}, ent_begin, ent_end - ent_begin);
 | 
				
			||||||
						ent_off = 0;
 | 
											ent_off = 0;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
					graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas, point{ ent_off, 0 });
 | 
										graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas, point{ ent_off, 0 });
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -3383,12 +3413,19 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			void write_selection(const point& text_pos, unsigned text_px, const wchar_t* text, std::size_t len, bool has_focused)
 | 
								void write_selection(const point& text_pos, unsigned text_px, const wchar_t* text, std::size_t len, bool has_focused)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									graph_.rectangle(::nana::rectangle{ text_pos,{ text_px, line_px_ } }, true,
 | 
				
			||||||
 | 
										selection_color(false, has_focused));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									graph_.string(text_pos, { text, len }, selection_color(true, has_focused));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				graph_.palette(true, selection_color(true, has_focused));
 | 
									graph_.palette(true, selection_color(true, has_focused));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				graph_.rectangle(::nana::rectangle{ text_pos, { text_px, line_px_ } }, true,
 | 
									graph_.rectangle(::nana::rectangle{ text_pos, { text_px, line_px_ } }, true,
 | 
				
			||||||
					selection_color(false, has_focused));
 | 
										selection_color(false, has_focused));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				graph_.string(text_pos, text, len);
 | 
									graph_.string(text_pos, text, len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			void rtl_string(point strpos, const wchar_t* str, std::size_t len, std::size_t str_px, unsigned glyph_front, unsigned glyph_selected, bool has_focused)
 | 
								void rtl_string(point strpos, const wchar_t* str, std::size_t len, std::size_t str_px, unsigned glyph_front, unsigned glyph_selected, bool has_focused)
 | 
				
			||||||
@ -3402,9 +3439,12 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				int sel_xpos = static_cast<int>(str_px - (glyph_front + glyph_selected));
 | 
									int sel_xpos = static_cast<int>(str_px - (glyph_front + glyph_selected));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									graph.string({ -sel_xpos, 0 }, { str, len }, selection_color(true, has_focused));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				graph.palette(true, selection_color(true, has_focused));
 | 
									graph.palette(true, selection_color(true, has_focused));
 | 
				
			||||||
 | 
					 | 
				
			||||||
				graph.string({ -sel_xpos, 0 }, str, len);
 | 
									graph.string({ -sel_xpos, 0 }, str, len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_px_), graph);
 | 
									graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_px_), graph);
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
@ -3500,7 +3540,12 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
				for (auto & ent : reordered)
 | 
									for (auto & ent : reordered)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					std::size_t len = ent.end - ent.begin;
 | 
										std::size_t len = ent.end - ent.begin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										unsigned str_w = graph_.text_extent_size(std::wstring_view{ ent.begin, len }).width;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					unsigned str_w = graph_.text_extent_size(ent.begin, len).width;
 | 
										unsigned str_w = graph_.text_extent_size(ent.begin, len).width;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if ((text_draw_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_draw_pos.x < text_right))
 | 
										if ((text_draw_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_draw_pos.x < text_right))
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
@ -3519,7 +3564,11 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
				for (auto & ent : reordered)
 | 
									for (auto & ent : reordered)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					const auto len = ent.end - ent.begin;
 | 
										const auto len = ent.end - ent.begin;
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										auto ent_px = graph_.text_extent_size(std::wstring_view(ent.begin, len)).width;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					auto ent_px = graph_.text_extent_size(ent.begin, len).width;
 | 
										auto ent_px = graph_.text_extent_size(ent.begin, len).width;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					extra_space = false;
 | 
										extra_space = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3548,8 +3597,12 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
							unsigned select_pos = static_cast<unsigned>(ent_sbegin != ent.begin ? ent_sbegin - ent.begin : 0);
 | 
												unsigned select_pos = static_cast<unsigned>(ent_sbegin != ent.begin ? ent_sbegin - ent.begin : 0);
 | 
				
			||||||
							unsigned select_len = static_cast<unsigned>(ent_send - ent_sbegin);
 | 
												unsigned select_len = static_cast<unsigned>(ent_send - ent_sbegin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
												auto pxbuf = graph_.glyph_pixels({ ent.begin, static_cast<std::size_t>(len) });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
							std::unique_ptr<unsigned[]> pxbuf{ new unsigned[len] };
 | 
												std::unique_ptr<unsigned[]> pxbuf{ new unsigned[len] };
 | 
				
			||||||
							graph_.glyph_pixels(ent.begin, len, pxbuf.get());
 | 
												graph_.glyph_pixels(ent.begin, len, pxbuf.get());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							auto head_px = std::accumulate(pxbuf.get(), pxbuf.get() + select_pos, unsigned{});
 | 
												auto head_px = std::accumulate(pxbuf.get(), pxbuf.get() + select_pos, unsigned{});
 | 
				
			||||||
							auto select_px = std::accumulate(pxbuf.get() + select_pos, pxbuf.get() + select_pos + select_len, unsigned{});
 | 
												auto select_px = std::accumulate(pxbuf.get() + select_pos, pxbuf.get() + select_pos + select_len, unsigned{});
 | 
				
			||||||
@ -3589,7 +3642,11 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
				auto pos = text_coord.x + text_len;
 | 
									auto pos = text_coord.x + text_len;
 | 
				
			||||||
				if (b.x != pos || text_coord.y != b.y)
 | 
									if (b.x != pos || text_coord.y != b.y)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										auto whitespace_w = graph_.text_extent_size(std::wstring_view{ L" ", 1 }).width;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					auto whitespace_w = graph_.text_extent_size(L" ", 1).width;
 | 
										auto whitespace_w = graph_.text_extent_size(L" ", 1).width;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
					graph_.rectangle(::nana::rectangle{ text_draw_pos, { whitespace_w, line_h_pixels } }, true);
 | 
										graph_.rectangle(::nana::rectangle{ text_draw_pos, { whitespace_w, line_h_pixels } }, true);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -3617,9 +3674,13 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
		unsigned text_editor::_m_char_by_pixels(const unicode_bidi::entity& ent, unsigned pos) const
 | 
							unsigned text_editor::_m_char_by_pixels(const unicode_bidi::entity& ent, unsigned pos) const
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto len = static_cast<std::size_t>(ent.end - ent.begin);
 | 
								auto len = static_cast<std::size_t>(ent.end - ent.begin);
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								auto pxbuf = graph_.glyph_pixels({ ent.begin, len });
 | 
				
			||||||
 | 
								if (pxbuf)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
 | 
								std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
 | 
				
			||||||
			if (graph_.glyph_pixels(ent.begin, len, pxbuf.get()))
 | 
								if (graph_.glyph_pixels(ent.begin, len, pxbuf.get()))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				const auto px_end = pxbuf.get() + len;
 | 
									const auto px_end = pxbuf.get() + len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3677,8 +3738,12 @@ namespace nana{	namespace widgets
 | 
				
			|||||||
					{
 | 
										{
 | 
				
			||||||
						//Characters of some bidi languages may transform in a word.
 | 
											//Characters of some bidi languages may transform in a word.
 | 
				
			||||||
						//RTL
 | 
											//RTL
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
											auto pxbuf = graph_.glyph_pixels({ent.begin, len});
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
						std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
 | 
											std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
 | 
				
			||||||
						graph_.glyph_pixels(ent.begin, len, pxbuf.get());
 | 
											graph_.glyph_pixels(ent.begin, len, pxbuf.get());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
						return std::accumulate(pxbuf.get() + (target - ent.begin), pxbuf.get() + len, text_w);
 | 
											return std::accumulate(pxbuf.get() + (target - ent.begin), pxbuf.get() + len, text_w);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					//LTR
 | 
										//LTR
 | 
				
			||||||
 | 
				
			|||||||
@ -82,10 +82,39 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				bool check_value(const std::string& str) const override
 | 
									bool check_value(const std::string& str) const override
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
 | 
					#ifdef __cpp_if_constexpr
 | 
				
			||||||
 | 
										auto i = str.c_str();
 | 
				
			||||||
 | 
										if ('+' == *i || '-' == *i)
 | 
				
			||||||
 | 
											++i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if constexpr(std::is_same<T, int>::value)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											for (; 0 != *i; ++i)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												if (*i < '0' || '9' < *i)
 | 
				
			||||||
 | 
													return false;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											bool dot = false;
 | 
				
			||||||
 | 
											for (; 0 != *i; ++i)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												if (('.' == *i) && (!dot))
 | 
				
			||||||
 | 
												{
 | 
				
			||||||
 | 
													dot = true;
 | 
				
			||||||
 | 
													continue;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
												if (*i < '0' || '9' < *i)
 | 
				
			||||||
 | 
													return false;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					if (str.empty())
 | 
										if (str.empty())
 | 
				
			||||||
						return true;
 | 
											return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					auto size = str.size();
 | 
										auto const size = str.size();
 | 
				
			||||||
					std::size_t pos = 0;
 | 
										std::size_t pos = 0;
 | 
				
			||||||
					if (str[0] == '+' || str[0] == '-')
 | 
										if (str[0] == '+' || str[0] == '-')
 | 
				
			||||||
						pos = 1;
 | 
											pos = 1;
 | 
				
			||||||
@ -115,6 +144,7 @@ namespace nana
 | 
				
			|||||||
								return false;
 | 
													return false;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
					return true;
 | 
										return true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -744,7 +774,7 @@ namespace nana
 | 
				
			|||||||
		modifier(to_utf8(prefix), to_utf8(suffix));
 | 
							modifier(to_utf8(prefix), to_utf8(suffix));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto spinbox::_m_caption() const throw() -> native_string_type
 | 
						auto spinbox::_m_caption() const noexcept -> native_string_type
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		internal_scope_guard lock;
 | 
							internal_scope_guard lock;
 | 
				
			||||||
		auto editor = get_drawer_trigger().impl()->editor();
 | 
							auto editor = get_drawer_trigger().impl()->editor();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *	A Tabbar Implementation
 | 
					 *	A Tabbar Implementation
 | 
				
			||||||
 *	Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -1489,7 +1489,12 @@ namespace nana
 | 
				
			|||||||
							}
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							graph.rectangle(r, true);
 | 
												graph.rectangle(r, true);
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
												graph.bidi_string({ m.pos_ends.first + 5, 0 }, m.text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
							graph.bidi_string({ m.pos_ends.first + 5, 0 }, m.text.data(), m.text.size());
 | 
												graph.bidi_string({ m.pos_ends.first + 5, 0 }, m.text.data(), m.text.size());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							++pos;
 | 
												++pos;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
@ -1533,7 +1538,7 @@ namespace nana
 | 
				
			|||||||
						delete model_;
 | 
											delete model_;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					model* driver::get_model() const throw()
 | 
										model* driver::get_model() const noexcept
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						return model_;
 | 
											return model_;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
				
			|||||||
@ -785,7 +785,7 @@ namespace drawerbase {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//Override _m_caption for caption()
 | 
							//Override _m_caption for caption()
 | 
				
			||||||
		auto textbox::_m_caption() const throw() -> native_string_type
 | 
							auto textbox::_m_caption() const noexcept -> native_string_type
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			internal_scope_guard lock;
 | 
								internal_scope_guard lock;
 | 
				
			||||||
			auto editor = get_drawer_trigger().editor();
 | 
								auto editor = get_drawer_trigger().editor();
 | 
				
			||||||
 | 
				
			|||||||
@ -1163,7 +1163,11 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				virtual unsigned item_height(graph_reference graph) const override
 | 
									virtual unsigned item_height(graph_reference graph) const override
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										return graph.text_extent_size(std::wstring_view{ L"jH{", 3 }).height + 8;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					return graph.text_extent_size(L"jH{", 3).height + 8;
 | 
										return graph.text_extent_size(L"jH{", 3).height + 8;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				virtual unsigned item_width(graph_reference graph, const item_attribute_t& attr) const override
 | 
									virtual unsigned item_width(graph_reference graph, const item_attribute_t& attr) const override
 | 
				
			||||||
 | 
				
			|||||||
@ -54,12 +54,12 @@ namespace nana
 | 
				
			|||||||
			widget& wdg_;
 | 
								widget& wdg_;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string widget::caption() const throw()
 | 
							std::string widget::caption() const noexcept
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return to_utf8(_m_caption());
 | 
								return to_utf8(_m_caption());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::wstring widget::caption_wstring() const throw()
 | 
							std::wstring widget::caption_wstring() const noexcept
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
#if defined(NANA_WINDOWS)
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
			return _m_caption();
 | 
								return _m_caption();
 | 
				
			||||||
@ -68,7 +68,7 @@ namespace nana
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto widget::caption_native() const throw() -> native_string_type
 | 
							auto widget::caption_native() const noexcept -> native_string_type
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return _m_caption();
 | 
								return _m_caption();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -287,7 +287,7 @@ namespace nana
 | 
				
			|||||||
		void widget::_m_complete_creation()
 | 
							void widget::_m_complete_creation()
 | 
				
			||||||
		{}
 | 
							{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto widget::_m_caption() const throw() -> native_string_type
 | 
							auto widget::_m_caption() const noexcept -> native_string_type
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return API::dev::window_caption(handle());
 | 
								return API::dev::window_caption(handle());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
*	An Implementation of i18n
 | 
					*	An Implementation of i18n
 | 
				
			||||||
*	Nana C++ Library(http://www.nanapro.org)
 | 
					*	Nana C++ Library(http://www.nanapro.org)
 | 
				
			||||||
*	Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
 | 
					*	Copyright(C) 2003-2018 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
 | 
				
			||||||
@ -185,14 +185,17 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				table["NANA_FILEBOX_SAVE_AS"] = "Save As";
 | 
									table["NANA_FILEBOX_SAVE_AS"] = "Save As";
 | 
				
			||||||
				table["NANA_FILEBOX_OPEN"] = "Open";
 | 
									table["NANA_FILEBOX_OPEN"] = "Open";
 | 
				
			||||||
				table["NANA_FILEBOX_DIRECTORY"] = "Directory";
 | 
									table["NANA_FILEBOX_OPEN_DIRECTORY"] = "Select A Directory";
 | 
				
			||||||
				table["NANA_FILEBOX_FILE"] = "File";
 | 
									table["NANA_FILEBOX_FILE"] = "File";
 | 
				
			||||||
				table["NANA_FILEBOX_FILE_COLON"] = "File:";
 | 
									table["NANA_FILEBOX_FILE_COLON"] = "File:";
 | 
				
			||||||
 | 
									table["NANA_FILEBOX_DIRECTORY"] = "Directory";
 | 
				
			||||||
 | 
									table["NANA_FILEBOX_DIRECTORY_COLON"] = "Directory:";
 | 
				
			||||||
				table["NANA_FILEBOX_ERROR_INVALID_FOLDER_NAME"] = "Please input a valid name for the new folder.";
 | 
									table["NANA_FILEBOX_ERROR_INVALID_FOLDER_NAME"] = "Please input a valid name for the new folder.";
 | 
				
			||||||
				table["NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_EXISTING"] = "The folder is existing, please rename it.";
 | 
									table["NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_EXISTING"] = "The folder is existing, please rename it.";
 | 
				
			||||||
				table["NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_FAILED_CREATION"] = "Failed to create the folder, please rename it.";
 | 
									table["NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_FAILED_CREATION"] = "Failed to create the folder, please rename it.";
 | 
				
			||||||
				table["NANA_FILEBOX_ERROR_INVALID_FILENAME"] = "The filename is invalid.";
 | 
									table["NANA_FILEBOX_ERROR_INVALID_FILENAME"] = "The filename is invalid.";
 | 
				
			||||||
				table["NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY"] = "The file \"%arg0\"\n is not existing. Please check and retry.";
 | 
									table["NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY"] = "The file \"%arg0\"\n is not existing. Please check and retry.";
 | 
				
			||||||
 | 
									table["NANA_FILEBOX_ERROR_DIRECTORY_NOT_EXISTING_AND_RETRY"] = "The directory \"%arg0\"\n is not existing. Please check and retry.";
 | 
				
			||||||
				table["NANA_FILEBOX_ERROR_QUERY_REWRITE_BECAUSE_OF_EXISTING"] = "The input file is existing, do you want to overwrite it?";
 | 
									table["NANA_FILEBOX_ERROR_QUERY_REWRITE_BECAUSE_OF_EXISTING"] = "The input file is existing, do you want to overwrite it?";
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -414,45 +417,47 @@ namespace nana
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>&) const
 | 
					#ifndef _nana_cxx_folding_expression
 | 
				
			||||||
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>&)
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, const char* arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, const char* arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(arg);
 | 
							v.emplace_back(arg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::string& arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::string& arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(arg);
 | 
							v.emplace_back(arg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string& arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string& arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(arg);
 | 
							v.emplace_back(arg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string&& arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, std::string&& arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(std::move(arg));
 | 
							v.emplace_back(std::move(arg));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, const wchar_t* arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, const wchar_t* arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(to_utf8(arg));
 | 
							v.emplace_back(to_utf8(arg));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::wstring& arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, const std::wstring& arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(to_utf8(arg));
 | 
							v.emplace_back(to_utf8(arg));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring& arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring& arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(to_utf8(arg));
 | 
							v.emplace_back(to_utf8(arg));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring&& arg) const
 | 
						void internationalization::_m_fetch_args(std::vector<std::string>& v, std::wstring&& arg)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		v.emplace_back(to_utf8(arg));
 | 
							v.emplace_back(to_utf8(arg));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -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-2017 Jinhao(cnjinhao@hotmail.com)
 | 
					 *	Copyright(C) 2003-2018 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 
 | 
				
			||||||
@ -134,20 +134,54 @@ namespace detail
 | 
				
			|||||||
		pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, point{r.x, r.y});
 | 
							pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, point{r.x, r.y});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nana::size raw_text_extent_size(drawable_type dw, const wchar_t* text, std::size_t len)
 | 
						nana::size real_text_extent_size(drawable_type dw, const wchar_t* text, std::size_t len)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if(nullptr == dw || nullptr == text || 0 == len) return nana::size();
 | 
							if (dw && text && len)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(NANA_WINDOWS)
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
			::SIZE size;
 | 
								::SIZE size;
 | 
				
			||||||
			if (::GetTextExtentPoint32(dw->context, text, static_cast<int>(len), &size))
 | 
								if (::GetTextExtentPoint32(dw->context, text, static_cast<int>(len), &size))
 | 
				
			||||||
				return nana::size(size.cx, size.cy);
 | 
									return nana::size(size.cx, size.cy);
 | 
				
			||||||
#elif defined(NANA_X11)
 | 
					#elif defined(NANA_X11)
 | 
				
			||||||
 | 
								std::string utf8text = to_utf8(std::wstring(text, len));
 | 
				
			||||||
#if defined(NANA_USE_XFT)
 | 
					#if defined(NANA_USE_XFT)
 | 
				
			||||||
		std::string utf8str = to_utf8(std::wstring(text, len));
 | 
					 | 
				
			||||||
			XGlyphInfo ext;
 | 
								XGlyphInfo ext;
 | 
				
			||||||
			XftFont * fs = reinterpret_cast<XftFont*>(dw->font->native_handle());
 | 
								XftFont * fs = reinterpret_cast<XftFont*>(dw->font->native_handle());
 | 
				
			||||||
			::XftTextExtentsUtf8(nana::detail::platform_spec::instance().open_display(), fs,
 | 
								::XftTextExtentsUtf8(nana::detail::platform_spec::instance().open_display(), fs,
 | 
				
			||||||
								reinterpret_cast<XftChar8*>(const_cast<char*>(utf8str.c_str())), utf8str.size(), &ext);
 | 
									reinterpret_cast<XftChar8*>(const_cast<char*>(utf8text.data())), utf8text.size(), &ext);
 | 
				
			||||||
 | 
								return nana::size(ext.xOff, fs->ascent + fs->descent);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
								XRectangle ink;
 | 
				
			||||||
 | 
								XRectangle logic;
 | 
				
			||||||
 | 
								::XmbTextExtents(reinterpret_cast<XFontSet>(dw->font->native_handle()), utf8text.c_str(), utf8text.size(), &ink, &logic);
 | 
				
			||||||
 | 
								return nana::size(logic.width, logic.height);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nana::size real_text_extent_size(drawable_type dw, const char* text, std::size_t len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (dw && text && len)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								auto wstr = to_wstring(std::string_view(text, len));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
								auto wstr = to_wstring(std::string(text,len));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								::SIZE size;
 | 
				
			||||||
 | 
								if (::GetTextExtentPoint32(dw->context, wstr.c_str(), static_cast<int>(wstr.size()), &size))
 | 
				
			||||||
 | 
									return nana::size(size.cx, size.cy);
 | 
				
			||||||
 | 
					#elif defined(NANA_X11)
 | 
				
			||||||
 | 
					#if defined(NANA_USE_XFT)
 | 
				
			||||||
 | 
								XGlyphInfo ext;
 | 
				
			||||||
 | 
								XftFont * fs = reinterpret_cast<XftFont*>(dw->font->native_handle());
 | 
				
			||||||
 | 
								::XftTextExtentsUtf8(nana::detail::platform_spec::instance().open_display(), fs,
 | 
				
			||||||
 | 
									reinterpret_cast<XftChar8*>(const_cast<char*>(text)), len, &ext);
 | 
				
			||||||
			return nana::size(ext.xOff, fs->ascent + fs->descent);
 | 
								return nana::size(ext.xOff, fs->ascent + fs->descent);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
			XRectangle ink;
 | 
								XRectangle ink;
 | 
				
			||||||
@ -156,7 +190,28 @@ namespace detail
 | 
				
			|||||||
			return nana::size(logic.width, logic.height);
 | 
								return nana::size(logic.width, logic.height);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		return nana::size();
 | 
							}
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nana::size text_extent_size(drawable_type dw, const char * text, std::size_t len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (nullptr == dw || nullptr == text || 0 == len)
 | 
				
			||||||
 | 
								return{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							nana::size extents = real_text_extent_size(dw, text, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto const end = text + len;
 | 
				
			||||||
 | 
							int tabs = 0;
 | 
				
			||||||
 | 
							for (; text != end; ++text)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (*text == '\t')
 | 
				
			||||||
 | 
									++tabs;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (tabs)
 | 
				
			||||||
 | 
								extents.width = static_cast<int>(extents.width) - tabs * static_cast<int>(dw->string.tab_pixels - dw->string.whitespace_pixels * dw->string.tab_length);
 | 
				
			||||||
 | 
							return extents;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nana::size text_extent_size(drawable_type dw, const wchar_t * text, std::size_t len)
 | 
						nana::size text_extent_size(drawable_type dw, const wchar_t * text, std::size_t len)
 | 
				
			||||||
@ -164,7 +219,7 @@ namespace detail
 | 
				
			|||||||
		if (nullptr == dw || nullptr == text || 0 == len)
 | 
							if (nullptr == dw || nullptr == text || 0 == len)
 | 
				
			||||||
			return{};
 | 
								return{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nana::size extents = raw_text_extent_size(dw, text, len);
 | 
							nana::size extents = real_text_extent_size(dw, text, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const wchar_t* const end = text + len;
 | 
							const wchar_t* const end = text + len;
 | 
				
			||||||
		int tabs = 0;
 | 
							int tabs = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -411,8 +411,8 @@ namespace paint
 | 
				
			|||||||
					impl_->handle = dw.get();
 | 
										impl_->handle = dw.get();
 | 
				
			||||||
					impl_->size = sz;
 | 
										impl_->size = sz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;
 | 
										impl_->handle->string.tab_pixels = detail::real_text_extent_size(impl_->handle, L"\t", 1).width;
 | 
				
			||||||
					impl_->handle->string.whitespace_pixels = detail::raw_text_extent_size(impl_->handle, L" ", 1).width;
 | 
										impl_->handle->string.whitespace_pixels = detail::real_text_extent_size(impl_->handle, L" ", 1).width;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -438,8 +438,9 @@ namespace paint
 | 
				
			|||||||
#if defined(NANA_WINDOWS)
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
				::SelectObject(impl_->handle->context, reinterpret_cast<HFONT>(f.impl_->real_font->native_handle()));
 | 
									::SelectObject(impl_->handle->context, reinterpret_cast<HFONT>(f.impl_->real_font->native_handle()));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
				impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;
 | 
					
 | 
				
			||||||
				impl_->handle->string.whitespace_pixels = detail::raw_text_extent_size(impl_->handle, L" ", 1).width;
 | 
									impl_->handle->string.tab_pixels = detail::real_text_extent_size(impl_->handle, L"\t", 1).width;
 | 
				
			||||||
 | 
									impl_->handle->string.whitespace_pixels = detail::real_text_extent_size(impl_->handle, L" ", 1).width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (impl_->changed == false)
 | 
									if (impl_->changed == false)
 | 
				
			||||||
					impl_->changed = true;
 | 
										impl_->changed = true;
 | 
				
			||||||
@ -453,6 +454,114 @@ namespace paint
 | 
				
			|||||||
			return (impl_->handle ? font(impl_->handle) : impl_->font_shadow);
 | 
								return (impl_->handle ? font(impl_->handle) : impl_->font_shadow);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
							size graphics::text_extent_size(std::string_view text) const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								throw_not_utf8(text);
 | 
				
			||||||
 | 
								return detail::text_extent_size(impl_->handle, text.data(), text.length());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size graphics::text_extent_size(std::wstring_view text) const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return detail::text_extent_size(impl_->handle, text.data(), text.length());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							nana::size graphics::glyph_extent_size(std::wstring_view text, std::size_t begin, std::size_t end) const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								end = std::clamp(end, static_cast<std::size_t>(0), static_cast<std::size_t>(text.size()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (nullptr == impl_->handle || text.empty() || begin >= end) return{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								nana::size sz;
 | 
				
			||||||
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
 | 
								int * dx = new int[text.size()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SIZE extents;
 | 
				
			||||||
 | 
								::GetTextExtentExPoint(impl_->handle->context, text.data(), static_cast<int>(text.size()), 0, 0, dx, &extents);
 | 
				
			||||||
 | 
								sz.width = dx[end - 1] - (begin ? dx[begin - 1] : 0);
 | 
				
			||||||
 | 
								unsigned tab_pixels = impl_->handle->string.tab_length * impl_->handle->string.whitespace_pixels;
 | 
				
			||||||
 | 
								const wchar_t * pend = text.data() + end;
 | 
				
			||||||
 | 
								for (const wchar_t * p = text.data() + begin; p != pend; ++p)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (*p == '\t')
 | 
				
			||||||
 | 
										sz.width += tab_pixels;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sz.height = extents.cy;
 | 
				
			||||||
 | 
								delete[] dx;
 | 
				
			||||||
 | 
					#elif defined(NANA_X11)
 | 
				
			||||||
 | 
								sz = text_extent_size(text.substr(begin, end - begin));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								return sz;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::unique_ptr<unsigned[]> graphics::glyph_pixels(std::wstring_view text) const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (nullptr == impl_->handle || nullptr == impl_->handle->context) return {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (text.empty()) return std::unique_ptr<unsigned[]>{new unsigned[1]};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								unsigned tab_pixels = impl_->handle->string.tab_length * impl_->handle->string.whitespace_pixels;
 | 
				
			||||||
 | 
					#if defined(NANA_WINDOWS)
 | 
				
			||||||
 | 
								int * dx = new int[text.size()];
 | 
				
			||||||
 | 
								SIZE extents;
 | 
				
			||||||
 | 
								::GetTextExtentExPoint(impl_->handle->context, text.data(), static_cast<int>(text.size()), 0, 0, dx, &extents);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								auto pxbuf = std::unique_ptr<unsigned[]>{ new unsigned[text.size()] };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								pxbuf[0] = (text[0] == '\t' ? tab_pixels : dx[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (std::size_t i = 1; i < text.size(); ++i)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									pxbuf[i] = (text[i] == '\t' ? tab_pixels : dx[i] - dx[i - 1]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								delete[] dx;
 | 
				
			||||||
 | 
					#elif defined(NANA_X11) && defined(NANA_USE_XFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								auto disp = nana::detail::platform_spec::instance().open_display();
 | 
				
			||||||
 | 
								auto xft = reinterpret_cast<XftFont*>(impl_->handle->font->native_handle());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								XGlyphInfo extents;
 | 
				
			||||||
 | 
								for (std::size_t i = 0; i < len; ++i)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (text[i] != '\t')
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										FT_UInt glyphs = ::XftCharIndex(disp, xft, text[i]);
 | 
				
			||||||
 | 
										::XftGlyphExtents(disp, xft, &glyphs, 1, &extents);
 | 
				
			||||||
 | 
										pxbuf[i] = extents.xOff;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										pxbuf[i] = tab_pixels;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								return pxbuf;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							::nana::size graphics::bidi_extent_size(std::string_view utf8str) const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return bidi_extent_size(to_wstring(utf8str));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							nana::size	graphics::bidi_extent_size(std::wstring_view text) const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								nana::size sz;
 | 
				
			||||||
 | 
								if (impl_->handle && impl_->handle->context && text.size())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									auto const reordered = unicode_reorder(text.data(), text.size());
 | 
				
			||||||
 | 
									for (auto & i : reordered)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										nana::size t = text_extent_size(std::wstring_view(i.begin, i.end - i.begin));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
										nana::size t = text_extent_size(i.begin, i.end - i.begin);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
										sz.width += t.width;
 | 
				
			||||||
 | 
										if (sz.height < t.height)
 | 
				
			||||||
 | 
											sz.height = t.height;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return sz;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		::nana::size graphics::text_extent_size(const ::std::string& text) const
 | 
							::nana::size graphics::text_extent_size(const ::std::string& text) const
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			throw_not_utf8(text);
 | 
								throw_not_utf8(text);
 | 
				
			||||||
@ -562,7 +671,11 @@ namespace paint
 | 
				
			|||||||
				auto const reordered = unicode_reorder(str.c_str(), str.size());
 | 
									auto const reordered = unicode_reorder(str.c_str(), str.size());
 | 
				
			||||||
				for (auto & i : reordered)
 | 
									for (auto & i : reordered)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										nana::size t = text_extent_size(std::wstring_view(i.begin, i.end - i.begin));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					nana::size t = text_extent_size(i.begin, i.end - i.begin);
 | 
										nana::size t = text_extent_size(i.begin, i.end - i.begin);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
					sz.width += t.width;
 | 
										sz.width += t.width;
 | 
				
			||||||
					if (sz.height < t.height)
 | 
										if (sz.height < t.height)
 | 
				
			||||||
						sz.height = t.height;
 | 
											sz.height = t.height;
 | 
				
			||||||
@ -575,6 +688,7 @@ namespace paint
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			return bidi_extent_size(static_cast<std::wstring>(::nana::charset(str, ::nana::unicode::utf8)));
 | 
								return bidi_extent_size(static_cast<std::wstring>(::nana::charset(str, ::nana::unicode::utf8)));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif	//end _nana_std_has_string_view
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool graphics::text_metrics(unsigned & ascent, unsigned& descent, unsigned& internal_leading) const
 | 
							bool graphics::text_metrics(unsigned & ascent, unsigned& descent, unsigned& internal_leading) const
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -937,7 +1051,7 @@ namespace paint
 | 
				
			|||||||
			impl_->size.width = impl_->size.height = 0;
 | 
								impl_->size.width = impl_->size.height = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void graphics::save_as_file(const char* file_utf8) const throw()
 | 
							void graphics::save_as_file(const char* file_utf8) const noexcept
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if(impl_->handle)
 | 
								if(impl_->handle)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@ -1003,25 +1117,6 @@ namespace paint
 | 
				
			|||||||
			return *this;
 | 
								return *this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		unsigned graphics::bidi_string(const nana::point& pos, const wchar_t * str, std::size_t len)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			auto moved_pos = pos;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			auto const reordered = unicode_reorder(str, len);
 | 
					 | 
				
			||||||
			for (auto & i : reordered)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				string(moved_pos, i.begin, i.end - i.begin);
 | 
					 | 
				
			||||||
				moved_pos.x += static_cast<int>(text_extent_size(i.begin, i.end - i.begin).width);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return static_cast<unsigned>(moved_pos.x - pos.x);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		unsigned graphics::bidi_string(const point& pos, const char* str, std::size_t len)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			std::wstring wstr = ::nana::charset(std::string(str, str + len), ::nana::unicode::utf8);
 | 
					 | 
				
			||||||
			return bidi_string(pos, wstr.data(), wstr.size());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void graphics::set_pixel(int x, int y, const ::nana::color& clr)
 | 
							void graphics::set_pixel(int x, int y, const ::nana::color& clr)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (impl_->handle)
 | 
								if (impl_->handle)
 | 
				
			||||||
@ -1046,6 +1141,116 @@ namespace paint
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
							unsigned graphics::bidi_string(const point& pos, std::string_view utf8str)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return bidi_string(pos, to_wstring(utf8str));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unsigned graphics::bidi_string(const nana::point& pos, std::wstring_view str)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto moved_pos = pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								auto const reordered = unicode_reorder(str.data(), str.size());
 | 
				
			||||||
 | 
								for (auto & i : reordered)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									this->string(moved_pos, std::wstring_view{ i.begin, static_cast<std::wstring_view::size_type>(i.end - i.begin) });
 | 
				
			||||||
 | 
									moved_pos.x += static_cast<int>(text_extent_size(std::wstring_view(i.begin, i.end - i.begin)).width);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
									this->string(moved_pos, i.begin, i.end - i.begin);
 | 
				
			||||||
 | 
									moved_pos.x += static_cast<int>(text_extent_size(i.begin, i.end - i.begin).width);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return static_cast<unsigned>(moved_pos.x - pos.x);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void graphics::string(const point& pos, std::string_view utf8str)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this->string(pos, to_wstring(utf8str));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void graphics::string(const point& pos, std::string_view utf8str, const nana::color& text_color)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								palette(true, text_color);
 | 
				
			||||||
 | 
								string(pos, utf8str);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void graphics::string(const nana::point& text_pos, std::wstring_view str)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (impl_->handle && !str.empty())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
					#if defined(NANA_POSIX)
 | 
				
			||||||
 | 
									impl_->handle->update_text_color();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
									auto begin = str.data();
 | 
				
			||||||
 | 
									auto const end = begin + str.size();
 | 
				
			||||||
 | 
									auto i = std::find(begin, end, '\t');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (i != end)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										auto pos = text_pos;
 | 
				
			||||||
 | 
										std::size_t tab_pixels = impl_->handle->string.tab_length * impl_->handle->string.tab_pixels;
 | 
				
			||||||
 | 
										while (true)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											auto len = i - begin;
 | 
				
			||||||
 | 
											if (len)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												//Render a part that does not contains a tab
 | 
				
			||||||
 | 
												detail::draw_string(impl_->handle, pos, begin, len);
 | 
				
			||||||
 | 
												pos.x += detail::real_text_extent_size(impl_->handle, begin, len).width;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											begin = i;
 | 
				
			||||||
 | 
											while (begin != end && (*begin == '\t'))
 | 
				
			||||||
 | 
												++begin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											if (begin != end)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												//Now i_tab is not a tab, but a non-tab character following the previous tabs
 | 
				
			||||||
 | 
												pos.x += static_cast<int>(tab_pixels * (begin - i));
 | 
				
			||||||
 | 
												i = std::find(begin, end, '\t');
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
												break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										detail::draw_string(impl_->handle, text_pos, str.data(), str.size());
 | 
				
			||||||
 | 
									if (impl_->changed == false) impl_->changed = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void graphics::string(const point& pos, std::wstring_view str, const nana::color& text_color)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								palette(true, text_color);
 | 
				
			||||||
 | 
								string(pos, str);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							unsigned graphics::bidi_string(const nana::point& pos, const wchar_t * str, std::size_t len)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto moved_pos = pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								auto const reordered = unicode_reorder(str, len);
 | 
				
			||||||
 | 
								for (auto & i : reordered)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									string(moved_pos, i.begin, i.end - i.begin);
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									moved_pos.x += static_cast<int>(text_extent_size(std::wstring_view(i.begin, i.end - i.begin)).width);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
									moved_pos.x += static_cast<int>(text_extent_size(i.begin, i.end - i.begin).width);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return static_cast<unsigned>(moved_pos.x - pos.x);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unsigned graphics::bidi_string(const point& pos, const char* str, std::size_t len)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								std::wstring wstr = ::nana::charset(std::string(str, str + len), ::nana::unicode::utf8);
 | 
				
			||||||
 | 
								return bidi_string(pos, wstr.data(), wstr.size());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void graphics::string(const point& pos, const std::string& text_utf8)
 | 
							void graphics::string(const point& pos, const std::string& text_utf8)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			string(pos, to_wstring(text_utf8));
 | 
								string(pos, to_wstring(text_utf8));
 | 
				
			||||||
@ -1076,7 +1281,7 @@ namespace paint
 | 
				
			|||||||
						{
 | 
											{
 | 
				
			||||||
							//Render a part that does not contains a tab
 | 
												//Render a part that does not contains a tab
 | 
				
			||||||
							detail::draw_string(impl_->handle, pos, str, len);
 | 
												detail::draw_string(impl_->handle, pos, str, len);
 | 
				
			||||||
							pos.x += detail::raw_text_extent_size(impl_->handle, str, len).width;
 | 
												pos.x += detail::real_text_extent_size(impl_->handle, str, len).width;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						str = i;
 | 
											str = i;
 | 
				
			||||||
@ -1114,6 +1319,7 @@ namespace paint
 | 
				
			|||||||
			palette(true, clr);
 | 
								palette(true, clr);
 | 
				
			||||||
			string(pos, text.data(), text.size());
 | 
								string(pos, text.data(), text.size());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif //_nana_std_has_string_view
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void graphics::line(const nana::point& pos1, const nana::point& pos2)
 | 
							void graphics::line(const nana::point& pos1, const nana::point& pos2)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ namespace nana
 | 
				
			|||||||
						{
 | 
											{
 | 
				
			||||||
							std::size_t len = ent.end - ent.begin;
 | 
												std::size_t len = ent.end - ent.begin;
 | 
				
			||||||
							nana::size ts = detail::text_extent_size(dw, ent.begin, len);
 | 
												nana::size ts = detail::text_extent_size(dw, ent.begin, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							if(ts.height > pixels)	pixels = ts.height;
 | 
												if(ts.height > pixels)	pixels = ts.height;
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
							if(pos.x + static_cast<int>(ts.width) > 0)
 | 
												if(pos.x + static_cast<int>(ts.width) > 0)
 | 
				
			||||||
@ -128,7 +129,11 @@ namespace nana
 | 
				
			|||||||
				draw_string_omitted(graphics& graph, int x, int endpos, bool omitted)
 | 
									draw_string_omitted(graphics& graph, int x, int endpos, bool omitted)
 | 
				
			||||||
					: graph(graph), x(x), endpos(endpos)
 | 
										: graph(graph), x(x), endpos(endpos)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
										omitted_pixels = (omitted ? graph.text_extent_size(std::string_view{ "...", 3 }).width : 0);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
					omitted_pixels = (omitted ? graph.text_extent_size("...", 3).width : 0);
 | 
										omitted_pixels = (omitted ? graph.text_extent_size("...", 3).width : 0);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
					if (endpos - x > static_cast<int>(omitted_pixels))
 | 
										if (endpos - x > static_cast<int>(omitted_pixels))
 | 
				
			||||||
						this->endpos -= omitted_pixels;
 | 
											this->endpos -= omitted_pixels;
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
@ -164,8 +169,12 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
							dum_graph.bitblt(r, graph, pos);
 | 
												dum_graph.bitblt(r, graph, pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
												dum_graph.string({}, { i.begin, len }, graph.palette(true));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
							dum_graph.palette(true, graph.palette(true));
 | 
												dum_graph.palette(true, graph.palette(true));
 | 
				
			||||||
							dum_graph.string({}, i.begin, len);
 | 
												dum_graph.string({}, i.begin, len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							r.x = pos.x;
 | 
												r.x = pos.x;
 | 
				
			||||||
							r.y = top;
 | 
												r.y = top;
 | 
				
			||||||
@ -228,10 +237,14 @@ namespace nana
 | 
				
			|||||||
								const std::size_t len = i.end - i.begin;
 | 
													const std::size_t len = i.end - i.begin;
 | 
				
			||||||
								if(len > 1)
 | 
													if(len > 1)
 | 
				
			||||||
								{
 | 
													{
 | 
				
			||||||
									std::unique_ptr<unsigned[]> pixel_buf(new unsigned[len]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
									//Find the char that should be splitted
 | 
														//Find the char that should be splitted
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
														auto pixel_buf = graph.glyph_pixels({ i.begin, len });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
														std::unique_ptr<unsigned[]> pixel_buf(new unsigned[len]);
 | 
				
			||||||
									graph.glyph_pixels(i.begin, len, pixel_buf.get());
 | 
														graph.glyph_pixels(i.begin, len, pixel_buf.get());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									std::size_t idx_head = 0, idx_splitted;
 | 
														std::size_t idx_head = 0, idx_splitted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									do
 | 
														do
 | 
				
			||||||
@ -448,10 +461,16 @@ namespace nana
 | 
				
			|||||||
								std::size_t len = i.end - i.begin;
 | 
													std::size_t len = i.end - i.begin;
 | 
				
			||||||
								if(len > 1)
 | 
													if(len > 1)
 | 
				
			||||||
								{
 | 
													{
 | 
				
			||||||
 | 
														//Find the char that should be splitted
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
														auto scope_res = graph.glyph_pixels({ i.begin, len });
 | 
				
			||||||
 | 
														auto pxbuf = scope_res.get();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
									std::unique_ptr<unsigned[]> scope_res(new unsigned[len]);
 | 
														std::unique_ptr<unsigned[]> scope_res(new unsigned[len]);
 | 
				
			||||||
									auto pxbuf = scope_res.get();
 | 
														auto pxbuf = scope_res.get();
 | 
				
			||||||
									//Find the char that should be splitted
 | 
					 | 
				
			||||||
									graph.glyph_pixels(i.begin, len, pxbuf);
 | 
														graph.glyph_pixels(i.begin, len, pxbuf);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									std::size_t idx_head = 0, idx_splitted;
 | 
														std::size_t idx_head = 0, idx_splitted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
									do
 | 
														do
 | 
				
			||||||
@ -625,14 +644,23 @@ namespace nana
 | 
				
			|||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									graph_.bidi_string(pos, text);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				graph_.bidi_string(pos, text.c_str(), text.size());
 | 
									graph_.bidi_string(pos, text.c_str(), text.size());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
								const auto ellipsis = graph_.text_extent_size(std::string_view{ "...", 3 }).width;
 | 
				
			||||||
 | 
								auto pixels = graph_.glyph_pixels({ text.c_str(), text.size() });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
			const auto ellipsis = graph_.text_extent_size("...", 3).width;
 | 
								const auto ellipsis = graph_.text_extent_size("...", 3).width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::unique_ptr<unsigned[]> pixels(new unsigned[text.size()]);
 | 
								std::unique_ptr<unsigned[]> pixels(new unsigned[text.size()]);
 | 
				
			||||||
			graph_.glyph_pixels(text.c_str(), text.size(), pixels.get());
 | 
								graph_.glyph_pixels(text.c_str(), text.size(), pixels.get());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::size_t substr_len = 0;
 | 
								std::size_t substr_len = 0;
 | 
				
			||||||
			unsigned substr_px = 0;
 | 
								unsigned substr_px = 0;
 | 
				
			||||||
@ -653,7 +681,11 @@ namespace nana
 | 
				
			|||||||
				} while (p != end);
 | 
									} while (p != end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				pos.x += static_cast<int>(width - ellipsis - substr_px) + ellipsis;
 | 
									pos.x += static_cast<int>(width - ellipsis - substr_px) + ellipsis;
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									graph_.bidi_string(pos, { text.c_str() + substr_len, text.size() - substr_len });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				graph_.bidi_string(pos, text.c_str() + substr_len, text.size() - substr_len);
 | 
									graph_.bidi_string(pos, text.c_str() + substr_len, text.size() - substr_len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				pos.x -= ellipsis;
 | 
									pos.x -= ellipsis;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
@ -670,8 +702,11 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if (align::center == text_align_ex_)
 | 
									if (align::center == text_align_ex_)
 | 
				
			||||||
					pos.x += (width - substr_px - ellipsis) / 2;
 | 
										pos.x += (width - substr_px - ellipsis) / 2;
 | 
				
			||||||
 | 
					#ifdef _nana_std_has_string_view
 | 
				
			||||||
 | 
									graph_.bidi_string(pos, { text.c_str(), substr_len });
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
				graph_.bidi_string(pos, text.c_str(), substr_len);
 | 
									graph_.bidi_string(pos, text.c_str(), substr_len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				pos.x += substr_px;
 | 
									pos.x += substr_px;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -426,7 +426,7 @@ namespace std
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _enable_std_put_time
 | 
					#ifdef _nana_std_put_time
 | 
				
			||||||
#include <cwchar>
 | 
					#include <cwchar>
 | 
				
			||||||
namespace std
 | 
					namespace std
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user