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