diff --git a/build/vc2013/nana.vcxproj b/build/vc2013/nana.vcxproj
index 7e216758..9cdc46b0 100644
--- a/build/vc2013/nana.vcxproj
+++ b/build/vc2013/nana.vcxproj
@@ -67,24 +67,32 @@
- ../bin/vc2013/
+ ../bin/
..\..\include;$(IncludePath)
..\..\source;$(VC_SourcePath);
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
..\..\include;$(IncludePath)
..\..\source;$(VC_SourcePath);
- ../bin/vc2013/
+ ../bin/
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
- ../bin/vc2013/
+ ../bin/
..\..\include;$(IncludePath)
..\..\source;$(VC_SourcePath);
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
..\..\include;$(IncludePath)
..\..\source;$(VC_SourcePath);
- ../bin/vc2013/
+ ../bin/
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
@@ -102,7 +110,7 @@
true
- $(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib
+ $(TargetPath)
@@ -119,7 +127,7 @@
true
- $(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib
+ $(TargetPath)
@@ -141,7 +149,7 @@
true
- $(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib
+ $(TargetPath)
@@ -162,7 +170,7 @@
true
- $(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib
+ $(TargetPath)
@@ -177,6 +185,7 @@
+
@@ -247,6 +256,9 @@
+
+
+
diff --git a/build/vc2013/nana.vcxproj.filters b/build/vc2013/nana.vcxproj.filters
index f0f82981..ac073316 100644
--- a/build/vc2013/nana.vcxproj.filters
+++ b/build/vc2013/nana.vcxproj.filters
@@ -300,5 +300,18 @@
Source Files\nana\gui\widgets
+
+ Source Files\nana\filesystem
+
+
+
+
+ Header Files
+
+
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/build/vc2015/nana.sln b/build/vc2015/nana.sln
new file mode 100644
index 00000000..eab31ab5
--- /dev/null
+++ b/build/vc2015/nana.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nana", "nana.vcxproj", "{25B21068-491B-4A9F-B99F-6C27BF31BAAD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x64.ActiveCfg = Debug|x64
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x64.Build.0 = Debug|x64
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x86.ActiveCfg = Debug|Win32
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x86.Build.0 = Debug|Win32
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x64.ActiveCfg = Release|x64
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x64.Build.0 = Release|x64
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x86.ActiveCfg = Release|Win32
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/build/vc2015/nana.vcxproj b/build/vc2015/nana.vcxproj
new file mode 100644
index 00000000..94b72562
--- /dev/null
+++ b/build/vc2015/nana.vcxproj
@@ -0,0 +1,266 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {25B21068-491B-4A9F-B99F-6C27BF31BAAD}
+ Win32Proj
+ nana
+ 8.1
+
+
+
+ StaticLibrary
+ true
+ v140
+ Unicode
+
+
+ StaticLibrary
+ true
+ v140
+ Unicode
+
+
+ StaticLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ StaticLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ../bin/
+ ..\..\include;$(IncludePath)
+ ..\..\source;$(VC_SourcePath);
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
+
+
+ ..\..\include;$(IncludePath)
+ ..\..\source;$(VC_SourcePath);
+ ../bin/
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
+
+
+ ../bin/
+ ..\..\include;$(IncludePath)
+ ..\..\source;$(VC_SourcePath);
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
+
+
+ ..\..\include;$(IncludePath)
+ ..\..\source;$(VC_SourcePath);
+ ../bin/
+ $(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)
+ ..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ true
+ false
+
+
+ Windows
+ true
+
+
+ $(TargetPath)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ Windows
+ true
+
+
+ $(TargetPath)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+
+
+ Windows
+ true
+ true
+ true
+
+
+ $(TargetPath)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+ $(TargetPath)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/vc2015/nana.vcxproj.filters b/build/vc2015/nana.vcxproj.filters
new file mode 100644
index 00000000..cb51dab8
--- /dev/null
+++ b/build/vc2015/nana.vcxproj.filters
@@ -0,0 +1,312 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {b0bd11b1-bcbb-4e05-885e-44295bc1a7bb}
+
+
+ {aab16aa3-c8d4-4495-8606-1b21ae739ee5}
+
+
+ {c395f107-7102-415b-a019-54e7cf3575af}
+
+
+ {e2569be2-9e68-477d-8b59-e248595de6c7}
+
+
+ {52ed7f8e-fa48-495e-af1f-4df013205a35}
+
+
+ {87d14798-9015-4162-b9ab-72c741cff063}
+
+
+ {4f8e7d23-9fe1-4409-bb03-2bd0809e606b}
+
+
+ {85c9c1bb-d87b-4481-bf3c-7425f680a12d}
+
+
+ {8058b530-86ec-4d72-890d-345aa30db056}
+
+
+ {87b124cb-408d-460b-a81b-8a788bbae0d9}
+
+
+ {b10db2f1-0542-421a-9e1d-4357e3be5f68}
+
+
+ {59f186c8-f5f8-4499-8e19-f278d4754220}
+
+
+ {5acf1733-47b2-4872-a105-66c7ad15cd39}
+
+
+ {a81fa10e-1274-44e0-92a0-434fa28f89ae}
+
+
+ {e95b4a72-643f-4416-af95-b0bbaf7f0c57}
+
+
+
+
+ Source Files\nana\audio\detail
+
+
+ Source Files\nana\audio\detail
+
+
+ Source Files\nana\audio\detail
+
+
+ Source Files\nana\audio
+
+
+ Source Files\nana\detail\win32
+
+
+ Source Files\nana\filesystem
+
+
+ Source Files\nana\filesystem
+
+
+ Source Files\nana\gui\detail\win32
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\widgets\skeletons
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\paint\detail
+
+
+ Source Files\nana\paint\detail
+
+
+ Source Files\nana\paint
+
+
+ Source Files\nana\paint
+
+
+ Source Files\nana\paint
+
+
+ Source Files\nana\paint
+
+
+ Source Files\nana\paint
+
+
+ Source Files\nana\paint
+
+
+ Source Files\nana\system
+
+
+ Source Files\nana\system
+
+
+ Source Files\nana\system
+
+
+ Source Files\nana\system
+
+
+ Source Files\nana\threads
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana
+
+
+ Source Files\nana\gui\detail
+
+
+ Source Files\nana\gui
+
+
+ Source Files\nana\gui\widgets
+
+
+ Source Files\nana\filesystem
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/include/nana/config.hpp b/include/nana/config.hpp
index 77b9005c..6d2cf836 100644
--- a/include/nana/config.hpp
+++ b/include/nana/config.hpp
@@ -13,6 +13,26 @@
#ifndef NANA_CONFIG_HPP
#define NANA_CONFIG_HPP
+
+#if defined(_MSC_VER)
+ #define _SCL_SECURE_NO_WARNINGS
+ #define _CRT_SECURE_NO_DEPRECATE
+ #pragma warning(disable : 4996)
+
+ #if (_MSC_VER < 1900)
+ // is this a good idea?
+ #define NOT_IMPLEMENTED_KEYWORD_noexcept
+ #endif // _MSC_VER < 1900
+ #if (_MSC_VER == 1900)
+ // google: break any code that tries to use codecvt or codecvt.
+ // google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support.
+ // google: Those definitions are for codecvt::id, codecvt::id and codecvt::id respectively.
+ // However, the codecvt::id and codecvt::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all.
+ // google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources.
+ #define STD_CODECVT_NOT_SUPPORTED
+ #endif // _MSC_VER == 1900
+#endif // _MSVC
+
//Select platform automatically
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
//Windows:
@@ -35,7 +55,7 @@
#define PLATFORM_SPEC_HPP
#define STD_CODECVT_NOT_SUPPORTED
#else
-# static_assert(false, "Only Windows and Unix are support now");
+# static_assert(false, "Only Windows and Unix are supported now");
#endif
#if defined(NANA_MINGW) || defined(NANA_LINUX)
diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp
index 9e735f99..39f21366 100644
--- a/include/nana/detail/win32/platform_spec.hpp
+++ b/include/nana/detail/win32/platform_spec.hpp
@@ -55,6 +55,13 @@ namespace detail
unsigned ignore; //determinate that pos or size would be ignored.
};
+ struct map_thread
+ {
+ rectangle update_area;
+ bool ignore_update_area;
+ bool forced;
+ };
+
enum
{
tray = 0x501,
diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp
new file mode 100644
index 00000000..b00760d2
--- /dev/null
+++ b/include/nana/filesystem/filesystem.hpp
@@ -0,0 +1,469 @@
+/*
+ * A filesystem Implementation
+ * Copyright(C) 2003 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: stdex/filesystem/filesystem.hpp
+ * @description:
+ * file_iterator is a toolkit for applying each file and directory in a
+ * specified path.
+ * Modiffied by Ariel Vina-Rodriguez:
+ * Now mimic std::experimental::filesystem::v1 (boost v3)
+ * and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013
+ */
+
+// http://en.cppreference.com/w/cpp/experimental/fs
+// http://cpprocks.com/introduction-to-tr2-filesystem-library-in-vs2012/ --- TR2 filesystem in VS2012
+// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.140%29.aspx --- C++ 14, the header VS2015
+// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- header VS2013
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 2014-07-04
+// http://cplusplus.github.io/filesystem-ts/working-draft.html --- in html format
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html --- in html format
+// http://article.gmane.org/gmane.comp.lib.boost.devel/256220 --- The filesystem TS unanimously approved by ISO.
+// http://theboostcpplibraries.com/boost.filesystem --- Boost docs
+// http://www.boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htm ---
+// http://www.boost.org/doc/libs/1_34_0/libs/filesystem/doc/index.htm
+// http://www.boost.org/doc/libs/1_58_0/boost/filesystem.hpp
+// https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x --- Table 1.4. g++ C++ Technical Specifications Implementation Status
+
+#ifndef NANA_FILESYSTEM_HPP
+#define NANA_FILESYSTEM_HPP
+#include
+#include
+#include
+
+#include
+
+#ifdef NANA_WINDOWS
+ #include
+ typedef HANDLE find_handle_t;
+#elif defined(NANA_LINUX)
+ #include
+ #include
+ #include
+ typedef DIR* find_handle_t;
+#endif
+
+ // namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
+
+namespace nana { namespace experimental
+{
+namespace filesystem
+{
+ enum class file_type
+ {
+ none = 0, ///< has not been determined or an error occurred while trying to determine
+ not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error
+ regular = 1,
+ directory = 2 ,
+ symlink =3, ///< Symbolic link file
+ block =4, ///< Block special file
+ character= 5 , ///< Character special file
+ fifo = 6 , ///< FIFO or pipe file
+ socket =7,
+ unknown= 8 ///< The file does exist, but is of an operating system dependent type not covered by any of the other
+ };
+
+ enum class perms
+ {
+ none =0, ///< There are no permissions set for the file.
+ unknown = 0xFFFF ///< not known, such as when a file_status object is created without specifying the permissions
+ };
+ //enum class copy_options;
+ //enum class directory_options;
+
+ // class filesystem_error;
+ enum class error { none = 0 }; // deprecate ??
+
+ struct attribute // deprecate ??
+ {
+ uintmax_t size {};
+ bool directory{};
+ tm modified {};
+
+ attribute() {} ;
+ attribute( uintmax_t size, bool is_directory) :size{size}, directory{is_directory} {}
+ };
+
+ struct space_info
+ {
+ uintmax_t capacity;
+ uintmax_t free;
+ uintmax_t available;
+ };
+ using file_time_type = std::chrono::time_point< std::chrono::system_clock>;// trivial-clock> ;
+
+ class file_status
+ {
+ file_type m_ft = file_type::none;
+ perms m_prms = perms::unknown;
+
+ public:
+ explicit file_status(file_type ft = file_type::none, perms prms = perms::unknown)
+ :m_ft{ft}, m_prms{prms}
+ {}
+
+ file_status(const file_status& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default;
+ file_status(file_status&& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default;
+
+ ~file_status(){};
+ file_status& operator=(const file_status&) = default;
+ file_status& operator=(file_status&&fs) // = default;
+ {
+ m_ft=fs.m_ft; m_prms = fs.m_prms;
+ return *this;
+ }
+ // observers
+ file_type type() const { return m_ft;}
+ perms permissions() const { return m_prms;}
+ // modifiers
+ void type (file_type ft) { m_ft=ft ;}
+ void permissions(perms prms) { m_prms = prms; }
+ };
+
+ /// concerned only with lexical and syntactic aspects and does not necessarily exist in
+ /// external storage, and the pathname is not necessarily valid for the current operating system
+ /// or for a particular file system
+ /// A sequence of elements that identify the location of a file within a filesystem.
+ /// The elements are the:
+ /// rootname (opt), root-directory (opt), and an optional sequence of filenames.
+ /// The maximum number of elements in the sequence is operating system dependent.
+ class path
+ {
+ public:
+ path();
+ path(const nana::string&);
+
+ bool empty() const;
+ path root() const;
+ file_type what() const;
+
+ nana::string filename() const;
+#if defined(NANA_WINDOWS)
+ public:
+ nana::string to_string() const { return text_; }
+ operator nana::string() const { return text_; }
+ private:
+ nana::string text_;
+#else
+ public:
+ std::string to_string() const { return text_; }
+ operator std::string() const { return text_; }
+ private:
+ std::string text_;
+#endif
+ };
+
+ struct directory_entry
+ {
+ path m_path;
+
+ attribute attr{};
+ //file_status m_status;
+
+ directory_entry(){}
+ directory_entry(const nana::string& filename_, bool is_directory, uintmax_t size)
+ :m_path{filename_}, attr{size, is_directory}
+ {}
+
+ void assign (const path& p){ m_path=p;}
+ void replace_filename(const path& p){ m_path=p;}
+
+ //file_status status() const;
+
+ operator const path&() const {return m_path;};
+ const path& path() const {return m_path;}
+
+ };
+
+ /// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator
+ //template
+ class directory_iterator :public std::iterator
+ {
+ public:
+ using value_type = directory_entry ;
+ typedef ptrdiff_t difference_type;
+ typedef const directory_entry* pointer;
+ typedef const directory_entry& reference;
+ typedef std::input_iterator_tag iterator_category;
+
+ directory_iterator():end_(true), handle_(nullptr){}
+
+ directory_iterator(const nana::string& file_path) { _m_prepare(file_path); }
+ //directory_iterator(const path& file_path) { _m_prepare(file_path.filename()); }
+
+ const value_type&
+ operator*() const { return value_; }
+
+ const value_type*
+ operator->() const { return &(operator*()); }
+
+ directory_iterator& operator++()
+ { _m_read(); return *this; }
+
+ directory_iterator operator++(int)
+ {
+ directory_iterator tmp = *this;
+ _m_read();
+ return tmp;
+ }
+
+ bool equal(const directory_iterator& x) const
+ {
+ if(end_ && (end_ == x.end_)) return true;
+ return (value_.path().filename() == x.value_.path().filename());
+ }
+
+
+ // enable directory_iterator range-based for statements
+ directory_iterator begin( ) { return *this; }
+ directory_iterator end( ) { return {}; }
+
+ private:
+ template
+ static bool _m_ignore(const Char * p)
+ {
+ while(*p == '.')
+ ++p;
+ return (*p == 0);
+ }
+
+ void _m_prepare(const nana::string& file_path)
+ {
+ #if defined(NANA_WINDOWS)
+ path_ = file_path;
+ auto pat = file_path;
+ DWORD attr = ::GetFileAttributes(pat.data());
+ if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
+ pat += STR("\\*");
+
+ ::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_);
+
+ if(handle == INVALID_HANDLE_VALUE)
+ {
+ end_ = true;
+ return;
+ }
+
+ while(_m_ignore(wfd_.cFileName))
+ {
+ if(::FindNextFile(handle, &wfd_) == 0)
+ {
+ end_ = true;
+ ::FindClose(handle);
+ return;
+ }
+ }
+
+ value_ = value_type(wfd_.cFileName,
+ (FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
+ wfd_.nFileSizeLow);
+
+ #elif defined(NANA_LINUX)
+ path_ = nana::charset(file_path);
+ if(path_.size() && (path_[path_.size() - 1] != '/'))
+ path_ += '/';
+ find_handle_t handle = opendir(path_.c_str());
+ end_ = true;
+ if(handle)
+ {
+ struct dirent * dnt = readdir(handle);
+ if(dnt)
+ {
+ while(_m_ignore(dnt->d_name))
+ {
+ dnt = readdir(handle);
+ if(dnt == 0)
+ {
+ closedir(handle);
+ return;
+ }
+ }
+
+ struct stat fst;
+ if(stat((path_ + dnt->d_name).c_str(), &fst) == 0)
+ {
+ value_ = value_type(nana::charset(dnt->d_name), 0 != S_ISDIR(fst.st_mode), fst.st_size);
+ }
+ else
+ {
+ value_.m_path = nana::charset(dnt->d_name);
+ value_.size = 0;
+ value_.directory = false;
+ }
+ end_ = false;
+ }
+ }
+ #endif
+ if(false == end_)
+ {
+ find_ptr_ = std::shared_ptr(new find_handle_t(handle), inner_handle_deleter());
+ handle_ = handle;
+ }
+ }
+
+ void _m_read()
+ {
+ if(handle_)
+ {
+ #if defined(NANA_WINDOWS)
+ if(::FindNextFile(handle_, &wfd_) != 0)
+ {
+ while(_m_ignore(wfd_.cFileName))
+ {
+ if(::FindNextFile(handle_, &wfd_) == 0)
+ {
+ end_ = true;
+ return;
+ }
+ }
+ value_ = value_type(wfd_.cFileName,
+ (FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
+ wfd_.nFileSizeLow);
+ }
+ else
+ end_ = true;
+ #elif defined(NANA_LINUX)
+ struct dirent * dnt = readdir(handle_);
+ if(dnt)
+ {
+ while(_m_ignore(dnt->d_name))
+ {
+ dnt = readdir(handle_);
+ if(dnt == 0)
+ {
+ end_ = true;
+ return;
+ }
+ }
+ struct stat fst;
+ if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0)
+ value_ = value_type(wfd_.cFileName,
+ (FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
+ wfd_.nFileSizeLow);
+ else
+ value_.m_path = nana::charset(dnt->d_name);
+ }
+ else
+ end_ = true;
+ #endif
+ }
+ }
+ private:
+ struct inner_handle_deleter
+ {
+ void operator()(find_handle_t * handle)
+ {
+ if(handle && *handle)
+ {
+ #if defined(NANA_WINDOWS)
+ ::FindClose(*handle);
+ #elif defined(NANA_LINUX)
+ ::closedir(*handle);
+ #endif
+ }
+ delete handle;
+ }
+ };
+ private:
+ bool end_{false};
+
+#if defined(NANA_WINDOWS)
+ WIN32_FIND_DATA wfd_;
+ nana::string path_;
+#elif defined(NANA_LINUX)
+ std::string path_;
+#endif
+ std::shared_ptr find_ptr_;
+
+ find_handle_t handle_{nullptr};
+ value_type value_;
+ };
+
+
+ //class recursive_directory_iterator;
+ //// enable recursive_directory_iterator range-based for statements
+ //recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
+ //recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
+
+ //template
+ inline bool operator==(const directory_iterator/**/ & x, const directory_iterator/**/ & y)
+ {
+ return x.equal(y);
+ }
+
+ //template
+ inline bool operator!=(const directory_iterator/**/ & x, const directory_iterator/**/ & y)
+ {
+ return !x.equal(y);
+ }
+
+
+ // file_status status(const path& p);
+ bool file_attrib(const nana::string& file, attribute&);
+
+ inline bool is_directory(file_status s) { return s.type() == file_type::directory ;}
+ inline bool is_directory(const path& p) { return directory_iterator{ p }->attr.directory; }//works??
+ inline bool is_directory(const directory_entry& d) { return d.attr.directory; }
+ //bool is_directory(const path& p, error_code& ec) noexcept;
+
+ //bool is_regular_file(file_status s) noexcept;
+
+ inline bool is_empty(const path& p)
+ {
+ directory_iterator d(p) ;
+ return d->attr.directory ? d == directory_iterator()
+ : d->attr.size == 0;
+ }
+ //bool is_empty(const path& p, error_code& ec) noexcept;
+
+ uintmax_t file_size(const nana::string& file); // deprecate?
+ inline uintmax_t file_size(const path& p){return file_size(p.filename());}
+ //uintmax_t file_size(const path& p, error_code& ec) noexcept;
+ //long long filesize(const nana::string& file);
+
+
+ bool create_directories(const path& p);
+ //bool create_directories(const path& p, error_code& ec) noexcept;
+ bool create_directory(const path& p);
+ //bool create_directory(const path& p, error_code& ec) noexcept;
+ bool create_directory(const path& p, const path& attributes);
+ //bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept;
+ bool create_directory(const nana::string& dir, bool & if_exist);
+ inline bool create_directory(const path& p, bool & if_exist)
+ {
+ return create_directory(p.filename(), if_exist);
+ };
+
+
+ bool modified_file_time(const nana::string& file, struct tm&);
+
+
+ nana::string path_user();
+
+
+ path current_path();
+ //path current_path(error_code& ec);
+ void current_path(const path& p);
+ //void current_path(const path& p, error_code& ec) noexcept;
+ //nana::string path_current();
+
+
+ //bool remove(const path& p);
+ //bool remove(const path& p, error_code& ec) noexcept;
+ bool rmfile(const nana::char_t* file);
+
+ //uintmax_t remove_all(const path& p);
+ //uintmax_t remove_all(const path& p, error_code& ec) noexcept;
+ bool rmdir(const nana::char_t* dir, bool fails_if_not_empty);
+ nana::string root(const nana::string& path);
+
+
+}//end namespace filesystem
+} //end namespace experimental
+}//end namespace nana
+
+#endif
diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp
index 1ae2a41d..501a3c8c 100644
--- a/include/nana/gui/detail/bedrock.hpp
+++ b/include/nana/gui/detail/bedrock.hpp
@@ -42,7 +42,7 @@ namespace detail
~bedrock();
void pump_event(window, bool is_modal);
- void map_thread_root_buffer(core_window_t*, bool forced);
+ void map_thread_root_buffer(core_window_t*, bool forced, const rectangle* update_area = nullptr);
static int inc_window(unsigned tid = 0);
thread_context* open_thread_context(unsigned tid = 0);
thread_context* get_thread_context(unsigned tid = 0);
diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp
index f6948a45..121c84b8 100644
--- a/include/nana/gui/detail/drawer.hpp
+++ b/include/nana/gui/detail/drawer.hpp
@@ -110,7 +110,7 @@ namespace nana
void key_char(const arg_keyboard&);
void key_release(const arg_keyboard&);
void shortkey(const arg_keyboard&);
- void map(window, bool forced); //Copy the root buffer to screen
+ void map(window, bool forced, const rectangle* update_area = nullptr); //Copy the root buffer to screen
void refresh();
drawer_trigger* realizer() const;
void attached(widget&, drawer_trigger&);
diff --git a/include/nana/gui/detail/effects_renderer.hpp b/include/nana/gui/detail/effects_renderer.hpp
index 91daf849..b9b1b785 100644
--- a/include/nana/gui/detail/effects_renderer.hpp
+++ b/include/nana/gui/detail/effects_renderer.hpp
@@ -13,9 +13,9 @@ namespace nana{
{
edge_nimbus_renderer() = default;
public:
- typedef CoreWindow core_window_t;
- typedef window_layout window_layer;
- typedef nana::paint::graphics & graph_reference;
+ using core_window_t = CoreWindow;
+ using window_layer = window_layout;
+ using graph_reference = ::nana::paint::graphics&;
static edge_nimbus_renderer& instance()
{
@@ -28,7 +28,34 @@ namespace nana{
return 2;
}
- bool render(core_window_t * wd, bool forced)
+ void erase(core_window_t* wd)
+ {
+ if (effects::edge_nimbus::none == wd->effect.edge_nimbus)
+ return;
+
+ core_window_t * root_wd = wd->root_widget;
+ auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
+
+ for (auto i = nimbus.cbegin(); i != nimbus.cend(); ++i)
+ {
+ if (i->window == wd)
+ {
+ auto pixels = weight();
+ rectangle r{wd->pos_root, wd->dimension};
+ r.x -= static_cast(pixels);
+ r.y -= static_cast(pixels);
+ r.width += static_cast(pixels << 1);
+ r.height += static_cast(pixels << 1);
+
+ root_wd->root_graph->paste(root_wd->root, r, r.x, r.y);
+
+ nimbus.erase(i);
+ break;
+ }
+ }
+ }
+
+ bool render(core_window_t * wd, bool forced, const rectangle* update_area = nullptr)
{
bool rendered = false;
core_window_t * root_wd = wd->root_widget;
@@ -49,8 +76,12 @@ namespace nana{
{
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r))
{
- if(action.window == wd)
+ if (action.window == wd)
+ {
+ if (update_area)
+ ::nana::overlap(*update_area, rectangle(r), r);
rendered = true;
+ }
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
if ((forced && (action.window == wd)) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp
index 37c9c150..ba6aa451 100644
--- a/include/nana/gui/detail/window_manager.hpp
+++ b/include/nana/gui/detail/window_manager.hpp
@@ -150,9 +150,9 @@ namespace detail
core_window_t* root(native_window_type) const;
//Copy the root buffer that wnd specified into DeviceContext
- void map(core_window_t*, bool forced);
+ void map(core_window_t*, bool forced, const rectangle* update_area = nullptr);
- bool update(core_window_t*, bool redraw, bool force);
+ bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr);
void refresh_tree(core_window_t*);
bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen);
diff --git a/include/nana/gui/widgets/progress.hpp b/include/nana/gui/widgets/progress.hpp
index 91e58ab7..f7697d7e 100644
--- a/include/nana/gui/widgets/progress.hpp
+++ b/include/nana/gui/widgets/progress.hpp
@@ -30,6 +30,8 @@ namespace nana
unsigned Max(unsigned);
void unknown(bool);
bool unknown() const;
+ bool stop(bool s = true);
+ bool stoped() const;
private:
void attached(widget_reference, graph_reference) override;
void refresh(graph_reference) override;
@@ -45,6 +47,7 @@ namespace nana
nana::paint::graphics* graph_{nullptr};
unsigned draw_width_{static_cast(-1)};
bool unknown_{false};
+ bool stop_{false};
unsigned max_{100};
unsigned value_{0};
}; //end class drawer
@@ -67,6 +70,8 @@ namespace nana
unsigned amount(unsigned value);
void unknown(bool);
bool unknown() const;
+ bool stop(bool s=true); ///< request stop or cancel and return previus stop status
+ bool stoped() const;
};
}//end namespace nana
#endif
diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp
new file mode 100644
index 00000000..4c6e8d22
--- /dev/null
+++ b/source/filesystem/filesystem.cpp
@@ -0,0 +1,444 @@
+/*
+ * A FileSystem Utility Implementation
+ * Copyright(C) 2003-2013 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/filesystem/filesystem.cpp
+ * @description:
+ * provide some interface for file managment
+ */
+
+#include
+#include
+#if defined(NANA_WINDOWS)
+ #include
+
+ #if defined(NANA_MINGW)
+ #ifndef _WIN32_IE
+ #define _WIN32_IE 0x0500
+ #endif
+ #endif
+
+ #include
+ #include
+#elif defined(NANA_LINUX)
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+#endif
+
+namespace nana {
+ namespace experimental
+ {
+ namespace filesystem
+ {
+ //Because of No wide character version of POSIX
+#if defined(NANA_LINUX)
+ typedef std::string string_t;
+ const char* splstr = "/\\";
+#else
+ typedef nana::string string_t;
+ const nana::char_t* splstr = STR("/\\");
+#endif
+ //class path
+ path::path() {}
+
+ path::path(const nana::string& text)
+#if defined(NANA_WINDOWS)
+ : text_(text)
+ {
+#else
+ :text_(nana::charset(text))
+ {
+#endif
+ auto pos = text_.find_last_of(splstr);
+ for (; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr))
+ text_.erase(pos);
+ }
+
+ bool path::empty() const
+ {
+#if defined(NANA_WINDOWS)
+ return (::GetFileAttributes(text_.c_str()) == INVALID_FILE_ATTRIBUTES);
+#elif defined(NANA_LINUX)
+ struct stat sta;
+ return (::stat(text_.c_str(), &sta) == -1);
+#endif
+ }
+
+ path path::root() const
+ {
+#if defined(NANA_WINDOWS)
+ return path(filesystem::root(text_));
+#elif defined(NANA_LINUX)
+ return path(filesystem::root(nana::charset(text_)));
+#endif
+ }
+
+ file_type path::what() const
+ {
+#if defined(NANA_WINDOWS)
+ unsigned long attr = ::GetFileAttributes(text_.c_str());
+ if (INVALID_FILE_ATTRIBUTES == attr)
+ return file_type::not_found; //??
+
+ if (FILE_ATTRIBUTE_DIRECTORY & attr)
+ return file_type::directory;
+
+ return file_type::regular;
+#elif defined(NANA_LINUX)
+ struct stat sta;
+ if (-1 == ::stat(text_.c_str(), &sta))
+ return file_type::not_found; //??
+
+ if ((S_IFDIR & sta.st_mode) == S_IFDIR)
+ return file_type::directory;
+
+ if ((S_IFREG & sta.st_mode) == S_IFREG)
+ return file_type::regular;
+
+ return file_type::none;
+#endif
+ }
+
+ nana::string path::filename() const
+ {
+ string_t::size_type pos = text_.find_last_of(splstr);
+#if defined(NANA_WINDOWS)
+ return text_.substr(pos + 1);
+#else
+ return nana::charset(text_.substr(pos + 1));
+#endif
+ }
+ //end class path
+
+ namespace detail
+ {
+ //rm_dir_recursive
+ //@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories
+ bool rm_dir_recursive(nana::string&& dir)
+ {
+ std::vector files;
+ nana::string path = dir;
+ path += '\\';
+
+ std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files));
+
+ for (auto & f : files)
+ {
+ if (f.attr.directory)
+ rm_dir_recursive(path + f.path().filename());
+ else
+ rmfile((path + f.path().filename()).c_str());
+ }
+
+ return rmdir(dir.c_str(), true);
+ }
+
+ bool mkdir_helper(const nana::string& dir, bool & if_exist)
+ {
+#if defined(NANA_WINDOWS)
+ if (::CreateDirectory(dir.c_str(), 0))
+ {
+ if_exist = false;
+ return true;
+ }
+
+ if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS);
+#elif defined(NANA_LINUX)
+ if (0 == ::mkdir(static_cast(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
+ {
+ if_exist = false;
+ return true;
+ }
+
+ if_exist = (errno == EEXIST);
+#endif
+ return false;
+ }
+
+#if defined(NANA_WINDOWS)
+ void filetime_to_c_tm(FILETIME& ft, struct tm& t)
+ {
+ FILETIME local_file_time;
+ if (::FileTimeToLocalFileTime(&ft, &local_file_time))
+ {
+ SYSTEMTIME st;
+ ::FileTimeToSystemTime(&local_file_time, &st);
+ t.tm_year = st.wYear - 1900;
+ t.tm_mon = st.wMonth - 1;
+ t.tm_mday = st.wDay;
+ t.tm_wday = st.wDayOfWeek - 1;
+ t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay);
+
+ t.tm_hour = st.wHour;
+ t.tm_min = st.wMinute;
+ t.tm_sec = st.wSecond;
+ }
+ }
+#endif
+ }//end namespace detail
+
+ bool file_attrib(const nana::string& file, attribute& attr)
+ {
+#if defined(NANA_WINDOWS)
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad))
+ {
+ LARGE_INTEGER li;
+ li.u.LowPart = fad.nFileSizeLow;
+ li.u.HighPart = fad.nFileSizeHigh;
+ attr.size = li.QuadPart;
+ attr.directory = (0 != (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
+ detail::filetime_to_c_tm(fad.ftLastWriteTime, attr.modified);
+ return true;
+ }
+#elif defined(NANA_LINUX)
+ struct stat fst;
+ if (0 == ::stat(static_cast(nana::charset(file)).c_str(), &fst))
+ {
+ attr.bytes = fst.st_size;
+ attr.is_directory = (0 != (040000 & fst.st_mode));
+ attr.modified = *(::localtime(&fst.st_ctime));
+ return true;
+ }
+#endif
+ return false;
+ }
+
+ uintmax_t file_size(const nana::string& file)
+ {
+#if defined(NANA_WINDOWS)
+ //Some compilation environment may fail to link to GetFileSizeEx
+ typedef BOOL(__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER);
+ GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx"));
+ if (get_file_size_ex)
+ {
+ HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ if (INVALID_HANDLE_VALUE != handle)
+ {
+ LARGE_INTEGER li;
+ if (!get_file_size_ex(handle, &li))
+ li.QuadPart = 0;
+
+ ::CloseHandle(handle);
+ return li.QuadPart;
+ }
+ }
+ return 0;
+#elif defined(NANA_LINUX)
+ FILE * stream = ::fopen(static_cast(nana::charset(file)).c_str(), "rb");
+ long long size = 0;
+ if (stream)
+ {
+ fseeko64(stream, 0, SEEK_END);
+ size = ftello64(stream);
+ fclose(stream);
+ }
+ return size;
+#endif
+ }
+
+ bool modified_file_time(const nana::string& file, struct tm& t)
+ {
+#if defined(NANA_WINDOWS)
+ WIN32_FILE_ATTRIBUTE_DATA attr;
+ if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr))
+ {
+ FILETIME local_file_time;
+ if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time))
+ {
+ SYSTEMTIME st;
+ ::FileTimeToSystemTime(&local_file_time, &st);
+ t.tm_year = st.wYear - 1900;
+ t.tm_mon = st.wMonth - 1;
+ t.tm_mday = st.wDay;
+ t.tm_wday = st.wDayOfWeek - 1;
+ t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay);
+
+ t.tm_hour = st.wHour;
+ t.tm_min = st.wMinute;
+ t.tm_sec = st.wSecond;
+ return true;
+ }
+ }
+#elif defined(NANA_LINUX)
+ struct stat attr;
+ if (0 == ::stat(static_cast(nana::charset(file)).c_str(), &attr))
+ {
+ t = *(::localtime(&attr.st_ctime));
+ return true;
+ }
+#endif
+ return false;
+ }
+
+ bool create_directory(const nana::string& path, bool & if_exist)
+ {
+ if_exist = false;
+ if (path.size() == 0) return false;
+
+ nana::string root;
+#if defined(NANA_WINDOWS)
+ if (path.size() > 3 && path[1] == STR(':'))
+ root = path.substr(0, 3);
+#elif defined(NANA_LINUX)
+ if (path[0] == STR('/'))
+ root = '/';
+#endif
+ bool mkstat = false;
+ std::size_t beg = root.size();
+
+ while (true)
+ {
+ beg = path.find_first_not_of(STR("/\\"), beg);
+ if (beg == path.npos)
+ break;
+
+ std::size_t pos = path.find_first_of(STR("/\\"), beg + 1);
+ if (pos != path.npos)
+ {
+ root += path.substr(beg, pos - beg);
+
+ mkstat = detail::mkdir_helper(root, if_exist);
+ if (mkstat == false && if_exist == false)
+ return false;
+
+#if defined(NANA_WINDOWS)
+ root += STR('\\');
+#elif defined(NANA_LINUX)
+ root += STR('/');
+#endif
+ }
+ else
+ {
+ if (beg + 1 < path.size())
+ {
+ root += path.substr(beg);
+ mkstat = detail::mkdir_helper(root, if_exist);
+ }
+ break;
+ }
+ beg = pos + 1;
+ }
+ return mkstat;
+ }
+
+ bool rmfile(const nana::char_t* file)
+ {
+#if defined(NANA_WINDOWS)
+ bool ret = false;
+ if (file)
+ {
+ ret = (::DeleteFile(file) == TRUE);
+ if (!ret)
+ ret = (ERROR_FILE_NOT_FOUND == ::GetLastError());
+ }
+
+ return ret;
+#elif defined(NANA_LINUX)
+ if (std::remove(static_cast(nana::charset(file)).c_str()))
+ return (errno == ENOENT);
+ return true;
+#endif
+ }
+
+ bool rmdir(const nana::char_t* dir, bool fails_if_not_empty)
+ {
+ bool ret = false;
+ if (dir)
+ {
+#if defined(NANA_WINDOWS)
+ ret = (::RemoveDirectory(dir) == TRUE);
+ if (!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY))
+ ret = detail::rm_dir_recursive(dir);
+#elif defined(NANA_LINUX)
+ std::string mbstr = nana::charset(dir);
+ if (::rmdir(mbstr.c_str()))
+ {
+ if (!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY))
+ ret = detail::rm_dir_recursive(dir);
+ }
+ else
+ ret = true;
+#endif
+ }
+ return ret;
+ }
+
+ nana::string root(const nana::string& path)
+ {
+ std::size_t index = path.size();
+
+ if (index)
+ {
+ const nana::char_t * str = path.c_str();
+
+ for (--index; index > 0; --index)
+ {
+ nana::char_t c = str[index];
+ if (c != '\\' && c != '/')
+ break;
+ }
+
+ for (--index; index > 0; --index)
+ {
+ nana::char_t c = str[index];
+ if (c == '\\' || c == '/')
+ break;
+ }
+ }
+
+ return index ? path.substr(0, index + 1) : nana::string();
+ }
+
+ nana::string path_user()
+ {
+#if defined(NANA_WINDOWS)
+ nana::char_t path[MAX_PATH];
+ if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path)))
+ return path;
+#elif defined(NANA_LINUX)
+ const char * s = ::getenv("HOME");
+ if (s)
+ return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
+#endif
+ return nana::string();
+ }
+
+ path current_path()
+ {
+#if defined(NANA_WINDOWS)
+ nana::char_t buf[MAX_PATH];
+ DWORD len = ::GetCurrentDirectory(MAX_PATH, buf);
+ if (len)
+ {
+ if (len > MAX_PATH)
+ {
+ nana::char_t * p = new nana::char_t[len + 1];
+ ::GetCurrentDirectory(len + 1, p);
+ nana::string s = p;
+ delete[] p;
+ return s;
+ }
+ return buf;
+ }
+#elif defined(NANA_LINUX)
+ const char * s = ::getenv("PWD");
+ if (s)
+ return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
+#endif
+ return nana::string();
+ }
+ }//end namespace filesystem
+ } //end namespace experimental
+}//end namespace nana
diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp
index 3b9702a3..8c176b4b 100644
--- a/source/gui/detail/drawer.cpp
+++ b/source/gui/detail/drawer.cpp
@@ -240,7 +240,7 @@ namespace nana
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
}
- void drawer::map(window wd, bool forced) //Copy the root buffer to screen
+ void drawer::map(window wd, bool forced, const rectangle* update_area) //Copy the root buffer to screen
{
if(wd)
{
@@ -262,11 +262,15 @@ namespace nana
#endif
}
- if (false == edge_nimbus_renderer_t::instance().render(iwd, forced))
+ if (false == edge_nimbus_renderer_t::instance().render(iwd, forced, update_area))
{
- nana::rectangle vr;
- if(bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
+ rectangle vr;
+ if (bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
+ {
+ if (update_area)
+ ::nana::overlap(*update_area, rectangle(vr), vr);
iwd->root_graph->paste(iwd->root, vr, vr.x, vr.y);
+ }
}
if(owns_caret)
diff --git a/source/gui/detail/linux_X11/bedrock.cpp b/source/gui/detail/linux_X11/bedrock.cpp
index 44ccef61..1a5a1ecc 100644
--- a/source/gui/detail/linux_X11/bedrock.cpp
+++ b/source/gui/detail/linux_X11/bedrock.cpp
@@ -167,7 +167,7 @@ namespace detail
delete impl_;
}
- void bedrock::map_thread_root_buffer(core_window_t*, bool forced)
+ void bedrock::map_thread_root_buffer(core_window_t*, bool forced, const rectangle*)
{
//GUI in X11 is thread-independent, so no implementation.
}
diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp
index 4a9d0f11..1bb25cc9 100644
--- a/source/gui/detail/win32/bedrock.cpp
+++ b/source/gui/detail/win32/bedrock.cpp
@@ -338,9 +338,14 @@ namespace detail
return bedrock_object;
}
- void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced)
+ void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced, const rectangle* update_area)
{
- ::PostMessage(reinterpret_cast(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast(wd), static_cast(forced ? TRUE : FALSE));
+ auto stru = reinterpret_cast(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread)));
+ if (stru)
+ {
+ if (FALSE == ::PostMessage(reinterpret_cast(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast(wd), reinterpret_cast(stru)))
+ ::HeapFree(::GetProcessHeap(), 0, stru);
+ }
}
void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
@@ -591,8 +596,12 @@ namespace detail
}
return true;
case nana::detail::messages::map_thread_root_buffer:
- bedrock.wd_manager.map(reinterpret_cast(wParam), (TRUE == lParam));
- ::UpdateWindow(wd);
+ {
+ auto stru = reinterpret_cast(lParam);
+ bedrock.wd_manager.map(reinterpret_cast(wParam), stru->forced, (stru->ignore_update_area ? nullptr : &stru->update_area));
+ ::UpdateWindow(wd);
+ ::HeapFree(::GetProcessHeap(), 0, stru);
+ }
return true;
case nana::detail::messages::remote_thread_move_window:
{
diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp
index b7719985..7f8da08b 100644
--- a/source/gui/detail/window_manager.cpp
+++ b/source/gui/detail/window_manager.cpp
@@ -372,21 +372,26 @@ namespace detail
//@brief: Delete the window handle
void window_manager::destroy(core_window_t* wd)
{
- core_window_t* parent = nullptr;
+ //Thread-Safe Required!
+ std::lock_guard lock(mutex_);
+ if (impl_->wd_register.available(wd) == false) return;
+
+ rectangle update_area(wd->pos_owner, wd->dimension);
+
+ auto parent = wd->parent;
+ if (parent)
+ utl::erase(parent->children, wd);
+
+ _m_destroy(wd);
+
+ while (parent && (parent->other.category == ::nana::category::flags::lite_widget))
{
- //Thread-Safe Required!
- std::lock_guard lock(mutex_);
- if (impl_->wd_register.available(wd) == false) return;
-
- if (wd->parent)
- {
- parent = wd->parent;
- utl::erase(wd->parent->children, wd);
- }
-
- _m_destroy(wd);
+ update_area.x += parent->pos_owner.x;
+ update_area.y += parent->pos_owner.y;
+ parent = parent->parent;
}
- update(parent, false, false);
+
+ update(parent, false, false, &update_area);
}
//destroy_handle
@@ -672,7 +677,7 @@ namespace detail
}
//Copy the root buffer that wnd specified into DeviceContext
- void window_manager::map(core_window_t* wd, bool forced)
+ void window_manager::map(core_window_t* wd, bool forced, const rectangle* update_area)
{
//Thread-Safe Required!
std::lock_guard lock(mutex_);
@@ -680,12 +685,12 @@ namespace detail
{
//Copy the root buffer that wd specified into DeviceContext
#if defined(NANA_LINUX)
- wd->drawer.map(reinterpret_cast(wd), forced);
+ wd->drawer.map(reinterpret_cast(wd), forced, update_area);
#elif defined(NANA_WINDOWS)
if(nana::system::this_thread_id() == wd->thread_id)
- wd->drawer.map(reinterpret_cast(wd), forced);
+ wd->drawer.map(reinterpret_cast(wd), forced, update_area);
else
- bedrock::instance().map_thread_root_buffer(wd, forced);
+ bedrock::instance().map_thread_root_buffer(wd, forced, update_area);
#endif
}
}
@@ -694,7 +699,7 @@ namespace detail
//@brief: update is used for displaying the screen-off buffer.
// Because of a good efficiency, if it is called in an event procedure and the event procedure window is the
// same as update's, update would not map the screen-off buffer and just set the window for lazy refresh
- bool window_manager::update(core_window_t* wd, bool redraw, bool forced)
+ bool window_manager::update(core_window_t* wd, bool redraw, bool forced, const rectangle* update_area)
{
//Thread-Safe Required!
std::lock_guard lock(mutex_);
@@ -705,7 +710,7 @@ namespace detail
if(forced || (false == wd->belong_to_lazy()))
{
wndlayout_type::paint(wd, redraw, false);
- this->map(wd, forced);
+ this->map(wd, forced, update_area);
}
else
{
@@ -1252,18 +1257,9 @@ namespace detail
if (!established)
{
- if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
- {
- auto & cont = root_attr->effects_edge_nimbus;
- for (auto i = cont.begin(); i != cont.end(); ++i)
- {
- if (i->window == wd)
- {
- cont.erase(i);
- break;
- }
- }
- }
+ //remove the window from edge nimbus effect when it is destroying
+ using edge_nimbus = detail::edge_nimbus_renderer;
+ edge_nimbus::instance().erase(wd);
}
else if (pa_root_attr != root_attr)
{
diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp
index b1d401f5..64208c54 100644
--- a/source/gui/widgets/combox.cpp
+++ b/source/gui/widgets/combox.cpp
@@ -18,6 +18,8 @@
#include
#include
+#include
+
namespace nana
{
arg_combox::arg_combox(combox& wdg): widget(wdg)
diff --git a/source/gui/widgets/progress.cpp b/source/gui/widgets/progress.cpp
index 4459ddb1..e37b5814 100644
--- a/source/gui/widgets/progress.cpp
+++ b/source/gui/widgets/progress.cpp
@@ -89,6 +89,15 @@ namespace nana
{
return unknown_;
}
+ bool trigger::stoped() const
+ {
+ return stop_;
+ }
+ bool trigger::stop(bool s)
+ {
+ std::swap(s,stop_);
+ return s;
+ }
void trigger::refresh(graph_reference)
{
@@ -197,5 +206,13 @@ namespace nana
{
return get_drawer_trigger().unknown();
}
+ bool progress::stop(bool s)
+ {
+ return get_drawer_trigger().stop(s);
+ }
+ bool progress::stoped() const
+ {
+ return get_drawer_trigger().stoped();
+ }
//end class progress
}//end namespace nana