Merge branch 'feature-fit-content' into develop
This commit is contained in:
commit
f45762fdb0
@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* Predefined Symbols for C++
|
* Predefined Symbols for C++
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2016-2017 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
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*
|
*
|
||||||
* @file nana/config.hpp
|
* @file nana/c++defines.hpp
|
||||||
*
|
*
|
||||||
* @brief Provide switches to adapt to the target OS, use of external libraries or workarounds compiler errors or lack of std C++ support.
|
* @brief Provide switches to adapt to the target OS, use of external libraries or workarounds compiler errors or lack of std C++ support.
|
||||||
*
|
*
|
||||||
@ -31,13 +31,14 @@
|
|||||||
* - _SCL_SECURE_NO_WARNNGS, _CRT_SECURE_NO_DEPRECATE (VC)
|
* - _SCL_SECURE_NO_WARNNGS, _CRT_SECURE_NO_DEPRECATE (VC)
|
||||||
* - STD_CODECVT_NOT_SUPPORTED (VC RC, <codecvt> is a known issue on libstdc++, it works on libc++)
|
* - STD_CODECVT_NOT_SUPPORTED (VC RC, <codecvt> is a known issue on libstdc++, it works on libc++)
|
||||||
* - STD_THREAD_NOT_SUPPORTED (GCC < 4.8.1)
|
* - STD_THREAD_NOT_SUPPORTED (GCC < 4.8.1)
|
||||||
* - STD_put_time_NOT_SUPPORTED (GCC < 5)
|
|
||||||
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
|
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
|
||||||
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
|
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
|
||||||
* - 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)
|
||||||
* - STD_MAKE_UNIQUE_NOT_SUPPORTED (GCC < 4.9)
|
* - _enable_std_make_unique (GCC < 4.9)
|
||||||
|
* - _enable_std_put_time (GCC < 5)
|
||||||
|
* - _enable_std_clamp (Visual C++ < 2017)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NANA_CXX_DEFINES_INCLUDED
|
#ifndef NANA_CXX_DEFINES_INCLUDED
|
||||||
@ -57,7 +58,7 @@
|
|||||||
# define CXX_NO_INLINE_NAMESPACE //no support of C++11 inline namespace until Visual C++ 2015
|
# define CXX_NO_INLINE_NAMESPACE //no support of C++11 inline namespace until Visual C++ 2015
|
||||||
# define noexcept //no support of noexcept until Visual C++ 2015
|
# define noexcept //no support of noexcept until Visual C++ 2015
|
||||||
|
|
||||||
# define constexpr const //no support of constexpr until Visual C++ 2015 ? const ??
|
# define constexpr //no support of constexpr until Visual C++ 2015 ? const ??
|
||||||
# else
|
# else
|
||||||
# undef STD_FILESYSTEM_NOT_SUPPORTED
|
# undef STD_FILESYSTEM_NOT_SUPPORTED
|
||||||
# endif
|
# endif
|
||||||
@ -102,14 +103,18 @@
|
|||||||
#define _CRT_SECURE_NO_DEPRECATE
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
#pragma warning(disable : 4996)
|
#pragma warning(disable : 4996)
|
||||||
|
|
||||||
#if (_MSC_VER >= 1900)
|
# if (_MSC_VER >= 1900)
|
||||||
// google: break any code that tries to use codecvt<char16_t> or codecvt<char32_t>.
|
// google: break any code that tries to use codecvt<char16_t> or codecvt<char32_t>.
|
||||||
// google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support.
|
// google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support.
|
||||||
// google: Those definitions are for codecvt<wchar_t>::id, codecvt<unsigned short>::id and codecvt<char>::id respectively.
|
// google: Those definitions are for codecvt<wchar_t>::id, codecvt<unsigned short>::id and codecvt<char>::id respectively.
|
||||||
// However, the codecvt<char16_t>::id and codecvt<char32_t>::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all.
|
// However, the codecvt<char16_t>::id and codecvt<char32_t>::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all.
|
||||||
// google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources.
|
// google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources.
|
||||||
#define STD_CODECVT_NOT_SUPPORTED
|
# define STD_CODECVT_NOT_SUPPORTED
|
||||||
#endif // _MSC_VER == 1900
|
# endif // _MSC_VER == 1900
|
||||||
|
|
||||||
|
# if (_MSC_VER < 1910) //VS2017 RTM
|
||||||
|
# define _enable_std_clamp
|
||||||
|
# endif
|
||||||
|
|
||||||
#elif defined(__clang__) //Clang
|
#elif defined(__clang__) //Clang
|
||||||
|
|
||||||
@ -119,13 +124,15 @@
|
|||||||
#define STD_CODECVT_NOT_SUPPORTED
|
#define STD_CODECVT_NOT_SUPPORTED
|
||||||
|
|
||||||
#if !defined(__cpp_lib_make_unique) || (__cpp_lib_make_unique != 201304)
|
#if !defined(__cpp_lib_make_unique) || (__cpp_lib_make_unique != 201304)
|
||||||
#ifndef STD_MAKE_UNIQUE_NOT_SUPPORTED
|
#ifndef _enable_std_make_unique
|
||||||
#define STD_MAKE_UNIQUE_NOT_SUPPORTED
|
#define _enable_std_make_unique
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
# define _enable_std_clamp
|
||||||
|
|
||||||
#elif defined(__GNUC__) //GCC
|
#elif defined(__GNUC__) //GCC
|
||||||
|
|
||||||
#include <iosfwd> //Introduces some implement-specific flags of ISO C++ Library
|
#include <iosfwd> //Introduces some implement-specific flags of ISO C++ Library
|
||||||
@ -145,9 +152,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if ((__GNUC__ < 5) )
|
# if ((__GNUC__ < 5) )
|
||||||
# define STD_put_time_NOT_SUPPORTED
|
# define _enable_std_put_time
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
|
#if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
|
||||||
# undef STD_FILESYSTEM_NOT_SUPPORTED
|
# undef STD_FILESYSTEM_NOT_SUPPORTED
|
||||||
@ -160,7 +167,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (__GNUC_MINOR__ < 9)
|
#if (__GNUC_MINOR__ < 9)
|
||||||
#define STD_MAKE_UNIQUE_NOT_SUPPORTED
|
#define _enable_std_make_unique
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(NANA_MINGW)
|
#if defined(NANA_MINGW)
|
||||||
@ -181,6 +188,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
# define _enable_std_clamp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,99 +17,10 @@
|
|||||||
#include <nana/push_ignore_diagnostic>
|
#include <nana/push_ignore_diagnostic>
|
||||||
|
|
||||||
#include <nana/config.hpp>
|
#include <nana/config.hpp>
|
||||||
|
#include <nana/stdc++.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <nana/charset.hpp>
|
#include <nana/charset.hpp>
|
||||||
|
|
||||||
//Implement workarounds for GCC/MinGW which version is below 4.8.2
|
|
||||||
#if defined(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED)
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
//Workaround for no implemenation of std::stoi in MinGW.
|
|
||||||
int stoi(const std::string&, std::size_t * pos = nullptr, int base = 10);
|
|
||||||
int stoi(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stof in MinGW.
|
|
||||||
float stof(const std::string&, std::size_t * pos = nullptr);
|
|
||||||
float stof(const std::wstring&, std::size_t* pos = nullptr);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stod in MinGW.
|
|
||||||
double stod(const std::string&, std::size_t * pos = nullptr);
|
|
||||||
double stod(const std::wstring&, std::size_t* pos = nullptr);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stold in MinGW.
|
|
||||||
long double stold(const std::string&, std::size_t * pos = nullptr);
|
|
||||||
long double stold(const std::wstring&, std::size_t* pos = nullptr);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stol in MinGW.
|
|
||||||
long stol(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
long stol(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stoll in MinGW.
|
|
||||||
long long stoll(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
long long stoll(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stoul in MinGW.
|
|
||||||
unsigned long stoul(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
unsigned long stoul(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stoull in MinGW.
|
|
||||||
unsigned long long stoull(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
unsigned long long stoull(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
|
||||||
}
|
|
||||||
#endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
|
|
||||||
|
|
||||||
#ifdef STD_TO_STRING_NOT_SUPPORTED
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
//Workaround for no implemenation of std::to_string/std::to_wstring in MinGW.
|
|
||||||
std::string to_string(long double);
|
|
||||||
std::string to_string(double);
|
|
||||||
std::string to_string(unsigned);
|
|
||||||
std::string to_string(int);
|
|
||||||
std::string to_string(long);
|
|
||||||
std::string to_string(unsigned long);
|
|
||||||
std::string to_string(long long);
|
|
||||||
std::string to_string(unsigned long long);
|
|
||||||
std::string to_string(float);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
std::wstring to_wstring(long double);
|
|
||||||
std::wstring to_wstring(double);
|
|
||||||
std::wstring to_wstring(unsigned);
|
|
||||||
std::wstring to_wstring(int);
|
|
||||||
std::wstring to_wstring(long);
|
|
||||||
std::wstring to_wstring(unsigned long);
|
|
||||||
std::wstring to_wstring(long long);
|
|
||||||
std::wstring to_wstring(unsigned long long);
|
|
||||||
std::wstring to_wstring(float);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STD_put_time_NOT_SUPPORTED
|
|
||||||
#include <ctime>
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
//Workaround for no implemenation of std::put_time in gcc < 5.
|
|
||||||
/* std unspecified return type */
|
|
||||||
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
|
|
||||||
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
|
|
||||||
|
|
||||||
//template< >
|
|
||||||
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt);
|
|
||||||
|
|
||||||
//Defined in header <ctime>
|
|
||||||
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
|
|
||||||
//template<>
|
|
||||||
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
|
|
||||||
}
|
|
||||||
#endif // STD_put_time_NOT_SUPPORTED
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
/// move to *.h ??
|
/// move to *.h ??
|
||||||
@ -192,45 +103,5 @@ namespace nana
|
|||||||
|
|
||||||
#define NANA_RGB(a) (((DWORD)(a) & 0xFF)<<16) | ((DWORD)(a) & 0xFF00) | (((DWORD)(a) & 0xFF0000) >> 16 )
|
#define NANA_RGB(a) (((DWORD)(a) & 0xFF)<<16) | ((DWORD)(a) & 0xFF00) | (((DWORD)(a) & 0xFF0000) >> 16 )
|
||||||
|
|
||||||
|
|
||||||
#ifdef STD_MAKE_UNIQUE_NOT_SUPPORTED
|
|
||||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template<class T> struct _Unique_if {
|
|
||||||
typedef unique_ptr<T> _Single_object;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T> struct _Unique_if<T[]> {
|
|
||||||
typedef unique_ptr<T[]> _Unknown_bound;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, size_t N> struct _Unique_if<T[N]> {
|
|
||||||
typedef void _Known_bound;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, class... Args>
|
|
||||||
typename _Unique_if<T>::_Single_object
|
|
||||||
make_unique(Args&&... args) {
|
|
||||||
return unique_ptr<T>(new T(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
typename _Unique_if<T>::_Unknown_bound
|
|
||||||
make_unique(size_t n) {
|
|
||||||
typedef typename remove_extent<T>::type U;
|
|
||||||
return unique_ptr<T>(new U[n]());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class... Args>
|
|
||||||
typename _Unique_if<T>::_Known_bound
|
|
||||||
make_unique(Args&&...) = delete;
|
|
||||||
}
|
|
||||||
#endif //STD_make_unique_NOT_SUPPORTED
|
|
||||||
#include <nana/pop_ignore_diagnostic>
|
#include <nana/pop_ignore_diagnostic>
|
||||||
#endif //NANA_DEPLOY_HPP
|
#endif //NANA_DEPLOY_HPP
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 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-2017 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,13 +23,13 @@ namespace filesystem_ext
|
|||||||
{
|
{
|
||||||
|
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
constexpr auto def_root = "C:";
|
constexpr auto const def_root = "C:";
|
||||||
constexpr auto def_rootstr = "C:\\";
|
constexpr auto const def_rootstr = "C:\\";
|
||||||
constexpr auto def_rootname = "Local Drive(C:)";
|
constexpr auto const def_rootname = "Local Drive(C:)";
|
||||||
#elif defined(NANA_LINUX)
|
#elif defined(NANA_LINUX)
|
||||||
constexpr auto def_root = "/";
|
constexpr auto const def_root = "/";
|
||||||
constexpr auto def_rootstr = "/";
|
constexpr auto const def_rootstr = "/";
|
||||||
constexpr auto def_rootname = "Root/";
|
constexpr auto const def_rootname = "Root/";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::experimental::filesystem::path path_user(); ///< extention ?
|
std::experimental::filesystem::path path_user(); ///< extention ?
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "drawer.hpp"
|
#include "drawer.hpp"
|
||||||
#include "events_holder.hpp"
|
#include "events_holder.hpp"
|
||||||
#include "widget_geometrics.hpp"
|
#include "widget_geometrics.hpp"
|
||||||
|
#include "widget_content_measurer_interface.hpp"
|
||||||
#include "widget_notifier_interface.hpp"
|
#include "widget_notifier_interface.hpp"
|
||||||
#include <nana/basic_types.hpp>
|
#include <nana/basic_types.hpp>
|
||||||
#include <nana/system/platform.hpp>
|
#include <nana/system/platform.hpp>
|
||||||
@ -191,6 +192,7 @@ namespace detail
|
|||||||
//The following pointers refer to the widget's object.
|
//The following pointers refer to the widget's object.
|
||||||
std::shared_ptr<general_events> events_ptr;
|
std::shared_ptr<general_events> events_ptr;
|
||||||
widget_geometrics* scheme{ nullptr };
|
widget_geometrics* scheme{ nullptr };
|
||||||
|
::nana::dev::widget_content_measurer_interface* content_measurer{ nullptr };
|
||||||
}annex;
|
}annex;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Widget Content Measurer Interface
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*
|
||||||
|
* @file: nana/gui/detail/widget_content_measurer_interface.hpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NANA_WIDGET_CONTENT_MEASURER_INTERFACE_HEADER_INCLUDED
|
||||||
|
#define NANA_WIDGET_CONTENT_MEASURER_INTERFACE_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <nana/basic_types.hpp>
|
||||||
|
#include <nana/optional.hpp>
|
||||||
|
#include <nana/paint/graphics.hpp>
|
||||||
|
|
||||||
|
namespace nana
|
||||||
|
{
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
/// An interface for measuring content of the widget
|
||||||
|
class widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using graph_reference = paint::graphics&;
|
||||||
|
virtual ~widget_content_measurer_interface() = default;
|
||||||
|
|
||||||
|
/// Measures content
|
||||||
|
/**
|
||||||
|
* @param graph The graphics for the operation.
|
||||||
|
* @param limit_pixels The number of pixels of the limited edge. If this parameter is zero, it is ignored.
|
||||||
|
* @param limit_width True if limits the width, false if limits the height.
|
||||||
|
* @return the size of content.
|
||||||
|
*/
|
||||||
|
virtual 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
|
||||||
|
/**
|
||||||
|
* @return the width and height of extension to the widget size.
|
||||||
|
*/
|
||||||
|
virtual size extension() const = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -16,6 +16,7 @@
|
|||||||
#include "effects.hpp"
|
#include "effects.hpp"
|
||||||
#include "detail/general_events.hpp"
|
#include "detail/general_events.hpp"
|
||||||
#include "detail/color_schemes.hpp"
|
#include "detail/color_schemes.hpp"
|
||||||
|
#include "detail/widget_content_measurer_interface.hpp"
|
||||||
#include <nana/paint/image.hpp>
|
#include <nana/paint/image.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -73,6 +74,9 @@ namespace API
|
|||||||
void set_scheme(window, widget_geometrics*);
|
void set_scheme(window, widget_geometrics*);
|
||||||
widget_geometrics* get_scheme(window);
|
widget_geometrics* get_scheme(window);
|
||||||
|
|
||||||
|
/// Sets a content measurer
|
||||||
|
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) throw();
|
||||||
void window_caption(window, ::nana::detail::native_string_type);
|
void window_caption(window, ::nana::detail::native_string_type);
|
||||||
@ -399,6 +403,17 @@ namespace API
|
|||||||
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
|
||||||
|
/**
|
||||||
|
* @param wd A handle to a window that returns its content extent size.
|
||||||
|
* @param limited_px Specifies the max pixels of width or height. If this parameter is zero, this parameter will be ignored.
|
||||||
|
* @param limit_width Indicates whether the it limits the width or height. If this parameter is *true*, the width is limited.
|
||||||
|
* If the parameter is *false*, the height is limited. This parameter is ignored if limited_px = 0.
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width);
|
||||||
}//end namespace API
|
}//end namespace API
|
||||||
|
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
@ -25,6 +25,7 @@ namespace nana{
|
|||||||
/// Draw the button
|
/// Draw the button
|
||||||
class trigger: public drawer_trigger
|
class trigger: public drawer_trigger
|
||||||
{
|
{
|
||||||
|
class measurer;
|
||||||
public:
|
public:
|
||||||
trigger();
|
trigger();
|
||||||
~trigger();
|
~trigger();
|
||||||
@ -58,6 +59,8 @@ namespace nana{
|
|||||||
|
|
||||||
element::cite_bground cite_{"button"};
|
element::cite_bground cite_{"button"};
|
||||||
|
|
||||||
|
std::unique_ptr<measurer> measurer_;
|
||||||
|
|
||||||
struct attr_tag
|
struct attr_tag
|
||||||
{
|
{
|
||||||
element_state e_state;
|
element_state e_state;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Combox Implementation
|
* A Combox Implementation
|
||||||
* 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-2017 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
|
||||||
@ -68,7 +68,7 @@ namespace nana
|
|||||||
void key_press(graph_reference, const arg_keyboard&) override;
|
void key_press(graph_reference, const arg_keyboard&) override;
|
||||||
void key_char(graph_reference, const arg_keyboard&) override;
|
void key_char(graph_reference, const arg_keyboard&) override;
|
||||||
private:
|
private:
|
||||||
drawer_impl * drawer_;
|
drawer_impl * const drawer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class item_proxy
|
class item_proxy
|
||||||
|
@ -31,11 +31,11 @@ namespace nana
|
|||||||
class trigger: public drawer_trigger
|
class trigger: public drawer_trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct impl_t;
|
struct implement;
|
||||||
|
|
||||||
trigger();
|
trigger();
|
||||||
~trigger();
|
~trigger();
|
||||||
impl_t * impl() const;
|
implement * impl() const;
|
||||||
private:
|
private:
|
||||||
void attached(widget_reference, graph_reference) override;
|
void attached(widget_reference, graph_reference) override;
|
||||||
void refresh(graph_reference) override;
|
void refresh(graph_reference) override;
|
||||||
@ -43,7 +43,7 @@ namespace nana
|
|||||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||||
void click(graph_reference, const arg_click&) override;
|
void click(graph_reference, const arg_click&) override;
|
||||||
private:
|
private:
|
||||||
impl_t * impl_;
|
implement * impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//end namespace label
|
}//end namespace label
|
||||||
|
@ -647,7 +647,7 @@ namespace nana
|
|||||||
/// usefull for both absolute and display (sorted) positions
|
/// usefull for both absolute and display (sorted) positions
|
||||||
struct index_pair
|
struct index_pair
|
||||||
{
|
{
|
||||||
constexpr static size_type npos = ::nana::npos;
|
constexpr static const size_type npos = ::nana::npos;
|
||||||
|
|
||||||
size_type cat; //The pos of category
|
size_type cat; //The pos of category
|
||||||
size_type item; //the pos of item in a category.
|
size_type item; //the pos of item in a category.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Picture Implementation
|
* A Picture Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 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
|
||||||
|
364
include/nana/optional.hpp
Normal file
364
include/nana/optional.hpp
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
/**
|
||||||
|
* Optional
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* 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/optional.hpp
|
||||||
|
*
|
||||||
|
* @brief An implementation of experimental library optional of C++ standard(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED
|
||||||
|
#define NANA_STD_OPTIONAL_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <nana/c++defines.hpp>
|
||||||
|
namespace nana
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
class storage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
storage() = default;
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
storage(U&& value)
|
||||||
|
: initialized_{ true }
|
||||||
|
{
|
||||||
|
::new (data_) value_type(std::forward<U>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
storage(const U& value)
|
||||||
|
: initialized_{ true }
|
||||||
|
{
|
||||||
|
::new (data_) value_type(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
storage(const storage& other)
|
||||||
|
: initialized_{ other.initialized_ }
|
||||||
|
{
|
||||||
|
if (other.initialized_)
|
||||||
|
::new (data_) value_type(*other.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
storage(storage&& other)
|
||||||
|
: initialized_{ other.initialized_ }
|
||||||
|
{
|
||||||
|
if (other.initialized_)
|
||||||
|
::new (data_) value_type(std::move(*other.ptr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
storage(const storage<U>& other)
|
||||||
|
: initialized_{ other.initialized_ }
|
||||||
|
{
|
||||||
|
if (other.initialized_)
|
||||||
|
::new (data_) value_type(*other.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
~storage()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initialized() const noexcept
|
||||||
|
{
|
||||||
|
return initialized_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_initialized()
|
||||||
|
{
|
||||||
|
initialized_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
if (initialized_)
|
||||||
|
{
|
||||||
|
ptr()->~T();
|
||||||
|
initialized_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
void assign(U&& value)
|
||||||
|
{
|
||||||
|
if (initialized_)
|
||||||
|
*ptr() = std::forward<U>(value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::new (data) value_type(std::forward<U>(value));
|
||||||
|
initialized_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign(const storage& other)
|
||||||
|
{
|
||||||
|
if (!other.initialized_)
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialized_)
|
||||||
|
*ptr = *other.ptr();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::new (data) value_type(*other.ptr());
|
||||||
|
initialized_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign(storage&& other)
|
||||||
|
{
|
||||||
|
if (!other.initialized_)
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialized_)
|
||||||
|
*ptr() = std::move(*other.ptr());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::new (data) value_type(std::move(*other.ptr()));
|
||||||
|
initialized_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* ptr() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const T*>(data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
T* ptr()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(data_);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool initialized_{ false };
|
||||||
|
char data_[sizeof(value_type)];
|
||||||
|
};
|
||||||
|
}//end namespace detail
|
||||||
|
|
||||||
|
class bad_optional_access
|
||||||
|
: public std::logic_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bad_optional_access()
|
||||||
|
: std::logic_error("Attempted to access the value of an uninitialized optional object.")
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class optional
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
constexpr optional() = default;
|
||||||
|
constexpr optional(std::nullptr_t) {}
|
||||||
|
|
||||||
|
optional(const optional& other)
|
||||||
|
: storage_(other.storage_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional(optional&& other)
|
||||||
|
: storage_(std::move(other.storage_))
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr optional(const value_type& value)
|
||||||
|
: storage_(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr optional(value_type&& value)
|
||||||
|
: storage_(std::move(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional& operator=(std::nullptr_t)
|
||||||
|
{
|
||||||
|
storage_.destroy();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional& operator=(const optional& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
storage_.assign(other.storage_);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional& operator=(optional&& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
storage_.assign(std::move(other.storage_))
|
||||||
|
}
|
||||||
|
return *this;l
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
optional& operator=(U&& value)
|
||||||
|
{
|
||||||
|
storage_.assign(std::forward<U>(value));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Value access
|
||||||
|
//constexpr
|
||||||
|
value_type* operator->()
|
||||||
|
{
|
||||||
|
return storage_.ptr();
|
||||||
|
}
|
||||||
|
constexpr const value_type* operator->() const
|
||||||
|
{
|
||||||
|
return storage_.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
//constexpr
|
||||||
|
value_type& operator*()
|
||||||
|
{
|
||||||
|
return *storage_.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const value_type& operator*() const
|
||||||
|
{
|
||||||
|
return *storage_.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//constexpr
|
||||||
|
value_type&& operator*() &&
|
||||||
|
{
|
||||||
|
return std::move(*storage_.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
//constexpr
|
||||||
|
const value_type&& operator*() const &&
|
||||||
|
{
|
||||||
|
return std::move(*storage_.ptr());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Condition
|
||||||
|
constexpr explicit operator bool() const
|
||||||
|
{
|
||||||
|
return storage_.initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool has_value() const
|
||||||
|
{
|
||||||
|
return storage_.initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
//constexpr
|
||||||
|
value_type& value()
|
||||||
|
{
|
||||||
|
if (!storage_.initialized())
|
||||||
|
throw bad_optional_access{};
|
||||||
|
|
||||||
|
return *storage_.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const value_type& value() const
|
||||||
|
{
|
||||||
|
if (!storage_.initialized())
|
||||||
|
throw bad_optional_access{};
|
||||||
|
|
||||||
|
return *storage_.ptr();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
//constexpr
|
||||||
|
value_type&& value()
|
||||||
|
{
|
||||||
|
if (!storage_.initialized())
|
||||||
|
throw bad_optional_access{};
|
||||||
|
|
||||||
|
return std::move(*storage_.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const value_type&& value() const
|
||||||
|
{
|
||||||
|
if (!storage_.initialized())
|
||||||
|
throw bad_optional_access{};
|
||||||
|
|
||||||
|
return std::move(*storage_.ptr());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
constexpr T value_or(U&& default_value) const
|
||||||
|
{
|
||||||
|
return (has_value() ? **this : static_cast<T>(std::forward<U>(default_value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
//constexpr
|
||||||
|
T value_or(U&& default_value)
|
||||||
|
{
|
||||||
|
return (has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(default_value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Modifiers
|
||||||
|
void swap(optional& other)
|
||||||
|
{
|
||||||
|
if (has_value() && other.has_value())
|
||||||
|
{
|
||||||
|
std::swap(**this, *other);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (has_value())
|
||||||
|
{
|
||||||
|
other.emplace(std::move(***this));
|
||||||
|
storage_.destroy();
|
||||||
|
}
|
||||||
|
else if (other.has_value())
|
||||||
|
{
|
||||||
|
this->emplace(std::move(*other));
|
||||||
|
other.storage_.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
storage_.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void emplace(Args&&... args)
|
||||||
|
{
|
||||||
|
storage_.destroy();
|
||||||
|
::new (storage_.ptr()) T(std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
storage_.set_initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U, typename... Args>
|
||||||
|
void emplace(std::initializer_list<U> il, Args&& ... args)
|
||||||
|
{
|
||||||
|
storage_.destroy();
|
||||||
|
::new (storage_.ptr()) T(il, std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
storage_.set_initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
detail::storage<T> storage_;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -84,7 +84,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
std::unique_ptr<Interface> create() override
|
std::unique_ptr<Interface> create() override
|
||||||
{
|
{
|
||||||
constexpr auto Size = std::tuple_size<decltype(args_)>::value;
|
constexpr auto const Size = std::tuple_size<decltype(args_)>::value;
|
||||||
return std::unique_ptr<Interface>{ _m_new(make_pack<Size>{}) };
|
return std::unique_ptr<Interface>{ _m_new(make_pack<Size>{}) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
155
include/nana/stdc++.hpp
Normal file
155
include/nana/stdc++.hpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/**
|
||||||
|
* Standard Library for C++11/14/17
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* 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/stdc++.hpp
|
||||||
|
*
|
||||||
|
* @brief Implement the lack support of standard library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "c++defines.hpp"
|
||||||
|
|
||||||
|
//Implement workarounds for GCC/MinGW which version is below 4.8.2
|
||||||
|
#if defined(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED)
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
//Workaround for no implemenation of std::stoi in MinGW.
|
||||||
|
int stoi(const std::string&, std::size_t * pos = nullptr, int base = 10);
|
||||||
|
int stoi(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stof in MinGW.
|
||||||
|
float stof(const std::string&, std::size_t * pos = nullptr);
|
||||||
|
float stof(const std::wstring&, std::size_t* pos = nullptr);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stod in MinGW.
|
||||||
|
double stod(const std::string&, std::size_t * pos = nullptr);
|
||||||
|
double stod(const std::wstring&, std::size_t* pos = nullptr);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stold in MinGW.
|
||||||
|
long double stold(const std::string&, std::size_t * pos = nullptr);
|
||||||
|
long double stold(const std::wstring&, std::size_t* pos = nullptr);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stol in MinGW.
|
||||||
|
long stol(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
long stol(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stoll in MinGW.
|
||||||
|
long long stoll(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
long long stoll(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stoul in MinGW.
|
||||||
|
unsigned long stoul(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
unsigned long stoul(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stoull in MinGW.
|
||||||
|
unsigned long long stoull(const std::string&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
unsigned long long stoull(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
|
||||||
|
}
|
||||||
|
#endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
|
||||||
|
|
||||||
|
#ifdef STD_TO_STRING_NOT_SUPPORTED
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
//Workaround for no implemenation of std::to_string/std::to_wstring in MinGW.
|
||||||
|
std::string to_string(long double);
|
||||||
|
std::string to_string(double);
|
||||||
|
std::string to_string(unsigned);
|
||||||
|
std::string to_string(int);
|
||||||
|
std::string to_string(long);
|
||||||
|
std::string to_string(unsigned long);
|
||||||
|
std::string to_string(long long);
|
||||||
|
std::string to_string(unsigned long long);
|
||||||
|
std::string to_string(float);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
std::wstring to_wstring(long double);
|
||||||
|
std::wstring to_wstring(double);
|
||||||
|
std::wstring to_wstring(unsigned);
|
||||||
|
std::wstring to_wstring(int);
|
||||||
|
std::wstring to_wstring(long);
|
||||||
|
std::wstring to_wstring(unsigned long);
|
||||||
|
std::wstring to_wstring(long long);
|
||||||
|
std::wstring to_wstring(unsigned long long);
|
||||||
|
std::wstring to_wstring(float);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _enable_std_make_unique
|
||||||
|
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<class T> struct _Unique_if {
|
||||||
|
typedef unique_ptr<T> _Single_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct _Unique_if<T[]> {
|
||||||
|
typedef unique_ptr<T[]> _Unknown_bound;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, size_t N> struct _Unique_if<T[N]> {
|
||||||
|
typedef void _Known_bound;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class... Args>
|
||||||
|
typename _Unique_if<T>::_Single_object
|
||||||
|
make_unique(Args&&... args) {
|
||||||
|
return unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
typename _Unique_if<T>::_Unknown_bound
|
||||||
|
make_unique(size_t n) {
|
||||||
|
typedef typename remove_extent<T>::type U;
|
||||||
|
return unique_ptr<T>(new U[n]());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class... Args>
|
||||||
|
typename _Unique_if<T>::_Known_bound
|
||||||
|
make_unique(Args&&...) = delete;
|
||||||
|
}
|
||||||
|
#endif //_enable_std_make_unique
|
||||||
|
|
||||||
|
#ifdef _enable_std_put_time
|
||||||
|
#include <ctime>
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
//Workaround for no implemenation of std::put_time in gcc < 5.
|
||||||
|
/* std unspecified return type */
|
||||||
|
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
|
||||||
|
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
|
||||||
|
|
||||||
|
//template< >
|
||||||
|
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt);
|
||||||
|
|
||||||
|
//Defined in header <ctime>
|
||||||
|
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
|
||||||
|
//template<>
|
||||||
|
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
|
||||||
|
}
|
||||||
|
#endif // _enable_std_put_time
|
||||||
|
|
||||||
|
#if defined(_enable_std_clamp)
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
//<algorithm> since C++17
|
||||||
|
template<typename T>
|
||||||
|
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
|
||||||
|
{
|
||||||
|
return (v < lo ? lo : (hi < v ? hi : v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -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(STD_put_time_NOT_SUPPORTED) )
|
#pragma message ( SHOW_VALUE(_enable_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) )
|
||||||
|
@ -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-2015 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 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
|
||||||
@ -24,460 +24,6 @@
|
|||||||
#include <nana/detail/platform_spec_selector.hpp>
|
#include <nana/detail/platform_spec_selector.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Implement workarounds for GCC/MinGW which version is below 4.8.2
|
|
||||||
#if defined(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED)
|
|
||||||
#include <sstream>
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
int stoi(const std::string& str, std::size_t * pos, int base)
|
|
||||||
{
|
|
||||||
auto sptr = str.c_str();
|
|
||||||
char *end;
|
|
||||||
errno = 0;
|
|
||||||
auto result = std::strtol(sptr, &end, base);
|
|
||||||
|
|
||||||
if (sptr == end)
|
|
||||||
throw std::invalid_argument("invalid stoi argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoi argument out of range");
|
|
||||||
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - sptr);
|
|
||||||
return ((int)result);
|
|
||||||
}
|
|
||||||
|
|
||||||
int stoi(const std::wstring& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto sptr = str.data();
|
|
||||||
wchar_t *end;
|
|
||||||
errno = 0;
|
|
||||||
auto result = std::wcstol(sptr, &end, base);
|
|
||||||
|
|
||||||
if (sptr == end)
|
|
||||||
throw std::invalid_argument("invalid stoi argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoi argument out of range");
|
|
||||||
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - sptr);
|
|
||||||
return ((int)result);
|
|
||||||
}
|
|
||||||
using ::strtof;
|
|
||||||
using ::strtold;
|
|
||||||
using ::wcstold;
|
|
||||||
using ::strtoll;
|
|
||||||
using ::wcstoll;
|
|
||||||
using ::strtoull;
|
|
||||||
using ::wcstoull;
|
|
||||||
|
|
||||||
float stof(const std::string& str, std::size_t * pos)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char *end;
|
|
||||||
auto result = std::strtof(ptr, &end);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stof argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float stof(const std::wstring& str, std::size_t* pos)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t *end;
|
|
||||||
auto result = std::wcstof(ptr, &end);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stof argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
double stod(const std::string& str, std::size_t * pos)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char *end;
|
|
||||||
auto result = std::strtod(ptr, &end);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stod argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
double stod(const std::wstring& str, std::size_t* pos)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t *end;
|
|
||||||
auto result = std::wcstod(ptr, &end);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stod argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
long double stold(const std::string& str, std::size_t * pos)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char *end;
|
|
||||||
auto result = std::strtold(ptr, &end);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stold argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
long double stold(const std::wstring& str, std::size_t* pos)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t *end;
|
|
||||||
auto result = std::wcstold(ptr, &end);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stold argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
long stol(const std::string& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char *end;
|
|
||||||
auto result = std::strtol(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stol argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
long stol(const std::wstring& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t *end;
|
|
||||||
auto result = std::wcstol(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stol argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stoll in MinGW.
|
|
||||||
long long stoll(const std::string& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char* end;
|
|
||||||
auto result = std::strtoll(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoll argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long stoll(const std::wstring& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t* end;
|
|
||||||
auto result = std::wcstoll(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoll argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long stoull(const std::string& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char* end;
|
|
||||||
auto result = std::strtoull(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoull argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long stoull(const std::wstring& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t* end;
|
|
||||||
auto result = std::wcstoull(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoull argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Workaround for no implemenation of std::stoul in MinGW.
|
|
||||||
unsigned long stoul(const std::string& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
char* end;
|
|
||||||
auto result = std::strtoul(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoul argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long stoul(const std::wstring& str, std::size_t* pos, int base)
|
|
||||||
{
|
|
||||||
auto *ptr = str.data();
|
|
||||||
errno = 0;
|
|
||||||
wchar_t* end;
|
|
||||||
auto result = std::wcstoul(ptr, &end, base);
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
throw std::invalid_argument("invalid stod argument");
|
|
||||||
if (errno == ERANGE)
|
|
||||||
throw std::out_of_range("stoul argument out of range");
|
|
||||||
if (pos)
|
|
||||||
*pos = (std::size_t)(end - ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}//end namespace std
|
|
||||||
#endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
|
|
||||||
|
|
||||||
#ifdef STD_TO_STRING_NOT_SUPPORTED
|
|
||||||
#include <sstream>
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
std::string to_string(double v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(long double v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(unsigned v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(int v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(long v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(unsigned long v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(long long v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(unsigned long long v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(float v)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // STD_TO_STRING_NOT_SUPPORTED
|
|
||||||
|
|
||||||
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
|
|
||||||
#include <sstream>
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
std::wstring to_wstring(double v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(long double v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(unsigned v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(int v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(long v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(unsigned long v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(long long v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(unsigned long long v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring to_wstring(float v)
|
|
||||||
{
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << v;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#ifdef STD_put_time_NOT_SUPPORTED
|
|
||||||
#include <ctime>
|
|
||||||
#include <cwchar>
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
//Workaround for no implemenation of std::put_time in gcc < 5.
|
|
||||||
/* std unspecified return type */
|
|
||||||
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
|
|
||||||
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
|
|
||||||
|
|
||||||
//template< >
|
|
||||||
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt)
|
|
||||||
{
|
|
||||||
std::size_t sz = 200;
|
|
||||||
std::string str(sz, '\0');
|
|
||||||
sz = std::strftime(&str[0], str.size() - 1, fmt, tmb);
|
|
||||||
str.resize(sz);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
//Defined in header <ctime>
|
|
||||||
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
|
|
||||||
//template<>
|
|
||||||
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt)
|
|
||||||
//{
|
|
||||||
// unsigned sz = 200;
|
|
||||||
// std::wstring str(sz, L'\0');
|
|
||||||
// sz = std::wcsftime(&str[0], str.size() - 1, fmt, tmb);
|
|
||||||
// str.resize(sz);
|
|
||||||
// return str;
|
|
||||||
//}
|
|
||||||
// http://en.cppreference.com/w/cpp/chrono/c/wcsftime
|
|
||||||
// Defined in header <cwchar>
|
|
||||||
// std::size_t wcsftime(wchar_t* str, std::size_t count, const wchar_t* format, const std::tm* time);
|
|
||||||
// Converts the date and time information from a given calendar time time to a null - terminated
|
|
||||||
// wide character string str according to format string format.Up to count bytes are written.
|
|
||||||
// Parameters
|
|
||||||
// str - pointer to the first element of the wchar_t array for output
|
|
||||||
// count - maximum number of wide characters to write
|
|
||||||
// format - pointer to a null - terminated wide character string specifying the format of conversion.
|
|
||||||
|
|
||||||
}
|
|
||||||
//#endif // STD_put_time_NOT_SUPPORTED
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -523,12 +69,12 @@ namespace nana
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void utf8_Error::emit()
|
void utf8_Error::emit()
|
||||||
{
|
{
|
||||||
if (use_throw)
|
if (use_throw)
|
||||||
throw utf8_Error(*this);
|
throw utf8_Error(*this);
|
||||||
std::cerr << what();
|
std::cerr << what();
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool utf8_Error::use_throw{true};
|
//bool utf8_Error::use_throw{true};
|
||||||
bool utf8_Error::use_throw{ false };
|
bool utf8_Error::use_throw{ false };
|
||||||
@ -536,25 +82,18 @@ namespace nana
|
|||||||
|
|
||||||
void throw_not_utf8(const std::string& text)
|
void throw_not_utf8(const std::string& text)
|
||||||
{
|
{
|
||||||
if (!is_utf8(text.c_str(), text.length()))
|
throw_not_utf8(text.c_str(), text.size());
|
||||||
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
|
}
|
||||||
|
|
||||||
|
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)
|
void throw_not_utf8(const char* text, std::size_t len)
|
||||||
{
|
{
|
||||||
if (!is_utf8(text, len))
|
if (!is_utf8(text, len))
|
||||||
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit();
|
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit();
|
||||||
|
|
||||||
//throw std::invalid_argument("The text is not encoded in UTF8");
|
|
||||||
}
|
|
||||||
|
|
||||||
void throw_not_utf8(const char* text)
|
|
||||||
{
|
|
||||||
if (!is_utf8(text, std::strlen(text)))
|
|
||||||
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
|
|
||||||
|
|
||||||
//throw std::invalid_argument("The text is not encoded in UTF8");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string recode_to_utf8(std::string no_utf8)
|
std::string recode_to_utf8(std::string no_utf8)
|
||||||
@ -587,8 +126,6 @@ namespace nana
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const std::string& to_utf8(const std::string& str)
|
const std::string& to_utf8(const std::string& str)
|
||||||
{
|
{
|
||||||
return str;
|
return str;
|
||||||
|
1240
source/gui/place.cpp
1240
source/gui/place.cpp
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Parts of Class Place
|
* Parts of Class Place
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 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
|
||||||
@ -29,21 +29,16 @@ namespace nana
|
|||||||
virtual ~splitter_interface(){}
|
virtual ~splitter_interface(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
class splitter_dtrigger
|
|
||||||
: public drawer_trigger
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool IsLite>
|
template<bool IsLite>
|
||||||
class splitter
|
class splitter
|
||||||
: public widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, splitter_dtrigger>,
|
: public widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, drawer_trigger>,
|
||||||
public splitter_interface
|
public splitter_interface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
void _m_complete_creation() override
|
void _m_complete_creation() override
|
||||||
{
|
{
|
||||||
this->caption("place-splitter");
|
this->caption("place-splitter");
|
||||||
widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, splitter_dtrigger>::_m_complete_creation();
|
widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, drawer_trigger>::_m_complete_creation();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,7 +87,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
color xclr = colors::red;
|
color xclr = colors::red;
|
||||||
|
|
||||||
if(x_state_ == ::nana::mouse_action::pressed)
|
if(x_state_ == ::nana::mouse_action::pressed)
|
||||||
xclr = xclr.blend(colors::white, 0.8);
|
xclr = xclr.blend(colors::white, 0.8);
|
||||||
|
|
||||||
graph.rectangle(r, true, xclr);
|
graph.rectangle(r, true, xclr);
|
||||||
@ -144,11 +139,8 @@ namespace nana
|
|||||||
private:
|
private:
|
||||||
::nana::rectangle _m_button_area() const
|
::nana::rectangle _m_button_area() const
|
||||||
{
|
{
|
||||||
::nana::rectangle r{API::window_size(window_handle_)};
|
auto sz = API::window_size(window_handle_);
|
||||||
|
return{static_cast<int>(sz.width) - 20, 0, 20, sz.height};
|
||||||
r.x = r.right() - 20;
|
|
||||||
r.width = 20;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
window window_handle_;
|
window window_handle_;
|
||||||
@ -161,12 +153,17 @@ namespace nana
|
|||||||
};
|
};
|
||||||
|
|
||||||
class dockarea_caption
|
class dockarea_caption
|
||||||
: public widget_object < category::widget_tag, dockcaption_dtrigger >
|
: public widget_object<category::widget_tag, dockcaption_dtrigger>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using widget_object<category::widget_tag, dockcaption_dtrigger>::get_drawer_trigger;
|
using widget_object<category::widget_tag, dockcaption_dtrigger>::get_drawer_trigger;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned differ(unsigned x, unsigned y) noexcept
|
||||||
|
{
|
||||||
|
return (x > y ? x - y : 0);
|
||||||
|
}
|
||||||
|
|
||||||
class dockarea
|
class dockarea
|
||||||
: public widget_object <category::lite_widget_tag, drawer_trigger>
|
: public widget_object <category::lite_widget_tag, drawer_trigger>
|
||||||
{
|
{
|
||||||
@ -183,6 +180,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
notifier_ = notifier;
|
notifier_ = notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create(window parent)
|
void create(window parent)
|
||||||
{
|
{
|
||||||
host_window_ = parent;
|
host_window_ = parent;
|
||||||
@ -191,17 +189,14 @@ namespace nana
|
|||||||
caption_.create(*this, true);
|
caption_.create(*this, true);
|
||||||
caption_.get_drawer_trigger().on_close([this]
|
caption_.get_drawer_trigger().on_close([this]
|
||||||
{
|
{
|
||||||
bool destroy_dockarea = true;
|
|
||||||
|
|
||||||
if (tabbar_)
|
if (tabbar_)
|
||||||
{
|
{
|
||||||
tabbar_->erase(tabbar_->selected());
|
tabbar_->erase(tabbar_->selected());
|
||||||
|
if (tabbar_->length())
|
||||||
destroy_dockarea = (0 == tabbar_->length());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destroy_dockarea)
|
notifier_->request_close();
|
||||||
notifier_->request_close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this->events().resized.connect([this](const arg_resized& arg)
|
this->events().resized.connect([this](const arg_resized& arg)
|
||||||
@ -331,14 +326,11 @@ namespace nana
|
|||||||
private:
|
private:
|
||||||
widget* _m_add_pane(factory & fn)
|
widget* _m_add_pane(factory & fn)
|
||||||
{
|
{
|
||||||
rectangle r{ point(), this->size() };
|
rectangle r{ this->size() };
|
||||||
|
|
||||||
//get a rectangle excluding caption
|
//get a rectangle excluding caption
|
||||||
r.y = 20;
|
r.y = 20;
|
||||||
if (r.height > 20)
|
r.height = differ(r.height, 20);
|
||||||
r.height -= 20;
|
|
||||||
else
|
|
||||||
r.height = 0;
|
|
||||||
|
|
||||||
if (!tabbar_)
|
if (!tabbar_)
|
||||||
{
|
{
|
||||||
@ -426,7 +418,7 @@ namespace nana
|
|||||||
value_.integer = 0;
|
value_.integer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset() noexcept
|
||||||
{
|
{
|
||||||
kind_ = kind::none;
|
kind_ = kind::none;
|
||||||
value_.integer = 0;
|
value_.integer = 0;
|
||||||
@ -434,30 +426,21 @@ namespace nana
|
|||||||
|
|
||||||
bool is_negative() const
|
bool is_negative() const
|
||||||
{
|
{
|
||||||
switch (kind_)
|
return (((kind::integer == kind_) && (value_.integer < 0)) ||
|
||||||
{
|
((kind::real == kind_ || kind::percent == kind_) && (value_.real < 0)));
|
||||||
case kind::integer:
|
|
||||||
return (value_.integer < 0);
|
|
||||||
case kind::real:
|
|
||||||
case kind::percent:
|
|
||||||
return (value_.real < 0);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const throw()
|
bool empty() const noexcept
|
||||||
{
|
{
|
||||||
return (kind::none == kind_);
|
return (kind::none == kind_);
|
||||||
}
|
}
|
||||||
|
|
||||||
kind kind_of() const
|
kind kind_of() const noexcept
|
||||||
{
|
{
|
||||||
return kind_;
|
return kind_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_value(int ref_percent) const
|
double get_value(int ref_percent) const noexcept
|
||||||
{
|
{
|
||||||
switch (kind_)
|
switch (kind_)
|
||||||
{
|
{
|
||||||
@ -473,33 +456,33 @@ namespace nana
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int integer() const
|
int integer() const noexcept
|
||||||
{
|
{
|
||||||
if (kind::integer == kind_)
|
if (kind::integer == kind_)
|
||||||
return value_.integer;
|
return value_.integer;
|
||||||
return static_cast<int>(value_.real);
|
return static_cast<int>(value_.real);
|
||||||
}
|
}
|
||||||
|
|
||||||
double real() const
|
double real() const noexcept
|
||||||
{
|
{
|
||||||
if (kind::integer == kind_)
|
if (kind::integer == kind_)
|
||||||
return value_.integer;
|
return value_.integer;
|
||||||
return value_.real;
|
return value_.real;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign(int i)
|
void assign(int i) noexcept
|
||||||
{
|
{
|
||||||
kind_ = kind::integer;
|
kind_ = kind::integer;
|
||||||
value_.integer = i;
|
value_.integer = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign(double d)
|
void assign(double d) noexcept
|
||||||
{
|
{
|
||||||
kind_ = kind::real;
|
kind_ = kind::real;
|
||||||
value_.real = d;
|
value_.real = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign_percent(double d)
|
void assign_percent(double d) noexcept
|
||||||
{
|
{
|
||||||
kind_ = kind::percent;
|
kind_ = kind::percent;
|
||||||
value_.real = d / 100;
|
value_.real = d / 100;
|
||||||
@ -532,15 +515,12 @@ namespace nana
|
|||||||
all_edges_ = true;
|
all_edges_ = true;
|
||||||
margins_.clear();
|
margins_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(const number_t& v)
|
void push(const number_t& v, bool reset = false)
|
||||||
{
|
{
|
||||||
margins_.emplace_back(v);
|
if (reset)
|
||||||
}
|
clear();
|
||||||
|
|
||||||
void set_value(const number_t& v)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
margins_.emplace_back(v);
|
margins_.emplace_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,12 +539,11 @@ namespace nana
|
|||||||
if (all_edges_)
|
if (all_edges_)
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_.back().get_value(static_cast<int>(r.width)));
|
auto px = static_cast<int>(margins_.back().get_value(static_cast<int>(r.width)));
|
||||||
const auto dbl_px = static_cast<unsigned>(px << 1);
|
|
||||||
r.x += px;
|
r.x += px;
|
||||||
r.width = (r.width < dbl_px ? 0 : r.width - dbl_px);
|
r.width = differ(r.width, (static_cast<unsigned>(px) << 1));
|
||||||
|
|
||||||
r.y += px;
|
r.y += px;
|
||||||
r.height = (r.height < dbl_px ? 0 : r.height - dbl_px);
|
r.height = differ(r.height, (static_cast<unsigned>(px) << 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -587,49 +566,44 @@ namespace nana
|
|||||||
ib = 2;
|
ib = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef decltype(r.height) px_type;
|
using px_type = decltype(r.height);
|
||||||
auto calc = [](px_type a, px_type b)
|
|
||||||
{
|
|
||||||
return (a > b ? a - b : 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (0 == it) //top
|
if (0 == it) //top
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_[it].get_value(static_cast<int>(field_area.height)));
|
auto px = static_cast<int>(margins_[it].get_value(static_cast<int>(field_area.height)));
|
||||||
r.y += px;
|
r.y += px;
|
||||||
r.height = calc(r.height, static_cast<px_type>(px));
|
r.height = differ(r.height, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != ib) //bottom
|
if (-1 != ib) //bottom
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_[ib].get_value(static_cast<int>(field_area.height)));
|
auto px = static_cast<int>(margins_[ib].get_value(static_cast<int>(field_area.height)));
|
||||||
r.height = calc(r.height, static_cast<px_type>(px));
|
r.height = differ(r.height, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != il) //left
|
if (-1 != il) //left
|
||||||
{
|
{
|
||||||
auto px = static_cast<px_type>(margins_[il].get_value(static_cast<int>(field_area.width)));
|
auto px = static_cast<px_type>(margins_[il].get_value(static_cast<int>(field_area.width)));
|
||||||
r.x += px;
|
r.x += px;
|
||||||
r.width = calc(r.width, static_cast<px_type>(px));
|
r.width = differ(r.width, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != ir) //right
|
if (-1 != ir) //right
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_[ir].get_value(static_cast<int>(field_area.width)));
|
auto px = static_cast<int>(margins_[ir].get_value(static_cast<int>(field_area.width)));
|
||||||
r.width = calc(r.width, static_cast<px_type>(px));
|
r.width = differ(r.width, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool all_edges_ = true;
|
bool all_edges_{ true };
|
||||||
std::vector<number_t> margins_;
|
std::vector<number_t> margins_;
|
||||||
};//end class margin
|
};//end class margin
|
||||||
|
|
||||||
class repeated_array
|
class repeated_array
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//A workaround for VC2013, becuase it does not generated an implicit declared move-constructor as defaulted.
|
//A workaround for VC2013, becuase it does not generated an implicit declared move-constructor as defaulted.
|
||||||
repeated_array() = default;
|
repeated_array() = default;
|
||||||
|
|
||||||
@ -678,15 +652,10 @@ namespace nana
|
|||||||
|
|
||||||
number_t at(std::size_t pos) const
|
number_t at(std::size_t pos) const
|
||||||
{
|
{
|
||||||
if (values_.empty())
|
if (values_.size() && (repeated_ || pos < values_.size()))
|
||||||
return{};
|
return values_[pos % values_.size()];
|
||||||
|
|
||||||
if (repeated_)
|
return{};
|
||||||
pos %= values_.size();
|
|
||||||
else if (pos >= values_.size())
|
|
||||||
return{};
|
|
||||||
|
|
||||||
return values_[pos];
|
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool repeated_ = false;
|
bool repeated_ = false;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Nana GUI Programming Interface Implementation
|
* Nana GUI Programming Interface Implementation
|
||||||
* 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-2017 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
|
||||||
@ -210,6 +210,14 @@ namespace API
|
|||||||
return (restrict::wd_manager().available(iwd) ? iwd->annex.scheme : nullptr);
|
return (restrict::wd_manager().available(iwd) ? iwd->annex.scheme : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_measurer(window wd, ::nana::dev::widget_content_measurer_interface* measurer)
|
||||||
|
{
|
||||||
|
auto iwd = reinterpret_cast<basic_window*>(wd);
|
||||||
|
internal_scope_guard lock;
|
||||||
|
if (restrict::wd_manager().available(iwd))
|
||||||
|
iwd->annex.content_measurer = measurer;
|
||||||
|
}
|
||||||
|
|
||||||
void attach_drawer(widget& wd, drawer_trigger& dr)
|
void attach_drawer(widget& wd, drawer_trigger& dr)
|
||||||
{
|
{
|
||||||
const auto iwd = reinterpret_cast<basic_window*>(wd.handle());
|
const auto iwd = reinterpret_cast<basic_window*>(wd.handle());
|
||||||
@ -1009,6 +1017,8 @@ namespace API
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//modal has to guarantee that does not lock the mutex of window_manager before invokeing the pump_event,
|
||||||
|
//otherwise, the modal will prevent the other thread access the window.
|
||||||
restrict::bedrock.pump_event(wd, true);
|
restrict::bedrock.pump_event(wd, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1429,5 +1439,29 @@ 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)
|
||||||
|
{
|
||||||
|
auto iwd = reinterpret_cast<basic_window*>(wd);
|
||||||
|
internal_scope_guard lock;
|
||||||
|
|
||||||
|
if (restrict::wd_manager().available(iwd) && iwd->annex.content_measurer)
|
||||||
|
{
|
||||||
|
paint::graphics* graph = &iwd->drawer.graphics;
|
||||||
|
paint::graphics temp_graph;
|
||||||
|
if (graph->empty())
|
||||||
|
{
|
||||||
|
temp_graph.make({ 1, 1 });
|
||||||
|
temp_graph.typeface(graph->typeface());
|
||||||
|
graph = &temp_graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto extent = iwd->annex.content_measurer->measure(*graph, limited_px, limit_width);
|
||||||
|
if (extent)
|
||||||
|
return std::make_pair(extent.value(), extent.value() + iwd->annex.content_measurer->extension());
|
||||||
|
}
|
||||||
|
|
||||||
|
return{};
|
||||||
|
}
|
||||||
}//end namespace API
|
}//end namespace API
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
@ -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-2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 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
|
||||||
@ -11,12 +11,44 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nana/gui/widgets/button.hpp>
|
#include <nana/gui/widgets/button.hpp>
|
||||||
|
#include <nana/gui/detail/widget_content_measurer_interface.hpp>
|
||||||
|
|
||||||
#include <nana/paint/text_renderer.hpp>
|
#include <nana/paint/text_renderer.hpp>
|
||||||
|
|
||||||
namespace nana{ namespace drawerbase
|
namespace nana{ namespace drawerbase
|
||||||
{
|
{
|
||||||
namespace button
|
namespace button
|
||||||
{
|
{
|
||||||
|
class trigger::measurer
|
||||||
|
: public dev::widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
measurer(trigger* t)
|
||||||
|
: trigger_{ t }
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
|
{
|
||||||
|
//Button doesn't provide a support of vfit and hfit
|
||||||
|
if (limit_pixels)
|
||||||
|
return{};
|
||||||
|
|
||||||
|
wchar_t shortkey;
|
||||||
|
std::string::size_type shortkey_pos;
|
||||||
|
|
||||||
|
auto str = to_wstring(API::transform_shortkey_text(trigger_->wdg_->caption(), shortkey, &shortkey_pos));
|
||||||
|
auto text_sz = graph.text_extent_size(str);
|
||||||
|
|
||||||
|
return size{ text_sz.width, text_sz.height };
|
||||||
|
}
|
||||||
|
|
||||||
|
size extension() const override
|
||||||
|
{
|
||||||
|
return { 14, 10};
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
trigger * trigger_;
|
||||||
|
};
|
||||||
|
|
||||||
//trigger
|
//trigger
|
||||||
//@brief: draw the button
|
//@brief: draw the button
|
||||||
@ -26,6 +58,8 @@ namespace nana{ namespace drawerbase
|
|||||||
attr_.omitted = attr_.focused = attr_.pushed = attr_.enable_pushed = attr_.keep_pressed = false;
|
attr_.omitted = attr_.focused = attr_.pushed = attr_.enable_pushed = attr_.keep_pressed = false;
|
||||||
attr_.focus_color = true;
|
attr_.focus_color = true;
|
||||||
attr_.icon = nullptr;
|
attr_.icon = nullptr;
|
||||||
|
|
||||||
|
measurer_.reset(new measurer{this});
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger::~trigger()
|
trigger::~trigger()
|
||||||
@ -44,6 +78,7 @@ namespace nana{ namespace drawerbase
|
|||||||
API::tabstop(wd);
|
API::tabstop(wd);
|
||||||
API::effects_edge_nimbus(wd, effects::edge_nimbus::active);
|
API::effects_edge_nimbus(wd, effects::edge_nimbus::active);
|
||||||
API::effects_edge_nimbus(wd, effects::edge_nimbus::over);
|
API::effects_edge_nimbus(wd, effects::edge_nimbus::over);
|
||||||
|
API::dev::set_measurer(widget, measurer_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trigger::enable_pushed(bool eb)
|
bool trigger::enable_pushed(bool eb)
|
||||||
@ -251,17 +286,17 @@ namespace nana{ namespace drawerbase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graph.palette(true, ::nana::color(colors::white));
|
graph.palette(true, color{ colors::white });
|
||||||
if(attr_.omitted)
|
if(attr_.omitted)
|
||||||
{
|
{
|
||||||
tr.render(point{ pos.x + 1, pos.y + 1 }, txtptr, txtlen, omitted_pixels, true);
|
tr.render(point{ pos.x + 1, pos.y + 1 }, txtptr, txtlen, omitted_pixels, true);
|
||||||
graph.palette(true, ::nana::color(colors::gray));
|
graph.palette(true, color{ colors::gray });
|
||||||
tr.render(pos, txtptr, txtlen, omitted_pixels, true);
|
tr.render(pos, txtptr, txtlen, omitted_pixels, true);
|
||||||
}
|
}
|
||||||
else
|
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, ::nana::color(colors::gray));
|
graph.palette(true, color{ colors::gray });
|
||||||
graph.bidi_string(pos, txtptr, txtlen);
|
graph.bidi_string(pos, txtptr, txtlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Combox Implementation
|
* A Combox Implementation
|
||||||
* 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-2017 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
|
||||||
@ -17,8 +17,10 @@
|
|||||||
#include <nana/gui/widgets/float_listbox.hpp>
|
#include <nana/gui/widgets/float_listbox.hpp>
|
||||||
#include <nana/gui/widgets/skeletons/text_editor.hpp>
|
#include <nana/gui/widgets/skeletons/text_editor.hpp>
|
||||||
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
|
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
|
||||||
|
#include <nana/gui/detail/widget_content_measurer_interface.hpp>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -80,6 +82,46 @@ namespace nana
|
|||||||
|
|
||||||
class drawer_impl
|
class drawer_impl
|
||||||
{
|
{
|
||||||
|
class content_measurer
|
||||||
|
: public dev::widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
content_measurer(drawer_impl* drwimpl)
|
||||||
|
: drw_{ drwimpl }
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
|
{
|
||||||
|
//Button doesn't provide a support of vfit and hfit
|
||||||
|
if (limit_pixels)
|
||||||
|
return{};
|
||||||
|
|
||||||
|
size content_size;
|
||||||
|
for (auto i = 0; i < drw_->the_number_of_options(); ++i)
|
||||||
|
{
|
||||||
|
auto & m = drw_->at(i);
|
||||||
|
auto sz = graph.text_extent_size(m.item_text);
|
||||||
|
|
||||||
|
content_size.width = (std::max)(content_size.width, sz.width);
|
||||||
|
content_size.height = (std::max)(content_size.height, sz.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return content_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size extension() const override
|
||||||
|
{
|
||||||
|
auto text_size = drw_->editor()->text_area(false).dimension();
|
||||||
|
auto wdg_size = drw_->widget_ptr()->size();
|
||||||
|
|
||||||
|
return{
|
||||||
|
wdg_size.width > text_size.width ? wdg_size.width - text_size.width : 0,
|
||||||
|
wdg_size.height > text_size.height ? wdg_size.height - text_size.height : 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
drawer_impl* const drw_;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
using graph_reference = paint::graphics&;
|
using graph_reference = paint::graphics&;
|
||||||
using widget_reference = widget&;
|
using widget_reference = widget&;
|
||||||
@ -92,6 +134,8 @@ namespace nana
|
|||||||
state_.button_state = element_state::normal;
|
state_.button_state = element_state::normal;
|
||||||
state_.pointer_where = parts::none;
|
state_.pointer_where = parts::none;
|
||||||
state_.lister = nullptr;
|
state_.lister = nullptr;
|
||||||
|
|
||||||
|
measurer_.reset(new content_measurer{this});
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer(drawerbase::float_listbox::item_renderer* ir)
|
void renderer(drawerbase::float_listbox::item_renderer* ir)
|
||||||
@ -111,6 +155,8 @@ namespace nana
|
|||||||
|
|
||||||
evt_agent_.reset(new event_agent{ static_cast<nana::combox&>(wd) });
|
evt_agent_.reset(new event_agent{ static_cast<nana::combox&>(wd) });
|
||||||
editor_->textbase().set_event_agent(evt_agent_.get());
|
editor_->textbase().set_event_agent(evt_agent_.get());
|
||||||
|
|
||||||
|
API::dev::set_measurer(wd, measurer_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void detached()
|
void detached()
|
||||||
@ -528,6 +574,8 @@ namespace nana
|
|||||||
unsigned image_pixels_{ 16 };
|
unsigned image_pixels_{ 16 };
|
||||||
widgets::skeletons::text_editor * editor_{ nullptr };
|
widgets::skeletons::text_editor * editor_{ nullptr };
|
||||||
std::unique_ptr<event_agent> evt_agent_;
|
std::unique_ptr<event_agent> evt_agent_;
|
||||||
|
|
||||||
|
std::unique_ptr<content_measurer> measurer_;
|
||||||
struct state_type
|
struct state_type
|
||||||
{
|
{
|
||||||
bool focused;
|
bool focused;
|
||||||
@ -537,188 +585,191 @@ namespace nana
|
|||||||
nana::float_listbox * lister;
|
nana::float_listbox * lister;
|
||||||
std::size_t item_index_before_selection;
|
std::size_t item_index_before_selection;
|
||||||
}state_;
|
}state_;
|
||||||
};
|
|
||||||
|
|
||||||
|
}; //end class drawer_impl
|
||||||
|
|
||||||
|
|
||||||
//class trigger
|
//class trigger
|
||||||
trigger::trigger()
|
trigger::trigger() :
|
||||||
: drawer_(new drawer_impl)
|
drawer_(new drawer_impl)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
trigger::~trigger()
|
trigger::~trigger()
|
||||||
{
|
{
|
||||||
delete drawer_;
|
delete drawer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer_impl& trigger::get_drawer_impl()
|
drawer_impl& trigger::get_drawer_impl()
|
||||||
{
|
{
|
||||||
return *drawer_;
|
return *drawer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawer_impl& trigger::get_drawer_impl() const
|
const drawer_impl& trigger::get_drawer_impl() const
|
||||||
{
|
{
|
||||||
return *drawer_;
|
return *drawer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::attached(widget_reference wdg, graph_reference graph)
|
void trigger::attached(widget_reference wdg, graph_reference graph)
|
||||||
{
|
{
|
||||||
wdg.bgcolor(colors::white);
|
wdg.bgcolor(colors::white);
|
||||||
drawer_->attached(wdg, graph);
|
drawer_->attached(wdg, graph);
|
||||||
|
|
||||||
API::effects_edge_nimbus(wdg, effects::edge_nimbus::active);
|
API::effects_edge_nimbus(wdg, effects::edge_nimbus::active);
|
||||||
API::effects_edge_nimbus(wdg, effects::edge_nimbus::over);
|
API::effects_edge_nimbus(wdg, effects::edge_nimbus::over);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::detached()
|
void trigger::detached()
|
||||||
{
|
{
|
||||||
drawer_->detached();
|
drawer_->detached();
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::refresh(graph_reference)
|
void trigger::refresh(graph_reference)
|
||||||
|
{
|
||||||
|
drawer_->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::focus(graph_reference, const arg_focus& arg)
|
||||||
|
{
|
||||||
|
drawer_->set_focused(arg.getting);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
{
|
{
|
||||||
drawer_->draw();
|
drawer_->draw();
|
||||||
|
drawer_->editor()->reset_caret();
|
||||||
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void trigger::focus(graph_reference, const arg_focus& arg)
|
void trigger::mouse_enter(graph_reference, const arg_mouse&)
|
||||||
|
{
|
||||||
|
drawer_->set_button_state(element_state::hovered, true);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
{
|
{
|
||||||
drawer_->set_focused(arg.getting);
|
drawer_->draw();
|
||||||
if(drawer_->widget_ptr()->enabled())
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_leave(graph_reference, const arg_mouse&)
|
||||||
|
{
|
||||||
|
drawer_->set_button_state(element_state::normal, true);
|
||||||
|
drawer_->editor()->mouse_enter(false);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
|
{
|
||||||
|
drawer_->draw();
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
//drawer_->set_mouse_press(true);
|
||||||
|
drawer_->set_button_state(element_state::pressed, false);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
|
{
|
||||||
|
auto * editor = drawer_->editor();
|
||||||
|
editor->mouse_pressed(arg);
|
||||||
|
drawer_->open_lister_if_push_button_positioned();
|
||||||
|
|
||||||
|
drawer_->draw();
|
||||||
|
if(editor->attr().editable)
|
||||||
|
editor->reset_caret();
|
||||||
|
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_up(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
|
||||||
|
{
|
||||||
|
drawer_->editor()->mouse_pressed(arg);
|
||||||
|
drawer_->set_button_state(element_state::hovered, false);
|
||||||
|
drawer_->draw();
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
|
{
|
||||||
|
bool redraw = drawer_->calc_where(graph, arg.pos.x, arg.pos.y);
|
||||||
|
redraw |= drawer_->editor()->mouse_move(arg.left_button, arg.pos);
|
||||||
|
|
||||||
|
if(redraw)
|
||||||
{
|
{
|
||||||
drawer_->draw();
|
drawer_->draw();
|
||||||
drawer_->editor()->reset_caret();
|
drawer_->editor()->reset_caret();
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void trigger::mouse_enter(graph_reference, const arg_mouse&)
|
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
|
||||||
|
{
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
{
|
{
|
||||||
drawer_->set_button_state(element_state::hovered, true);
|
if(drawer_->has_lister())
|
||||||
if(drawer_->widget_ptr()->enabled())
|
drawer_->scroll_items(arg.upwards);
|
||||||
{
|
|
||||||
drawer_->draw();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_leave(graph_reference, const arg_mouse&)
|
|
||||||
{
|
|
||||||
drawer_->set_button_state(element_state::normal, true);
|
|
||||||
drawer_->editor()->mouse_enter(false);
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
drawer_->draw();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
//drawer_->set_mouse_press(true);
|
|
||||||
drawer_->set_button_state(element_state::pressed, false);
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
auto * editor = drawer_->editor();
|
|
||||||
editor->mouse_pressed(arg);
|
|
||||||
drawer_->open_lister_if_push_button_positioned();
|
|
||||||
|
|
||||||
drawer_->draw();
|
|
||||||
if(editor->attr().editable)
|
|
||||||
editor->reset_caret();
|
|
||||||
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_up(graph_reference, const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
|
|
||||||
{
|
|
||||||
drawer_->editor()->mouse_pressed(arg);
|
|
||||||
drawer_->set_button_state(element_state::hovered, false);
|
|
||||||
drawer_->draw();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
bool redraw = drawer_->calc_where(graph, arg.pos.x, arg.pos.y);
|
|
||||||
redraw |= drawer_->editor()->mouse_move(arg.left_button, arg.pos);
|
|
||||||
|
|
||||||
if(redraw)
|
|
||||||
{
|
|
||||||
drawer_->draw();
|
|
||||||
drawer_->editor()->reset_caret();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
|
|
||||||
{
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
if(drawer_->has_lister())
|
|
||||||
drawer_->scroll_items(arg.upwards);
|
|
||||||
else
|
|
||||||
drawer_->move_items(arg.upwards, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::key_press(graph_reference, const arg_keyboard& arg)
|
|
||||||
{
|
|
||||||
if(!drawer_->widget_ptr()->enabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool call_other_keys = false;
|
|
||||||
if(drawer_->editable())
|
|
||||||
{
|
|
||||||
bool is_move_up = false;
|
|
||||||
switch(arg.key)
|
|
||||||
{
|
|
||||||
case keyboard::os_arrow_left:
|
|
||||||
case keyboard::os_arrow_right:
|
|
||||||
drawer_->editor()->respond_key(arg);
|
|
||||||
drawer_->editor()->reset_caret();
|
|
||||||
break;
|
|
||||||
case keyboard::os_arrow_up:
|
|
||||||
is_move_up = true;
|
|
||||||
case keyboard::os_arrow_down:
|
|
||||||
drawer_->move_items(is_move_up, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
call_other_keys = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
drawer_->move_items(arg.upwards, false);
|
||||||
bool is_move_up = false;
|
|
||||||
switch(arg.key)
|
|
||||||
{
|
|
||||||
case keyboard::os_arrow_left:
|
|
||||||
case keyboard::os_arrow_up:
|
|
||||||
is_move_up = true;
|
|
||||||
case keyboard::os_arrow_right:
|
|
||||||
case keyboard::os_arrow_down:
|
|
||||||
drawer_->move_items(is_move_up, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
call_other_keys = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (call_other_keys)
|
|
||||||
drawer_->editor()->respond_key(arg);
|
|
||||||
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void trigger::key_char(graph_reference, const arg_keyboard& arg)
|
void trigger::key_press(graph_reference, const arg_keyboard& arg)
|
||||||
|
{
|
||||||
|
if(!drawer_->widget_ptr()->enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool call_other_keys = false;
|
||||||
|
if(drawer_->editable())
|
||||||
{
|
{
|
||||||
if (drawer_->editor()->respond_char(arg))
|
bool is_move_up = false;
|
||||||
API::dev::lazy_refresh();
|
switch(arg.key)
|
||||||
|
{
|
||||||
|
case keyboard::os_arrow_left:
|
||||||
|
case keyboard::os_arrow_right:
|
||||||
|
drawer_->editor()->respond_key(arg);
|
||||||
|
drawer_->editor()->reset_caret();
|
||||||
|
break;
|
||||||
|
case keyboard::os_arrow_up:
|
||||||
|
is_move_up = true;
|
||||||
|
case keyboard::os_arrow_down:
|
||||||
|
drawer_->move_items(is_move_up, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
call_other_keys = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool is_move_up = false;
|
||||||
|
switch(arg.key)
|
||||||
|
{
|
||||||
|
case keyboard::os_arrow_left:
|
||||||
|
case keyboard::os_arrow_up:
|
||||||
|
is_move_up = true;
|
||||||
|
case keyboard::os_arrow_right:
|
||||||
|
case keyboard::os_arrow_down:
|
||||||
|
drawer_->move_items(is_move_up, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
call_other_keys = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (call_other_keys)
|
||||||
|
drawer_->editor()->respond_key(arg);
|
||||||
|
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::key_char(graph_reference, const arg_keyboard& arg)
|
||||||
|
{
|
||||||
|
if (drawer_->editor()->respond_char(arg))
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
//end class trigger
|
//end class trigger
|
||||||
|
|
||||||
//class item_proxy
|
//class item_proxy
|
||||||
|
@ -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-2013 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -13,8 +13,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nana/gui/widgets/label.hpp>
|
#include <nana/gui/widgets/label.hpp>
|
||||||
#include <nana/unicode_bidi.hpp>
|
|
||||||
#include <nana/gui/widgets/skeletons/text_token_stream.hpp>
|
#include <nana/gui/widgets/skeletons/text_token_stream.hpp>
|
||||||
|
#include <nana/gui/detail/widget_content_measurer_interface.hpp>
|
||||||
|
#include <nana/unicode_bidi.hpp>
|
||||||
#include <nana/system/platform.hpp>
|
#include <nana/system/platform.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -80,14 +81,14 @@ namespace nana
|
|||||||
{
|
{
|
||||||
traceable_.clear();
|
traceable_.clear();
|
||||||
|
|
||||||
nana::paint::font ft = graph.typeface(); //used for restoring the font
|
auto pre_font = graph.typeface(); //used for restoring the font
|
||||||
|
|
||||||
const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height;
|
const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height;
|
||||||
|
|
||||||
font_ = ft;
|
font_ = pre_font;
|
||||||
fblock_ = nullptr;
|
fblock_ = nullptr;
|
||||||
|
|
||||||
_m_set_default(ft, fgcolor);
|
_m_set_default(pre_font, fgcolor);
|
||||||
|
|
||||||
_m_measure(graph);
|
_m_measure(graph);
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ namespace nana
|
|||||||
rs.pos.y += static_cast<int>(rs.pixels.back().pixels);
|
rs.pos.y += static_cast<int>(rs.pixels.back().pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.typeface(ft);
|
graph.typeface(pre_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(int x, int y, std::wstring& target, std::wstring& url) const
|
bool find(int x, int y, std::wstring& target, std::wstring& url) const
|
||||||
@ -183,10 +184,10 @@ namespace nana
|
|||||||
rs.text_align = th;
|
rs.text_align = th;
|
||||||
rs.text_align_v = tv;
|
rs.text_align_v = tv;
|
||||||
|
|
||||||
for(auto i = dstream_.begin(), end = dstream_.end(); i != end; ++i)
|
for(auto & line: dstream_)
|
||||||
{
|
{
|
||||||
rs.pixels.clear();
|
rs.pixels.clear();
|
||||||
unsigned w = _m_line_pixels(*i, def_line_pixels, rs);
|
unsigned w = _m_line_pixels(line, def_line_pixels, rs);
|
||||||
|
|
||||||
if(limited && (w > limited))
|
if(limited && (w > limited))
|
||||||
w = limited;
|
w = limited;
|
||||||
@ -365,7 +366,8 @@ namespace nana
|
|||||||
sz.height = max_ascent + max_descent;
|
sz.height = max_ascent + max_descent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(w + sz.width <= rs.allowed_width)
|
//Check if the content is displayed in a new line.
|
||||||
|
if((0 == rs.allowed_width) || (w + sz.width <= rs.allowed_width))
|
||||||
{
|
{
|
||||||
w += sz.width;
|
w += sz.width;
|
||||||
|
|
||||||
@ -613,10 +615,13 @@ namespace nana
|
|||||||
|
|
||||||
//class trigger
|
//class trigger
|
||||||
//@brief: Draw the label
|
//@brief: Draw the label
|
||||||
struct trigger::impl_t
|
struct trigger::implement
|
||||||
{
|
{
|
||||||
|
class measurer;
|
||||||
|
|
||||||
widget * wd{nullptr};
|
widget * wd{nullptr};
|
||||||
paint::graphics * graph{nullptr};
|
paint::graphics * graph{nullptr};
|
||||||
|
std::unique_ptr<measurer> msr_ptr{ nullptr };
|
||||||
|
|
||||||
align text_align{align::left};
|
align text_align{align::left};
|
||||||
align_v text_align_v;
|
align_v text_align_v;
|
||||||
@ -643,16 +648,44 @@ namespace nana
|
|||||||
std::vector<std::function<void(command, const std::string&)>> listener_;
|
std::vector<std::function<void(command, const std::string&)>> listener_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class trigger::implement::measurer
|
||||||
|
: public dev::widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
measurer(implement* impl)
|
||||||
|
: impl_{ impl }
|
||||||
|
{}
|
||||||
|
|
||||||
|
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.
|
||||||
|
if (graph && ((0 == limit_pixels) || limit_width))
|
||||||
|
{
|
||||||
|
return impl_->renderer.measure(graph, limit_pixels, impl_->text_align, impl_->text_align_v);
|
||||||
|
}
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
|
size extension() const override
|
||||||
|
{
|
||||||
|
return{ 2, 2 };
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
implement * const impl_;
|
||||||
|
};
|
||||||
|
|
||||||
trigger::trigger()
|
trigger::trigger()
|
||||||
:impl_(new impl_t)
|
:impl_(new implement)
|
||||||
{}
|
{
|
||||||
|
impl_->msr_ptr.reset(new trigger::implement::measurer{impl_});
|
||||||
|
}
|
||||||
|
|
||||||
trigger::~trigger()
|
trigger::~trigger()
|
||||||
{
|
{
|
||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger::impl_t * trigger::impl() const
|
trigger::implement * trigger::impl() const
|
||||||
{
|
{
|
||||||
return impl_;
|
return impl_;
|
||||||
}
|
}
|
||||||
@ -661,6 +694,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
impl_->graph = &graph;
|
impl_->graph = &graph;
|
||||||
impl_->wd = &widget;
|
impl_->wd = &widget;
|
||||||
|
API::dev::set_measurer(widget, impl_->msr_ptr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::mouse_move(graph_reference, const arg_mouse& arg)
|
void trigger::mouse_move(graph_reference, const arg_mouse& arg)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Picture Implementation
|
* A Picture Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 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 @@
|
|||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/paint/image.hpp>
|
#include <nana/paint/image.hpp>
|
||||||
#include <nana/gui/element.hpp>
|
#include <nana/gui/element.hpp>
|
||||||
|
#include <nana/gui/detail/widget_content_measurer_interface.hpp>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -23,11 +24,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
namespace picture
|
namespace picture
|
||||||
{
|
{
|
||||||
|
class content_measurer;
|
||||||
|
|
||||||
struct implement
|
struct implement
|
||||||
{
|
{
|
||||||
widget* wdg_ptr{nullptr};
|
widget* wdg_ptr{nullptr};
|
||||||
paint::graphics* graph_ptr{nullptr};
|
paint::graphics* graph_ptr{nullptr};
|
||||||
|
std::unique_ptr<content_measurer> measurer;
|
||||||
|
|
||||||
struct gradual_bground_tag
|
struct gradual_bground_tag
|
||||||
{
|
{
|
||||||
@ -47,9 +50,37 @@ namespace nana
|
|||||||
}backimg;
|
}backimg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class content_measurer
|
||||||
|
: public dev::widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
content_measurer(implement* impl)
|
||||||
|
: impl_{impl}
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
|
{
|
||||||
|
//Button doesn't provide a support of vfit and hfit
|
||||||
|
if (!limit_pixels)
|
||||||
|
{
|
||||||
|
if (impl_->backimg.valid_area.empty())
|
||||||
|
return impl_->backimg.image.size();
|
||||||
|
}
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
|
size extension() const override
|
||||||
|
{
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
implement* const impl_;
|
||||||
|
};
|
||||||
|
|
||||||
//class drawer
|
//class drawer
|
||||||
drawer::drawer() :impl_(new implement)
|
drawer::drawer() :impl_(new implement)
|
||||||
{
|
{
|
||||||
|
impl_->measurer.reset(new content_measurer{impl_});
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer::~drawer()
|
drawer::~drawer()
|
||||||
@ -61,6 +92,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
impl_->wdg_ptr = &wdg;
|
impl_->wdg_ptr = &wdg;
|
||||||
impl_->graph_ptr = &graph;
|
impl_->graph_ptr = &graph;
|
||||||
|
API::dev::set_measurer(wdg, impl_->measurer.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::refresh(graph_reference graph)
|
void drawer::refresh(graph_reference graph)
|
||||||
|
468
source/stdc++.cpp
Normal file
468
source/stdc++.cpp
Normal file
@ -0,0 +1,468 @@
|
|||||||
|
/**
|
||||||
|
* Standard Library for C++11/14/17
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* 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/stdc++.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nana/stdc++.hpp>
|
||||||
|
|
||||||
|
//Implement workarounds for GCC/MinGW which version is below 4.8.2
|
||||||
|
#if defined(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED)
|
||||||
|
#include <sstream>
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
int stoi(const std::string& str, std::size_t * pos, int base)
|
||||||
|
{
|
||||||
|
auto sptr = str.c_str();
|
||||||
|
char *end;
|
||||||
|
errno = 0;
|
||||||
|
auto result = std::strtol(sptr, &end, base);
|
||||||
|
|
||||||
|
if (sptr == end)
|
||||||
|
throw std::invalid_argument("invalid stoi argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoi argument out of range");
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - sptr);
|
||||||
|
return ((int)result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stoi(const std::wstring& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto sptr = str.data();
|
||||||
|
wchar_t *end;
|
||||||
|
errno = 0;
|
||||||
|
auto result = std::wcstol(sptr, &end, base);
|
||||||
|
|
||||||
|
if (sptr == end)
|
||||||
|
throw std::invalid_argument("invalid stoi argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoi argument out of range");
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - sptr);
|
||||||
|
return ((int)result);
|
||||||
|
}
|
||||||
|
using ::strtof;
|
||||||
|
using ::strtold;
|
||||||
|
using ::wcstold;
|
||||||
|
using ::strtoll;
|
||||||
|
using ::wcstoll;
|
||||||
|
using ::strtoull;
|
||||||
|
using ::wcstoull;
|
||||||
|
|
||||||
|
float stof(const std::string& str, std::size_t * pos)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char *end;
|
||||||
|
auto result = std::strtof(ptr, &end);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stof argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float stof(const std::wstring& str, std::size_t* pos)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t *end;
|
||||||
|
auto result = std::wcstof(ptr, &end);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stof argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double stod(const std::string& str, std::size_t * pos)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char *end;
|
||||||
|
auto result = std::strtod(ptr, &end);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stod argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double stod(const std::wstring& str, std::size_t* pos)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t *end;
|
||||||
|
auto result = std::wcstod(ptr, &end);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stod argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double stold(const std::string& str, std::size_t * pos)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char *end;
|
||||||
|
auto result = std::strtold(ptr, &end);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stold argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double stold(const std::wstring& str, std::size_t* pos)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t *end;
|
||||||
|
auto result = std::wcstold(ptr, &end);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stold argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
long stol(const std::string& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char *end;
|
||||||
|
auto result = std::strtol(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stol argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
long stol(const std::wstring& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t *end;
|
||||||
|
auto result = std::wcstol(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stol argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stoll in MinGW.
|
||||||
|
long long stoll(const std::string& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char* end;
|
||||||
|
auto result = std::strtoll(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoll argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long stoll(const std::wstring& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t* end;
|
||||||
|
auto result = std::wcstoll(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoll argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long stoull(const std::string& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char* end;
|
||||||
|
auto result = std::strtoull(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoull argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long stoull(const std::wstring& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t* end;
|
||||||
|
auto result = std::wcstoull(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoull argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Workaround for no implemenation of std::stoul in MinGW.
|
||||||
|
unsigned long stoul(const std::string& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
char* end;
|
||||||
|
auto result = std::strtoul(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoul argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long stoul(const std::wstring& str, std::size_t* pos, int base)
|
||||||
|
{
|
||||||
|
auto *ptr = str.data();
|
||||||
|
errno = 0;
|
||||||
|
wchar_t* end;
|
||||||
|
auto result = std::wcstoul(ptr, &end, base);
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
throw std::invalid_argument("invalid stod argument");
|
||||||
|
if (errno == ERANGE)
|
||||||
|
throw std::out_of_range("stoul argument out of range");
|
||||||
|
if (pos)
|
||||||
|
*pos = (std::size_t)(end - ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}//end namespace std
|
||||||
|
#endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
|
||||||
|
|
||||||
|
#ifdef STD_TO_STRING_NOT_SUPPORTED
|
||||||
|
#include <sstream>
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
std::string to_string(double v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(long double v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(unsigned v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(int v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(long v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(unsigned long v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(long long v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(unsigned long long v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(float v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // STD_TO_STRING_NOT_SUPPORTED
|
||||||
|
|
||||||
|
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
|
||||||
|
#include <sstream>
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
std::wstring to_wstring(double v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(long double v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(unsigned v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(int v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(long v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(unsigned long v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(long long v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(unsigned long long v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_wstring(float v)
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << v;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _enable_std_put_time
|
||||||
|
#include <ctime>
|
||||||
|
#include <cwchar>
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
//Workaround for no implemenation of std::put_time in gcc < 5.
|
||||||
|
/* std unspecified return type */
|
||||||
|
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
|
||||||
|
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
|
||||||
|
|
||||||
|
//template< >
|
||||||
|
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt)
|
||||||
|
{
|
||||||
|
std::size_t sz = 200;
|
||||||
|
std::string str(sz, '\0');
|
||||||
|
sz = std::strftime(&str[0], str.size() - 1, fmt, tmb);
|
||||||
|
str.resize(sz);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
//Defined in header <ctime>
|
||||||
|
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
|
||||||
|
//template<>
|
||||||
|
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt)
|
||||||
|
//{
|
||||||
|
// unsigned sz = 200;
|
||||||
|
// std::wstring str(sz, L'\0');
|
||||||
|
// sz = std::wcsftime(&str[0], str.size() - 1, fmt, tmb);
|
||||||
|
// str.resize(sz);
|
||||||
|
// return str;
|
||||||
|
//}
|
||||||
|
// http://en.cppreference.com/w/cpp/chrono/c/wcsftime
|
||||||
|
// Defined in header <cwchar>
|
||||||
|
// std::size_t wcsftime(wchar_t* str, std::size_t count, const wchar_t* format, const std::tm* time);
|
||||||
|
// Converts the date and time information from a given calendar time time to a null - terminated
|
||||||
|
// wide character string str according to format string format.Up to count bytes are written.
|
||||||
|
// Parameters
|
||||||
|
// str - pointer to the first element of the wchar_t array for output
|
||||||
|
// count - maximum number of wide characters to write
|
||||||
|
// format - pointer to a null - terminated wide character string specifying the format of conversion.
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // _enable_std_put_time
|
Loading…
x
Reference in New Issue
Block a user