From a580237e0523edc854f96a4b2eb21942904ef72c Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 16:50:44 +0100 Subject: [PATCH 01/15] to retrieve a modifiable object from a list item --- include/nana/detail/platform_spec_selector.hpp | 8 ++++---- include/nana/gui/detail/general_events.hpp | 2 +- include/nana/gui/widgets/listbox.hpp | 11 +++++++++++ source/detail/platform_spec_windows.cpp | 6 +++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/nana/detail/platform_spec_selector.hpp b/include/nana/detail/platform_spec_selector.hpp index d230088f..fc4504f8 100644 --- a/include/nana/detail/platform_spec_selector.hpp +++ b/include/nana/detail/platform_spec_selector.hpp @@ -1,15 +1,15 @@ -/* +/** * Selector of Platform Specification * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/detail/platform_spec_selector.hpp + * @file nana/detail/platform_spec_selector.hpp * - * Selects the proper platform_spec header file for the current platform + * @brief Selects the proper platform_spec header file for the current platform */ #include diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 454b407f..c30c2d1c 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -536,7 +536,7 @@ namespace nana struct arg_click : public event_arg { ::nana::window window_handle; ///< A handle to the event window - const arg_mouse* mouse_args; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise. + const arg_mouse* mouse_args{}; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise. }; /// provides some fundamental events that every widget owns. diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 42ac9123..f2c97612 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -295,7 +295,18 @@ namespace nana throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); return *p; } + template + T & value() + { + auto * pany = _m_value(); + if (nullptr == pany) + throw std::runtime_error("listbox::item_proxy.value() is empty"); + T * p = any_cast(_m_value(false)); + if (nullptr == p) + throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); + return *p; + } template item_proxy & value(T&& t) { diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 88317ede..70bc1714 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -1,7 +1,7 @@ -/* +/** * Platform Specification Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -9,7 +9,7 @@ * * @file: nana/detail/platform_spec.cpp * - * This file provides basis class and data structrue that required by nana + * @brief basis classes and data structrues required by nana */ #include From fd2971c87f96fbf0b6e934bcf143ed07d6710ba9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 16:59:54 +0100 Subject: [PATCH 02/15] runtime reduction of incompatibilities and potential crash: rewrite !! --- source/detail/platform_spec_windows.cpp | 169 +++++++++++++++++++++++- 1 file changed, 166 insertions(+), 3 deletions(-) diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 70bc1714..a2968f5b 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -19,9 +19,172 @@ #include #include -#if defined(_MSC_VER) -#include -#endif // _MSVC + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +/****************************************************************** +* * +* VersionHelpers.h -- This module defines helper functions to * +* promote version check with proper * +* comparisons. * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +******************************************************************/ + +#include // for _In_, etc. + +#if !defined(__midl) && !defined(SORTPP_PASS) + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +#ifdef __cplusplus + +#define VERSIONHELPERAPI inline bool + +#else // __cplusplus + +#define VERSIONHELPERAPI FORCEINLINE BOOL + +#endif // __cplusplus + +VERSIONHELPERAPI +IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +VERSIONHELPERAPI +IsWindowsXPOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + +VERSIONHELPERAPI +IsWindowsXPSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1); +} + +VERSIONHELPERAPI +IsWindowsXPSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2); +} + +VERSIONHELPERAPI +IsWindowsXPSP3OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3); +} + +VERSIONHELPERAPI +IsWindowsVistaOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +VERSIONHELPERAPI +IsWindowsVistaSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1); +} + +VERSIONHELPERAPI +IsWindowsVistaSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2); +} + +VERSIONHELPERAPI +IsWindows7OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +} + +VERSIONHELPERAPI +IsWindows7SP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); +} + +#ifndef _WIN32_WINNT_WIN8 // (0x0602) + #define _WIN32_WINNT_WIN8 (0x0602) +#endif // _WIN32_WINNT_WIN8(0x0602) + +VERSIONHELPERAPI +IsWindows8OrGreater() +{ + + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +} + +#ifndef _WIN32_WINNT_WINBLUE // (0x0602) + #define _WIN32_WINNT_WINBLUE (0x0602) +#endif // _WIN32_WINNT_WINBLUE (0x0602) + +VERSIONHELPERAPI +IsWindows8Point1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); +} + +VERSIONHELPERAPI +IsWindowsServer() +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0, 0, VER_NT_WORKSTATION }; + DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL); + + return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask); +} + +#endif // NTDDI_VERSION + +#endif // defined(__midl) + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// + + + +//#if defined(_MSC_VER) +////#include +//bool IsWindowsVistaOrGreater() { return false; } +//bool //VERSIONHELPERAPI +//IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +//{ +// OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; +// DWORDLONG const dwlConditionMask = VerSetConditionMask( +// VerSetConditionMask( +// VerSetConditionMask( +// 0, VER_MAJORVERSION, VER_GREATER_EQUAL), +// VER_MINORVERSION, VER_GREATER_EQUAL), +// VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); +// +// osvi.dwMajorVersion = wMajorVersion; +// osvi.dwMinorVersion = wMinorVersion; +// osvi.wServicePackMajor = wServicePackMajor; +// +// return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +//} +// +// +// +//#endif // _MSVC namespace nana { From a9ef23d8d85bac29ed6aa963d7892121c9a8c895 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 17:03:32 +0100 Subject: [PATCH 03/15] utf8_Error:std::runtime_error +static bool use_throw{true} and emit(); --- source/deploy.cpp | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/source/deploy.cpp b/source/deploy.cpp index 91c4300d..ba6a0907 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -479,6 +479,8 @@ namespace std } //#endif // STD_put_time_NOT_SUPPORTED +#include + namespace nana { bool is_utf8(const char* str, unsigned len) @@ -511,22 +513,52 @@ namespace nana return true; } + struct utf8_Error : std::runtime_error + { + static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? + + utf8_Error(const std::string& what_arg) + :std::runtime_error{ std::string("\nRun-time utf8 Error: ") + what_arg } + {} + + utf8_Error(const char * what_arg) + :utf8_Error{ std::string(what_arg) } + {} + + + void emit() + { + if (use_throw) + throw utf8_Error(*this); + std::cerr << what(); + } + }; + + //bool utf8_Error::use_throw{true}; + bool utf8_Error::use_throw{ false }; + void throw_not_utf8(const std::string& text) { if (!is_utf8(text.c_str(), text.length())) - throw std::invalid_argument("The text is not encoded in UTF8"); + return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + + //throw std::invalid_argument( std::string("The text is not encoded in UTF8: ")+text ) ; } void throw_not_utf8(const char* text, unsigned len) { if (!is_utf8(text, len)) - throw std::invalid_argument("The text is not encoded in UTF8"); + return utf8_Error(std::string("The text is not encoded in UTF8: ") + std::string(text, len) ).emit(); + + //throw std::invalid_argument("The text is not encoded in UTF8"); } void throw_not_utf8(const char* text) { if (!is_utf8(text, std::strlen(text))) - throw std::invalid_argument("The text is not encoded in UTF8"); + return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + + //throw std::invalid_argument("The text is not encoded in UTF8"); } From 10eaa91c3ce6e6898419c852a8d0d85c123375a2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 22:20:48 +0100 Subject: [PATCH 04/15] experimenting with review_utf8 --- include/nana/deploy.hpp | 6 +++++ source/deploy.cpp | 48 +++++++++++++++++++++++++--------- source/gui/msgbox.cpp | 6 +++-- source/gui/widgets/listbox.cpp | 1 + 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 069545cb..0f7cb8c9 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -119,6 +119,12 @@ namespace nana void throw_not_utf8(const char*, unsigned len); void throw_not_utf8(const char*); + /// this text needed change, it needed review ?? + bool review_utf8(const std::string& text); + + /// this text needed change, it needed review ?? + bool review_utf8(std::string& text); + const std::string& to_utf8(const std::string&); std::string to_utf8(const std::wstring&); diff --git a/source/deploy.cpp b/source/deploy.cpp index ba6a0907..0e6b0faf 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -513,19 +513,13 @@ namespace nana return true; } + /// move to *.h ?? struct utf8_Error : std::runtime_error { static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? - - utf8_Error(const std::string& what_arg) - :std::runtime_error{ std::string("\nRun-time utf8 Error: ") + what_arg } - {} - - utf8_Error(const char * what_arg) - :utf8_Error{ std::string(what_arg) } - {} - - + + using std::runtime_error::runtime_error; + void emit() { if (use_throw) @@ -541,8 +535,6 @@ namespace nana { if (!is_utf8(text.c_str(), text.length())) return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); - - //throw std::invalid_argument( std::string("The text is not encoded in UTF8: ")+text ) ; } void throw_not_utf8(const char* text, unsigned len) @@ -562,6 +554,38 @@ namespace nana } + std::string recode_to_utf8(std::string no_utf8) + { + return nana::charset(no_utf8).to_bytes(nana::unicode::utf8); + } + + /// this text needed change, it needed review ?? + bool review_utf8(const std::string& text) + { + if (!is_utf8(text.c_str(), text.length())) + { + utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + return true; /// it needed change, it needed review !! + } + else + return false; + } + + /// this text needed change, it needed review ?? + bool review_utf8(std::string& text) + { + if (!is_utf8(text.c_str(), text.length())) + { + utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + text.swap(recode_to_utf8(text)); + return true; /// it needed change, it needed review !! + } + else + return false; + } + + + const std::string& to_utf8(const std::string& str) { return str; diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 8d4914f6..e3accf06 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -355,13 +355,15 @@ namespace nana msgbox::msgbox(const std::string& title) : wd_(nullptr), title_(title), button_(ok), icon_(icon_none) { - throw_not_utf8(title_); + // throw_not_utf8(title_); + review_utf8(title_); } msgbox::msgbox(window wd, const std::string& title, button_t b) : wd_(wd), title_(title), button_(b), icon_(icon_none) { - throw_not_utf8(title_); + // throw_not_utf8(title_); + review_utf8(title_); } msgbox& msgbox::icon(icon_t ic) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 56eff953..405e88a4 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3148,6 +3148,7 @@ namespace nana { auto cell_txtcolor = fgcolor; auto & m_cell = item.cells[column_pos]; + review_utf8(m_cell.text); nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need From b0815fafca450801e1a6a3bd87043f61d8ef4d63 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 22:22:55 +0100 Subject: [PATCH 05/15] cool, the program disappear inversely --- source/gui/place.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 1a0e5cb1..e712b063 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -528,8 +528,14 @@ namespace nana { for (auto i = elements.begin(), end = elements.end(); i != end; ++i) { - if (!API::is_destroying(API::get_parent_window(wd))) - place_ptr_->collocate(); + if (i->handle == wd) + { + elements.erase(i); + + if (!API::is_destroying(API::get_parent_window(wd))) + place_ptr_->collocate(); + break; + } } }); } From 266def9ee31bec4712eda6083a2a56bf8b1b86cb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 23 Mar 2016 17:19:54 +0100 Subject: [PATCH 06/15] Doxy comments --- include/nana/charset.hpp | 50 ++++++++++++++++++++-------------------- source/charset.cpp | 13 ++++++----- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/nana/charset.hpp b/include/nana/charset.hpp index 41fa4d72..09f79bdf 100644 --- a/include/nana/charset.hpp +++ b/include/nana/charset.hpp @@ -46,7 +46,31 @@ namespace nana class charset_encoding_interface; } - /// An intelligent charset class for character code conversion. + /*!\class charset + \brief An intelligent charset class for character code conversion. + Example: + 1. A UTF-8 string from the socket. + + int len = ::recv(sd, buf, buflen, 0); + textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8)); + + 2. Send the string in text to the socket as UTF-8. + + std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8); + ::send(sd, utf8str.c_str(), utf8str.size(), 0); + + 3, Convert a string to the specified multi-byte character code. + + // Convert to a multibytes string through default system language. + std::string mbstr = nana::charset(a_wstring); + + // If the default system language is English and convert + // a Chinese unicode string to multibytes string through GB2312 + std::setlocale(LC_CTYPE, "zh_CN.GB2312"); + //set::setlocale(LC_CTYPE, ".936"); call it in Windows + std::string mbstr = nana::charset(a_wstring_with_chinese); + + */ class charset { public: @@ -74,27 +98,3 @@ namespace nana }//end namespace nana #endif -/*!\class charset - -Example -1. A UTF-8 string from the socket. - - int len = ::recv(sd, buf, buflen, 0); - textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8)); - -2. Send the string in text to the socket as UTF-8. - - std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8); - ::send(sd, utf8str.c_str(), utf8str.size(), 0); - -3, Convert a string to the specified multi-byte character code. - - //Convert to a multibytes string through default system language. - std::string mbstr = nana::charset(a_wstring); - //If the default system language is English and convert - //a Chinese unicode string to multibytes string through GB2312 - std::setlocale(LC_CTYPE, "zh_CN.GB2312"); - //set::setlocale(LC_CTYPE, ".936"); call it in Windows - std::string mbstr = nana::charset(a_wstring_with_chinese); - -*/ \ No newline at end of file diff --git a/source/charset.cpp b/source/charset.cpp index 686f8182..95753662 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -578,37 +578,38 @@ namespace nana std::string data_for_move_; }; #else + /// return the first code point and move the pointer to next character, springing to the end by errors unsigned long utf8char(const unsigned char*& p, const unsigned char* end) { if(p != end) { - if(*p < 0x80) + if(*p < 0x80) // ASCII char 0-127 or 0-0x80 { return *(p++); } unsigned ch = *p; unsigned long code; - if(ch < 0xC0) + if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { p = end; return 0; } - else if(ch < 0xE0 && (p + 1 <= end)) + else if(ch < 0xE0 && (p + 1 <= end)) // two byte chararcter { code = ((ch & 0x1F) << 6) | (p[1] & 0x3F); p += 2; } - else if(ch < 0xF0 && (p + 2 <= end)) + else if(ch < 0xF0 && (p + 2 <= end)) // 3 byte character { code = ((((ch & 0xF) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F); p += 3; } - else if(ch < 0x1F && (p + 3 <= end)) + else if(ch < 0x1F && (p + 3 <= end)) // 4 byte character { code = ((((((ch & 0x7) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F)) << 6) | (p[3] & 0x3F); p += 4; } - else + else // error, go to end { p = end; return 0; From db9167bb2182f8a3449615581aac74bd003fc479 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 23 Mar 2016 17:21:42 +0100 Subject: [PATCH 07/15] change default error behavior to preserve bad code unit as valid utf8 --- source/charset.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/charset.cpp b/source/charset.cpp index 95753662..ed4d643f 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -591,6 +591,7 @@ namespace nana unsigned long code; if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { + return *(p++); // temp: assume equal p = end; return 0; } From 6b2d5afa6b779dcb4d33d50b14cf2291329ee8f1 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 24 Mar 2016 03:14:18 +0100 Subject: [PATCH 08/15] move utf8_Error to *.h --- include/nana/deploy.hpp | 11 +++++++++++ source/deploy.cpp | 10 +--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index f172fb71..f031c66d 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -114,6 +114,17 @@ namespace std namespace nana { + /// move to *.h ?? + struct utf8_Error : std::runtime_error + { + static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? + + using std::runtime_error::runtime_error; + + void emit(); + }; + + /// Checks whether a specified text is utf8 encoding bool is_utf8(const char* str, unsigned len); void throw_not_utf8(const std::string& text); diff --git a/source/deploy.cpp b/source/deploy.cpp index 0e6b0faf..bf2f69d2 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -513,20 +513,12 @@ namespace nana return true; } - /// move to *.h ?? - struct utf8_Error : std::runtime_error - { - static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? - - using std::runtime_error::runtime_error; - - void emit() + void utf8_Error::emit() { if (use_throw) throw utf8_Error(*this); std::cerr << what(); } - }; //bool utf8_Error::use_throw{true}; bool utf8_Error::use_throw{ false }; From b2b2bf2858961d525fc768c5989cffe2b0810d1b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 24 Mar 2016 03:30:14 +0100 Subject: [PATCH 09/15] experimenting with def_encoding_error_police in my case all the 5 variant are working very well !! --- source/charset.cpp | 116 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 15 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index ed4d643f..d5e1edda 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1,4 +1,4 @@ -/* +/** * A Character Encoding Set Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,9 +7,9 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/charset.cpp - * @brief: A conversion between unicode characters and multi bytes characters - * @contributions: + * @file nana/charset.cpp + * @brief A conversion between unicode characters and multi bytes characters + * @contributions * UTF16 4-byte decoding issue by Renke Yan. * Pr0curo(pr#98) */ @@ -20,6 +20,7 @@ #include #include #include //Added by Pr0curo(pr#98) +#include //GCC 4.7.0 does not implement the and codecvt_utfx classes #ifndef STD_CODECVT_NOT_SUPPORTED @@ -210,22 +211,23 @@ namespace nana } namespace detail - { + { + /// candidate to be more general?? class locale_initializer { public: static void init() { static bool initialized = false; - if(false == initialized) - { - initialized = true; - //Only set the C library locale - std::setlocale(LC_CTYPE, ""); - } + if (initialized) return; + + initialized = true; + //Only set the C library locale + std::setlocale(LC_CTYPE, ""); } }; + /// convert wchar C string from ? ANSI code page CP_ACP (windows) or LC_CTYPE c locale (-nix) into utf8 std::string bool wc2mb(std::string& mbstr, const wchar_t * s) { if(nullptr == s || *s == 0) @@ -258,7 +260,8 @@ namespace nana #endif return true; } - + + /// convert a char C-string from The system default Windows ANSI code page CP_ACP or from LC_CTYPE c locale (-nix) into utf16 std::wstring bool mb2wc(std::wstring& wcstr, const char* s) { if(nullptr == s || *s == 0) @@ -291,6 +294,7 @@ namespace nana return true; } + /// convert a char C string from The system default Windows ANSI code page CP_ACP or LC_CTYPE c locale (-nix) into utf16 std::string bool mb2wc(std::string& wcstr, const char* s) { if(nullptr == s || *s == 0) @@ -304,6 +308,7 @@ namespace nana { wcstr.resize((chars - 1) * sizeof(wchar_t)); ::MultiByteToWideChar(CP_ACP, 0, s, -1, reinterpret_cast(&wcstr[0]), chars - 1); + // ^ the trick ! } #else locale_initializer::init(); @@ -338,6 +343,84 @@ namespace nana virtual std::wstring&& wstr_move() = 0; }; + /// playing with the idea - we need a mechanisme to set a user selected police - Testing an abtract interphase + struct encoding_error_police + { + virtual unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) = 0; + virtual ~encoding_error_police() = default; + }; + + /// the current nana default: it is safe - you may want to keep it ! use the other at your risk: mainly for debugging + struct utf8_error_police : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + current_code_unit = end; + return 0; + } + + }; + + /// + struct utf8_error_police_def_char : public encoding_error_police + { + static unsigned long def_error_mark ; + + unsigned long error_mark{ def_error_mark }; + utf8_error_police_def_char() = default; + utf8_error_police_def_char( unsigned long mark): error_mark{mark}{} + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + ++current_code_unit; //check (p != end) ? + return error_mark; + } + + }; + + unsigned long utf8_error_police_def_char::def_error_mark{ '*' }; + + /// + struct utf8_error_police_throw : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + //utf8_Error::use_throw = true; + utf8_Error(std::string("The text is not encoded in UTF8: ") + + reinterpret_cast( current_code_unit) ).emit();; + current_code_unit = end; + return 0; + } + + }; + + struct utf8_error_police_latin : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + return *(current_code_unit++) ; + } + }; + + struct utf8_error_police_system : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + std::wstring wc; + mb2wc(wc, reinterpret_cast(current_code_unit)); + current_code_unit++; + return wc[0]; // use utf16char + } + }; + + + auto def_encoding_error_police = std::make_unique(); // the nana default +// auto def_encoding_error_police = std::make_unique(); +// auto def_encoding_error_police = std::make_unique(); +// auto def_encoding_error_police = std::make_unique('X'); +// auto def_encoding_error_police = std::make_unique(); + + + #ifndef STD_CODECVT_NOT_SUPPORTED class charset_string : public charset_encoding_interface @@ -578,6 +661,8 @@ namespace nana std::string data_for_move_; }; #else + + /// return the first code point and move the pointer to next character, springing to the end by errors unsigned long utf8char(const unsigned char*& p, const unsigned char* end) { @@ -591,9 +676,10 @@ namespace nana unsigned long code; if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { - return *(p++); // temp: assume equal - p = end; - return 0; + //return *(p++); // temp: assume equal + //p = end; + //return 0; + return def_encoding_error_police->next_code_point(p, end); } else if(ch < 0xE0 && (p + 1 <= end)) // two byte chararcter { From c963bb2a3e73130fffebe26b9b0328c7e47fe2a0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 24 Mar 2016 03:43:39 +0100 Subject: [PATCH 10/15] fix error with compiling with gcc in Linux --- source/deploy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/deploy.cpp b/source/deploy.cpp index bf2f69d2..8054c07d 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -569,7 +569,7 @@ namespace nana if (!is_utf8(text.c_str(), text.length())) { utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); - text.swap(recode_to_utf8(text)); + text=recode_to_utf8(text); return true; /// it needed change, it needed review !! } else From a7c58709576fd882e00c857b87bea4d0f61a2ab2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 25 Mar 2016 00:48:49 +0100 Subject: [PATCH 11/15] FIX convert from system non Unicode to Unicode --- source/charset.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index d5e1edda..573e1e91 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1156,10 +1156,10 @@ namespace nana switch(encoding) { case unicode::utf8: - return utf32_to_utf8(wcstr); - case unicode::utf16: - return utf32_to_utf16(wcstr); + return utf16_to_utf8(wcstr); case unicode::utf32: + return utf16_to_utf32(wcstr); + case unicode::utf16: return wcstr; } } From e8df4b4f69fae64eecc1dda4a9a4e10e3d0dad48 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 25 Mar 2016 00:50:09 +0100 Subject: [PATCH 12/15] comments and using system default encoding as utf error "police" --- source/charset.cpp | 21 ++++++++++++++------- source/deploy.cpp | 12 ++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index 573e1e91..42fc386a 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -35,6 +35,7 @@ namespace nana { namespace utf { + /// return a pointer to the code unit of the character at pos const char* char_ptr(const char* text, unsigned pos) { auto ustr = reinterpret_cast(text); @@ -49,10 +50,10 @@ namespace nana continue; } - if (uch < 0xC0) + if (uch < 0xC0) // use police ? return nullptr; - if ((uch < 0xE0) && (ustr + 1 < end)) + if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0 ustr += 2; else if (uch < 0xF0 && (ustr + 2 <= end)) ustr += 3; @@ -65,6 +66,7 @@ namespace nana return reinterpret_cast(ustr); } + /// return a pointer to the code unit of the character at pos - reuse ^ ? const char* char_ptr(const std::string& text_utf8, unsigned pos) { auto ustr = reinterpret_cast(text_utf8.c_str()); @@ -95,6 +97,7 @@ namespace nana return reinterpret_cast(ustr); } + /// return a code point (max 16 bits?) and the len in code units of the character at pos wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len) { if (!text_utf8) @@ -113,10 +116,10 @@ namespace nana if (len) *len = 1; - return *text_utf8; + return *text_utf8; // uch ? } - if (uch < 0xC0) + if (uch < 0xC0) // use police or ?? { if (len) *len = 0; @@ -152,6 +155,7 @@ namespace nana return 0; } + /// return a code point (max 16 bits?) and the len in code units of the character at pos wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len) { const char* ptr; @@ -401,6 +405,7 @@ namespace nana } }; + /// buggie? struct utf8_error_police_system : public encoding_error_police { unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override @@ -408,16 +413,18 @@ namespace nana std::wstring wc; mb2wc(wc, reinterpret_cast(current_code_unit)); current_code_unit++; - return wc[0]; // use utf16char + //wchar_t *p = &wc[0]; + + return wc[0]; // use utf16char but what endian? } }; - auto def_encoding_error_police = std::make_unique(); // the nana default +// auto def_encoding_error_police = std::make_unique(); // the nana default // auto def_encoding_error_police = std::make_unique(); // auto def_encoding_error_police = std::make_unique(); // auto def_encoding_error_police = std::make_unique('X'); -// auto def_encoding_error_police = std::make_unique(); + auto def_encoding_error_police = std::make_unique(); diff --git a/source/deploy.cpp b/source/deploy.cpp index 8054c07d..eb79b86a 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -526,13 +526,13 @@ namespace nana void throw_not_utf8(const std::string& text) { if (!is_utf8(text.c_str(), text.length())) - return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit(); } void throw_not_utf8(const char* text, unsigned len) { if (!is_utf8(text, len)) - return utf8_Error(std::string("The text is not encoded in UTF8: ") + std::string(text, len) ).emit(); + return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit(); //throw std::invalid_argument("The text is not encoded in UTF8"); } @@ -540,7 +540,7 @@ namespace nana void throw_not_utf8(const char* text) { if (!is_utf8(text, std::strlen(text))) - return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit(); //throw std::invalid_argument("The text is not encoded in UTF8"); @@ -548,7 +548,7 @@ namespace nana std::string recode_to_utf8(std::string no_utf8) { - return nana::charset(no_utf8).to_bytes(nana::unicode::utf8); + return nana::charset(std::move(no_utf8)).to_bytes(nana::unicode::utf8); } /// this text needed change, it needed review ?? @@ -556,7 +556,7 @@ namespace nana { if (!is_utf8(text.c_str(), text.length())) { - utf8_Error(std::string("The 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 !! } else @@ -568,7 +568,7 @@ namespace nana { if (!is_utf8(text.c_str(), text.length())) { - utf8_Error(std::string("The 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); return true; /// it needed change, it needed review !! } From 8ab30d7457456a31c50320d5ad3684980a1fbd36 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 26 Mar 2016 16:25:56 +0100 Subject: [PATCH 13/15] doxy docs --- include/nana/gui/detail/basic_window.hpp | 67 +++++++++++------------- include/nana/gui/widgets/listbox.hpp | 28 +++++----- include/nana/gui/widgets/slider.hpp | 2 +- source/gui/detail/window_layout.cpp | 6 +-- source/gui/widgets/listbox.cpp | 24 ++++++--- 5 files changed, 69 insertions(+), 58 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index e2e68fe1..22f51122 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -1,4 +1,4 @@ -/* +/** * A Basic Window Widget Definition * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,7 +7,8 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/detail/basic_window.hpp + * @file nana/gui/detail/basic_window.hpp + * @brief A Basic Window Widget Definition */ #ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP @@ -58,20 +59,18 @@ namespace detail ::nana::rectangle effective_range_; };//end class caret_descriptor - //tab_type - //@brief: Define some constant about tab category, these flags can be combine with operator | + /// Define some constant about tab category, these flags can be combine with operator | struct tab_type { enum t { - none, //process by nana - tabstop, //move to the next tabstop window - eating, //process by current window + none, ///< process by nana + tabstop, ///< move to the next tabstop window + eating, ///< process by current window }; }; - //struct basic_window - //@brief: a window data structure descriptor + /// a window data structure descriptor struct basic_window : public events_holder { @@ -88,8 +87,7 @@ namespace detail bool rendered; }; - //basic_window - //@brief: constructor for the root window + /// constructor for the root window basic_window(basic_window* owner, std::unique_ptr&&, category::root_tag**); template @@ -106,8 +104,7 @@ namespace detail ~basic_window(); - //bind_native_window - //@brief: bind a native window and baisc_window + /// bind a native window and baisc_window void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&); void frame_window(native_window_type); @@ -116,13 +113,13 @@ namespace detail bool visible_parents() const; bool displayed() const; bool belong_to_lazy() const; - const basic_window * child_caret() const; //Returns a child which owns a caret + const basic_window * child_caret() const; ///< Returns the child which owns the caret bool is_draw_through() const; ///< Determines whether it is a draw-through window. basic_window * seek_non_lite_widget_ancestor() const; public: - //Override event_holder + /// Override event_holder bool set_events(const std::shared_ptr&) override; general_events * get_events() const override; private: @@ -132,7 +129,7 @@ namespace detail #if defined(NANA_LINUX) || defined(NANA_MACOS) point pos_native; #endif - point pos_root; //coordinate for root window + point pos_root; ///< coordinates of the root window point pos_owner; size dimension; ::nana::size min_track_size; @@ -147,9 +144,9 @@ namespace detail basic_window *owner; native_string_type title; - ::nana::detail::drawer drawer; //Self Drawer with owen graphics - basic_window* root_widget; //A pointer refers to the root basic window, if the window is a root, the pointer refers to itself. - paint::graphics* root_graph; //Refer to the root buffer graphics + ::nana::detail::drawer drawer; ///< Self Drawer with owen graphics + basic_window* root_widget; ///< A pointer refers to the root basic window, if the window is a root, the pointer refers to itself. + paint::graphics* root_graph; ///< Refer to the root buffer graphics cursor predef_cursor; std::unique_ptr widget_notifier; @@ -157,20 +154,20 @@ namespace detail { bool enabled :1; bool dbl_click :1; - bool captured :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle + bool captured :1; ///< if mouse button is down, it always receive mouse move even the mouse is out of its rectangle bool modal :1; - bool take_active:1; //If take_active is false, other.active_window still keeps the focus. + bool take_active:1; ///< If take_active is false, other.active_window still keeps the focus. bool refreshing :1; bool destroying :1; - bool dropable :1; //Whether the window has make mouse_drop event. - bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen. + bool dropable :1; ///< Whether the window has make mouse_drop event. + bool fullscreen :1; ///< When the window is maximizing whether it fit for fullscreen. bool borderless :1; - bool make_bground_declared : 1; //explicitly make bground for bground effects - bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus. - bool ignore_mouse_focus : 1; //A flag indicates whether the widget accepts focus when clicking on it - bool space_click_enabled : 1; //A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key. + bool make_bground_declared : 1; ///< explicitly make bground for bground effects + bool ignore_menubar_focus : 1; ///< A flag indicates whether the menubar sets the focus. + bool ignore_mouse_focus : 1; ///< A flag indicates whether the widget accepts focus when clicking on it + bool space_click_enabled : 1; ///< A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key. unsigned Reserved :18; - unsigned char tab; //indicate a window that can receive the keyboard TAB + unsigned char tab; ///< indicate a window that can receive the keyboard TAB mouse_action action; }flags; @@ -199,7 +196,7 @@ namespace detail struct attr_root_tag { - container frames; //initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame + container frames; ///< initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame container tabstop; std::vector effects_edge_nimbus; basic_window* focus{nullptr}; @@ -211,13 +208,13 @@ namespace detail cursor state_cursor{nana::cursor::arrow}; basic_window* state_cursor_window{ nullptr }; - std::function draw_through; // A draw through renderer for root widgets. + std::function draw_through; ///< A draw through renderer for root widgets. }; const category::flags category; - basic_window *active_window; //if flags.take_active is false, the active_window still keeps the focus, - //if the active_window is null, the parent of this window keeps focus. - paint::graphics glass_buffer; //if effect.bground is avaiable. Refer to window_layout::make_bground. + basic_window *active_window; ///< if flags.take_active is false, the active_window still keeps the focus, + ///< if the active_window is null, the parent of this window keeps focus. + paint::graphics glass_buffer; ///< if effect.bground is avaiable. Refer to window_layout::make_bground. update_state upd_state; union @@ -230,8 +227,8 @@ namespace detail ~other_tag(); }other; - native_window_type root; //root Window handle - unsigned thread_id; //the identifier of the thread that created the window. + native_window_type root; ///< root Window handle + unsigned thread_id; ///< the identifier of the thread that created the window. unsigned index; container children; }; diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 0f1e24e2..82e9abb1 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -517,7 +517,7 @@ namespace nana basic_event checked; basic_event selected; - /// An event occurs when a listbox category is double clicking. + /// An event that occurs when a listbox category is double clicking. basic_event category_dbl_click; }; @@ -536,19 +536,23 @@ namespace nana }//end namespace drawerbase /*! \class listbox -\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. -A category is a text with can be \a selected, \a checked and \a expanded to show the items. -An item is formed by \a column-fields, each corresponding to one of the \a headers. -An item can be \a selected and \a checked. +\brief A rectangle containing a list of strings from which the user can select. +This widget contain a list of \a categories, with in turn contain a list of \a items. +A \a category is a text with can be \a selected, \a checked and \a expanded to show the \a items. +An \a item is formed by \a column-fields, each corresponding to one of the \a headers. +An \a item can be \a selected and \a checked. The user can \a drag the header to \a resize it or to \a reorganize it. By \a clicking on one header the list get \a reordered, first up, and then down alternatively. -1. The resolver is used to resolute an object of the specified type for a listbox item. -3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. +1. The resolver is used to resolute an object of the specified type into (or back from) a listbox item. +3. nana::listbox creates the category 0 by default. + This is an special category, becouse it is invisible, while the associated items are visible. + The optional, user-created categories begin at index 1 and are visibles. + The member functions without the categ parameter operate the items that belong to category 0. 4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: Irreflexivity (comp(x, x) returns false) and - antisymmetry(comp(a, b) != comp(b, a) returns true) + Antisymmetry(comp(a, b) != comp(b, a) returns true) A simple example. bool sort_compare( const std::string& s1, nana::any*, const std::string& s2, nana::any*, bool reverse) @@ -563,10 +567,10 @@ By \a clicking on one header the list get \a reordered, first up, and then down { if(o1 && o2) //some items may not attach a customer object. { - int * i1 = o1->get(); - int * i2 = o2->get(); + int * i1 = any_cast(*o1); + int * i2 = any_cast(*o2); return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2)); - ;//some types may not be int. + // ^ some types may not be int. } return false; } @@ -710,7 +714,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down size_type size_categ() const; /// { diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 10a94e4d..edfafa3c 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -95,9 +95,9 @@ namespace nana } //read_visual_rectangle - //@brief: Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget, - // the visual rectangle is a rectangular block that a window should be displayed on screen. - // The result is a rectangle that is a visible area for its ancesters. + ///@brief Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget, + /// the visual rectangle is a rectangular block that a window should be displayed on screen. + /// The result is a rectangle that is a visible area for its ancesters. bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual) { if (! wd->displayed()) return false; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 723916ba..9604ac24 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -338,6 +338,7 @@ namespace nana column_t(native_string_type&& txt, unsigned px, size_type pos) : text(std::move(txt)), pixels(px), index(pos) {} + /// \todo introduce default cell format }; using container = std::vector ; @@ -1828,9 +1829,7 @@ namespace nana };//end class es_lister - //struct essence_t - //@brief: this struct gives many data for listbox, - // the state of the struct does not effect on member funcions, therefore all data members are public. + /// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public. struct essence_t { enum class item_state{normal, highlighted, pressed, grabbed, floated}; @@ -2644,6 +2643,7 @@ namespace nana item_spliter_ = npos; } + /// return true an set member item_spliter_ if x is in the spliter area after that header item (column) bool mouse_spliter(const nana::rectangle& r, int x) { if(essence_->ptr_state == item_state::highlighted) @@ -3003,9 +3003,19 @@ namespace nana } } - //Draws an item - //@param content_r the rectangle of list content - void _m_draw_item(const category_t& cat, const index_pair& item_pos, const int x, const int y, const int txtoff, unsigned width, const nana::rectangle& content_r, const std::vector& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const + /// Draws an item + void _m_draw_item(const category_t& cat, + const index_pair& item_pos, + const int x, + const int y, + const int txtoff, + unsigned width, + const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn + const std::vector& seqs, + nana::color bgcolor, + nana::color fgcolor, + item_state state + ) const { auto & item = cat.items[item_pos.item]; @@ -3022,7 +3032,7 @@ namespace nana if (item.flags.selected) bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected" else - bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); + bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } unsigned show_w = width - essence_->scroll.offset_x; From 5779b979f7e71b25969d18f31426189ce9355cfe Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 26 Mar 2016 16:32:45 +0100 Subject: [PATCH 14/15] implement some geometrical parameters ?? --- include/nana/gui/widgets/listbox.hpp | 14 ++++++++++++-- source/gui/widgets/listbox.cpp | 11 ++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 82e9abb1..cfad6214 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -529,8 +529,18 @@ namespace nana color_proxy header_floated{ static_cast(0xBABBBC)}; color_proxy item_selected{ static_cast(0xD5EFFC) }; - unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ?? - ext_w = 5; + /// \todo how to implement some geometrical parameters ?? + unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this + unsigned min_header_width{ 20 }; ///< non counting suspension_width + unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...") + unsigned ext_w { 5 }; ///< ?? + unsigned header_height { 20 }; ///< header height header_size + unsigned text_height { 0 }; ///< the trigger will set this to the height of the text font + unsigned item_height_ex { 6 }; ///< 6? item_height = text_height + item_height_ex + unsigned item_height { 0 }; ///< the trigger will set this TO item_height = text_height + item_height_ex + unsigned header_mouse_spliter_area_before{ 2 }; + unsigned header_mouse_spliter_area_after { 3 }; + }; } }//end namespace drawerbase diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 9604ac24..a0d30cdd 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1858,7 +1858,7 @@ namespace nana struct scroll_part { - static const unsigned scale = 16; + static const unsigned scale = 16; // ? int offset_x; index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. // need to be abs??? to see the same item after sort() ?? @@ -1982,8 +1982,9 @@ namespace nana void trace_item_abs( index_pair abs_pos ) { - if(abs_pos.item == npos && abs_pos.cat == scroll.offset_y_abs.cat - && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat + if( abs_pos.item == npos + && abs_pos.cat == scroll.offset_y_abs.cat + && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat return; trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ; @@ -2680,8 +2681,8 @@ namespace nana } //grab_move - //@brief: draw when an item is grabbing. - //@return: 0 = no graphics changed, 1 = just update, 2 = refresh + /// @brief draw when an item is grabbing. + /// @return 0 = no graphics changed, 1 = just update, 2 = refresh int grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) From c1f95c7f3cebd23b511a029364a187e9454d0bb6 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 20:50:51 +0200 Subject: [PATCH 15/15] small fix, more comments --- source/gui/widgets/listbox.cpp | 60 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index a0d30cdd..707eb339 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -329,7 +329,7 @@ namespace nana struct column_t { native_string_type text; ///< "text" header of the column number "index" with weigth "pixels" - unsigned pixels; + unsigned pixels; ///< width bool visible{true}; size_type index; std::function weak_ordering; @@ -411,7 +411,7 @@ namespace nana return cont_.back().index; } - void item_width(size_type pos, unsigned width) + void item_width(size_type pos, unsigned width) ///< set the column width { column(pos).pixels = width; } @@ -428,7 +428,7 @@ namespace nana return 0; } - unsigned pixels() const + unsigned pixels() const ///< the visible width of the whole header { unsigned pixels = 0; for(auto & m : cont_) @@ -471,12 +471,13 @@ namespace nana { if(x < static_cast(col.pixels)) return col.index; - x -= col.pixels; + if (col.visible) + x -= col.pixels; } return npos; } - /// return the left position of the column originaly at index "pos" . + /// return the left position and width (in variable *pixels) of the column originaly at index "pos" . int item_pos(size_type pos, unsigned * pixels) const { int left = 0; @@ -494,7 +495,8 @@ namespace nana } return left; } - /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" + + /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" size_type neighbor(size_type index, bool front) const { size_type n = npos; @@ -510,11 +512,12 @@ namespace nana break; } else if(i->visible) - n = i->index; + n = i->index; } return npos; } - /// return the original index of the currently first visible col + + /// return the original index of the currently first visible col size_type begin() const { for(const auto & m : cont_) @@ -533,7 +536,8 @@ namespace nana } return npos; } - /// move the col originaly at index to the position currently in front (or after) the col originaly at index "to" invalidating some current index + + /// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index void move(size_type index, size_type to, bool front) throw() { if ((index == to) || (index >= cont_.size()) || (to >= cont_.size())) @@ -880,7 +884,8 @@ namespace nana list_.back().key_ptr = ptr; return &list_.back(); } - /// add a new cat created at "pos" and return a ref to it + + /// add a new cat created at "pos" and return a ref to it category_t* create_cat(std::size_t pos, native_string_type&& text) { return &(*list_.emplace(this->get(pos), std::move(text))); @@ -1941,8 +1946,8 @@ namespace nana //number_of_lister_item - //@brief: Returns the number of items that are contained in pixels - //@param,with_rest: Means whether including extra one item that is not completely contained in reset pixels. + /// @brief Returns the number of items that are contained in pixels + /// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels. size_type number_of_lister_items(bool with_rest) const { unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale); @@ -2072,10 +2077,10 @@ namespace nana bool v = (lister.the_number_of_expanded() > screen_number); if(v == true && h == false) - h = (header_s > (sz.width - 2 - scroll.scale)); + h = ( (header_s + 2 + scroll.scale ) > sz.width); // 2? - unsigned width = sz.width - 2 - (v ? scroll.scale : 0); - unsigned height = sz.height - 2 - (h ? scroll.scale : 0); + unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2? + unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2? //event hander for scrollbars auto evt_fn = [this](const arg_scroll& arg) @@ -2168,7 +2173,8 @@ namespace nana return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0); } - std::pair where(int x, int y){ + std::pair where(int x, int y) + { std::pair new_where; if(2 < x && x < static_cast(graph->width()) - 2 && 1 < y && y < static_cast(graph->height()) - 1) @@ -2659,7 +2665,7 @@ namespace nana item_spliter_ = hd.index; // original index return true; } - x -= hd.pixels; + x -= hd.pixels; } } } @@ -2673,7 +2679,7 @@ namespace nana if(is_grab) { ref_xpos_ = pos.x; - if(item_spliter_ != npos) + if(item_spliter_ != npos) // resize header item, not move it orig_item_width_ = essence_->header.column(item_spliter_).pixels; } else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second) @@ -2686,16 +2692,16 @@ namespace nana int grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) - { - draw(rect); - _m_make_float(rect, pos); + { // move header item, not resize it + draw(rect); // first draw the entery header as it was + _m_make_float(rect, pos); // now draw one floating header item //Draw the target strip grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front); return 1; } else - { + { // resize header item, not move it const auto& item = essence_->header.column(item_spliter_); //Resize the item specified by item_spliter_. auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); @@ -3350,18 +3356,18 @@ namespace nana if(essence_->ptr_state == item_state::pressed) { if(essence_->pointer_where.first == parts::header) - { + { // moving a pressed header : grab it (or split-resize?) essence_->ptr_state = item_state::grabbed; nana::point pos = arg.pos; essence_->widget_to_header(pos); drawer_header_->grab(pos, true); API::capture_window(essence_->lister.wd_ptr()->handle(), true); - update = 2; + update = 2; //0 = nothing, 1 = update, 2 = refresh } } if(essence_->ptr_state == item_state::grabbed) - { + { // moving a grabbed header nana::point pos = arg.pos; essence_->widget_to_header(pos); @@ -3713,6 +3719,7 @@ namespace nana //end class trigger //class item_proxy + item_proxy::item_proxy(essence_t * ess) : ess_(ess) {} @@ -3985,6 +3992,7 @@ namespace nana //end class item_proxy //class cat_proxy + //the member cat_ is used for fast accessing to the category cat_proxy::cat_proxy(essence_t * ess, size_type pos) : ess_(ess), @@ -4315,6 +4323,7 @@ namespace nana //Implementation of arg_category //Contributed by leobackes(pr#97) + arg_category::arg_category ( const nana::drawerbase::listbox::cat_proxy& cat ) noexcept : category(cat), block_change_(false) { @@ -4332,6 +4341,7 @@ namespace nana //class listbox + listbox::listbox(window wd, bool visible) { create(wd, rectangle(), visible);