From 73a5352796fac3a17d4d2d5fc6a73884dba15233 Mon Sep 17 00:00:00 2001 From: Robert Hauck Date: Wed, 11 Feb 2015 13:23:01 +0100 Subject: [PATCH 01/23] fix for libpng --- build/cmake/CMakeLists.txt => CMakeLists.txt | 20 +++++++- build/cmake/config.hpp | 50 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) rename build/cmake/CMakeLists.txt => CMakeLists.txt (78%) create mode 100644 build/cmake/config.hpp diff --git a/build/cmake/CMakeLists.txt b/CMakeLists.txt similarity index 78% rename from build/cmake/CMakeLists.txt rename to CMakeLists.txt index e04ee417..8bdb64e4 100644 --- a/build/cmake/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,24 @@ project(nana) cmake_minimum_required(VERSION 2.8) -string(REGEX REPLACE "/[^/]*$" "" CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}) -string(REGEX REPLACE "/[^/]*$" "" CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}) + +option(NANA_ENABLE_PNG "Enable the use of PNG" ON) +if(NANA_ENABLE_PNG) + add_definitions(-DNANA_ENABLE_PNG) +endif() + +option(NANA_LIBPNG "Use the system installed libpng" OFF) +if(NANA_LIBPNG) + find_package(PNG) + if (PNG_FOUND) + include_directories( ${PNG_INCLUDE_DIRS}) + add_definitions(-DNANA_LIBPNG) + endif() +endif() + +#copy our new config.hpp (with removed PNG defines) +execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/build/cmake/config.hpp ${CMAKE_SOURCE_DIR}/include/nana/) + set(NANA_SOURCE_DIR ${CMAKE_SOURCE_DIR}/source) set(NANA_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) diff --git a/build/cmake/config.hpp b/build/cmake/config.hpp new file mode 100644 index 00000000..1436e7dc --- /dev/null +++ b/build/cmake/config.hpp @@ -0,0 +1,50 @@ +/* + * Nana Configuration + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2014 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/config.hpp + */ + +#ifndef NANA_CONFIG_HPP +#define NANA_CONFIG_HPP + +//Select platform automatically +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +//Windows: + #define NANA_WINDOWS 1 + #define PLATFORM_SPEC_HPP + + //Test if it is MINGW + #if defined(__MINGW32__) + #define NANA_MINGW + #define STD_CODECVT_NOT_SUPPORTED + //#define STD_THREAD_NOT_SUPPORTED //Use this flag if MinGW version is older than 4.8.1 + #endif +#elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +//Linux: + #define NANA_LINUX 1 + #define NANA_X11 1 + #define PLATFORM_SPEC_HPP + #define STD_CODECVT_NOT_SUPPORTED +#endif + +//Here defines some flags that tell Nana what features will be supported. + +#define NANA_UNICODE + +#if defined(NANA_UNICODE) && defined(NANA_WINDOWS) + #ifndef _UNICODE + #define _UNICODE + #endif + + #ifndef UNICODE + #define UNICODE + #endif +#endif + +#endif //NANA_CONFIG_HPP From 5afe02cdd457a76666e39d9e3f198f085fc8131b Mon Sep 17 00:00:00 2001 From: Robert Hauck Date: Wed, 11 Feb 2015 13:32:27 +0100 Subject: [PATCH 02/23] wrong defines --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bdb64e4..2ce5400c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,12 +10,13 @@ if(NANA_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) endif() -option(NANA_LIBPNG "Use the system installed libpng" OFF) +option(NANA_LIBPNG "Use the included libpng" ON) if(NANA_LIBPNG) + add_definitions(-DNANA_LIBPNG) +else() find_package(PNG) if (PNG_FOUND) include_directories( ${PNG_INCLUDE_DIRS}) - add_definitions(-DNANA_LIBPNG) endif() endif() From 68caee5c2b57f8a80f7d5159d6bed632d22297bf Mon Sep 17 00:00:00 2001 From: Robert Hauck Date: Wed, 11 Feb 2015 13:48:59 +0100 Subject: [PATCH 03/23] fix for linux build (Fedora 21) --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ce5400c..3834f2a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,10 @@ project(nana) cmake_minimum_required(VERSION 2.8) +#find dependencies +if(UNIX) + find_package(Freetype) +endif() option(NANA_ENABLE_PNG "Enable the use of PNG" ON) if(NANA_ENABLE_PNG) From 0464e8e5d71196f176a43088fc72beb4e8ff3b20 Mon Sep 17 00:00:00 2001 From: Robert Hauck Date: Wed, 11 Feb 2015 13:57:48 +0100 Subject: [PATCH 04/23] missing include --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3834f2a1..ccca4c4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,9 @@ cmake_minimum_required(VERSION 2.8) #find dependencies if(UNIX) find_package(Freetype) + if (FREETYPE_FOUND) + include_directories( ${FREETYPE_INCLUDE_DIRS}) + endif() endif() option(NANA_ENABLE_PNG "Enable the use of PNG" ON) From 0fa61b0c955ee218340340549484ffcb8510ecc0 Mon Sep 17 00:00:00 2001 From: Robert Hauck Date: Wed, 11 Feb 2015 14:02:55 +0100 Subject: [PATCH 05/23] make libpng only selectable when using png --- CMakeLists.txt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ccca4c4c..c85b7303 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,18 +15,20 @@ endif() option(NANA_ENABLE_PNG "Enable the use of PNG" ON) if(NANA_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) -endif() -option(NANA_LIBPNG "Use the included libpng" ON) -if(NANA_LIBPNG) - add_definitions(-DNANA_LIBPNG) -else() - find_package(PNG) - if (PNG_FOUND) - include_directories( ${PNG_INCLUDE_DIRS}) + option(NANA_LIBPNG "Use the included libpng" ON) + if(NANA_LIBPNG) + add_definitions(-DNANA_LIBPNG) + else() + find_package(PNG) + if (PNG_FOUND) + include_directories( ${PNG_INCLUDE_DIRS}) + endif() endif() endif() + + #copy our new config.hpp (with removed PNG defines) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/build/cmake/config.hpp ${CMAKE_SOURCE_DIR}/include/nana/) From c417f15b03ee1aa37a97432069d84d1f25cc1b23 Mon Sep 17 00:00:00 2001 From: cnjinhao Date: Thu, 12 Feb 2015 02:45:16 +0800 Subject: [PATCH 06/23] add contributor information --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c85b7303..1bef6aa8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ # CMake configuration for Nana -# Author: ierofant(https://github.com/ierofant) +# Author: Andrew Kornilov(https://github.com/ierofant) +# Contributor: +# Robert Hauck - Enable support for PNG/Freetype project(nana) cmake_minimum_required(VERSION 2.8) From 4385ac623d65e8d346d0da28e230bbe86e141249 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 16 Feb 2015 06:59:56 +0800 Subject: [PATCH 07/23] add fps modifier for animation --- include/nana/gui/animation.hpp | 18 +-- include/nana/gui/widgets/progress.hpp | 1 - source/gui/animation.cpp | 159 +++++++++++++++----------- source/gui/widgets/progress.cpp | 2 +- 4 files changed, 103 insertions(+), 77 deletions(-) diff --git a/include/nana/gui/animation.hpp b/include/nana/gui/animation.hpp index a1f15a63..42a338d9 100644 --- a/include/nana/gui/animation.hpp +++ b/include/nana/gui/animation.hpp @@ -1,6 +1,7 @@ /* * An Animation Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -27,15 +28,13 @@ namespace nana friend class animation; public: /// function which builds frames. - typedef std::function framebuilder; + using framebuilder = std::function; struct impl; public: frameset(); - void push_back(const paint::image&); ///< Inserts frames at the end. - void push_back(paint::image&&); - void push_back(framebuilder& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates. - void push_back(framebuilder&& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates. + void push_back(paint::image); ///< Inserts frames at the end. + void push_back(framebuilder fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates. private: std::shared_ptr impl_; }; @@ -51,9 +50,9 @@ namespace nana struct impl; class performance_manager; public: - animation(); + animation(std::size_t fps = 23); - void push_back(const frameset& frms); + void push_back(frameset frms); /* void branch(const std::string& name, const frameset& frms) { @@ -75,6 +74,9 @@ namespace nana void pause(); void output(window wd, const nana::point& pos); + + void fps(std::size_t n); + std::size_t fps() const; private: impl * impl_; }; diff --git a/include/nana/gui/widgets/progress.hpp b/include/nana/gui/widgets/progress.hpp index 352069df..5464571b 100644 --- a/include/nana/gui/widgets/progress.hpp +++ b/include/nana/gui/widgets/progress.hpp @@ -44,7 +44,6 @@ namespace nana widget * widget_{nullptr}; nana::paint::graphics* graph_{nullptr}; unsigned draw_width_{static_cast(-1)}; - //bool has_value_{true}; //deprecated bool unknown_{false}; unsigned max_{100}; unsigned value_{0}; diff --git a/source/gui/animation.cpp b/source/gui/animation.cpp index a8165470..0f4c1405 100644 --- a/source/gui/animation.cpp +++ b/source/gui/animation.cpp @@ -1,6 +1,7 @@ /* * An Animation Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -48,11 +49,7 @@ namespace nana std::size_t length; std::function frbuilder; - framebuilder(const std::function& f, std::size_t l) - : length(l), frbuilder(f) - {} - - framebuilder(std::size_t l, std::function&& f) + framebuilder(std::function f, std::size_t l) : length(l), frbuilder(std::move(f)) {} }; @@ -65,28 +62,16 @@ namespace nana framebuilder }; - frame(const paint::image& r) + frame(paint::image img) : type(kind::oneshot) { - u.oneshot = new paint::image(r); + u.oneshot = new paint::image(std::move(img)); } - frame(paint::image&& r) - : type(kind::oneshot) - { - u.oneshot = new paint::image(std::move(r)); - } - - frame(const std::function& frbuilder, std::size_t length) + frame(std::function frbuilder, std::size_t length) : type(kind::framebuilder) { - u.frbuilder = new framebuilder(frbuilder, length); - } - - frame(std::function&& frbuilder, std::size_t length) - : type(kind::framebuilder) - { - u.frbuilder = new framebuilder(frbuilder, length); + u.frbuilder = new framebuilder(std::move(frbuilder), length); } frame(const frame& r) @@ -323,29 +308,15 @@ namespace nana : impl_(new impl) {} - void frameset::push_back(const paint::image& m) + void frameset::push_back(paint::image img) { bool located = impl_->this_frame != impl_->frames.end(); - impl_->frames.emplace_back(m); + impl_->frames.emplace_back(std::move(img)); if(false == located) impl_->this_frame = impl_->frames.begin(); } - void frameset::push_back(paint::image&& m) - { - impl_->frames.emplace_back(std::move(m)); - if(1 == impl_->frames.size()) - impl_->this_frame = impl_->frames.begin(); - } - - void frameset::push_back(framebuilder&fb, std::size_t length) - { - impl_->frames.emplace_back(fb, length); - if(1 == impl_->frames.size()) - impl_->this_frame = impl_->frames.begin(); - } - - void frameset::push_back(framebuilder&& fb, std::size_t length) + void frameset::push_back(framebuilder fb, std::size_t length) { impl_->frames.emplace_back(std::move(fb), length); if(1 == impl_->frames.size()) @@ -365,10 +336,14 @@ namespace nana std::size_t active; //The number of active animations std::shared_ptr thread; + + std::size_t fps; + double interval; //milliseconds between 2 frames. double performance_parameter; }; - thread_variable * insert(impl* p); + void insert(impl* p); + void set_fps(impl*, std::size_t new_fps); void close(impl* p); bool empty() const; private: @@ -380,8 +355,9 @@ namespace nana struct animation::impl { - bool looped; - volatile bool paused; + bool looped{false}; + volatile bool paused{true}; + std::size_t fps; std::list framesets; std::map branches; @@ -399,17 +375,21 @@ namespace nana static performance_manager * perf_manager; - impl() - : looped(false), paused(true) + impl(std::size_t fps) + : fps(fps) { state.this_frameset = framesets.begin(); + if (!perf_manager) { nana::internal_scope_guard lock; - if(nullptr == perf_manager) - perf_manager = new performance_manager; + if (!perf_manager) + { + auto pm = new performance_manager; + perf_manager = pm; + } } - thr_variable = perf_manager->insert(this); + perf_manager->insert(this); } ~impl() @@ -457,46 +437,78 @@ namespace nana };//end struct animation::impl //class animation::performance_manager - auto animation::performance_manager::insert(impl* p) -> thread_variable * + void animation::performance_manager::insert(impl* p) { std::lock_guard lock(mutex_); for(auto thr : threads_) { std::lock_guardmutex)> privlock(thr->mutex); - if(thr->performance_parameter / (thr->animations.size() + 1) <= 43.3) + if ((thr->fps == p->fps) && (thr->performance_parameter / (thr->animations.size() + 1) <= 43.3)) { + p->thr_variable = thr; thr->animations.push_back(p); - return thr; + return; } } auto thr = new thread_variable; thr->animations.push_back(p); thr->performance_parameter = 0.0; + thr->fps = p->fps; + thr->interval = 1000.0 / double(p->fps); thr->thread = std::make_shared([this, thr]() { _m_perf_thread(thr); }); threads_.push_back(thr); - return thr; + p->thr_variable = thr; + } + + void animation::performance_manager::set_fps(impl* p, std::size_t new_fps) + { + if (p->fps == new_fps) + return; + + std::lock_guard lock(mutex_); + auto i = std::find(threads_.begin(), threads_.end(), p->thr_variable); + if (i == threads_.end()) + return; + + p->fps = new_fps; + auto thr = *i; + + //Simply modify the fps parameter if the thread just has one animation. + if (thr->animations.size() == 1) + { + thr->fps = new_fps; + thr->interval = 1000.0 / double(new_fps); + return; + } + + std::lock_guardmutex)> privlock(thr->mutex); + auto u = std::find(thr->animations.begin(), thr->animations.end(), p); + if (u != thr->animations.end()) + thr->animations.erase(u); + + p->thr_variable = nullptr; + insert(p); } void animation::performance_manager::close(impl* p) { std::lock_guard lock(mutex_); - for(auto thr : threads_) - { - std::lock_guardmutex)> privlock(thr->mutex); + auto i = std::find(threads_.begin(), threads_.end(), p->thr_variable); + if (i == threads_.end()) + return; - auto i = std::find(thr->animations.begin(), thr->animations.end(), p); - if(i != thr->animations.end()) - { - thr->animations.erase(i); - return; - } - } + auto thr = *i; + std::lock_guardmutex)> privlock(thr->mutex); + + auto u = std::find(thr->animations.begin(), thr->animations.end(), p); + if(u != thr->animations.end()) + thr->animations.erase(u); } bool animation::performance_manager::empty() const @@ -542,8 +554,8 @@ namespace nana if(thrvar->active) { thrvar->performance_parameter = tmpiece.calc(); - if(thrvar->performance_parameter < 43.4) - nana::system::sleep(static_cast(43.4 - thrvar->performance_parameter)); + if(thrvar->performance_parameter < thrvar->interval) + nana::system::sleep(static_cast(thrvar->interval - thrvar->performance_parameter)); } else { @@ -557,15 +569,15 @@ namespace nana } //end class animation::performance_manager - animation::animation() - : impl_(new impl) + animation::animation(std::size_t fps) + : impl_(new impl(fps)) { } - void animation::push_back(const frameset& frms) + void animation::push_back(frameset frms) { - impl_->framesets.emplace_back(frms); + impl_->framesets.emplace_back(std::move(frms)); if(1 == impl_->framesets.size()) impl_->state.this_frameset = impl_->framesets.begin(); } @@ -634,6 +646,19 @@ namespace nana } output.points.push_back(pos); } + + void animation::fps(std::size_t n) + { + if (n == impl_->fps) + return; + + impl::perf_manager->set_fps(impl_, n); + } + + std::size_t animation::fps() const + { + return impl_->fps; + } //end class animation diff --git a/source/gui/widgets/progress.cpp b/source/gui/widgets/progress.cpp index a0219504..4459ddb1 100644 --- a/source/gui/widgets/progress.cpp +++ b/source/gui/widgets/progress.cpp @@ -108,7 +108,7 @@ namespace nana { rectangle r = graph.size(); graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true); - ::nana::color lt{ 0x80, 0x80, 0x80 }, rb{colors::white}; + ::nana::color lt{ colors::gray }, rb{colors::white}; graph.frame_rectangle(r, lt, lt, rb, rb); } From 0ffa3e54ca897d7a2400037abb67c70db29320a0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 17 Feb 2015 04:03:55 +0800 Subject: [PATCH 08/23] some improvements --- include/nana/deploy.hpp | 12 +++ include/nana/gui/layout_utility.hpp | 1 + source/deploy.cpp | 99 +++++++++++++++++++++ source/gui/animation.cpp | 18 ++-- source/gui/detail/win32/bedrock.cpp | 2 - source/gui/msgbox.cpp | 43 ++------- source/gui/widgets/date_chooser.cpp | 11 +-- source/gui/widgets/listbox.cpp | 130 +++++++++------------------- source/gui/widgets/spinbox.cpp | 4 +- source/gui/widgets/textbox.cpp | 16 +--- 10 files changed, 175 insertions(+), 161 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index d417d06d..e59e0d85 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -50,6 +50,18 @@ namespace nana //Workaround for no implemenation of std::stod in MinGW. double stod(const std::string&, std::size_t * pos = nullptr); double stod(const std::wstring&, std::size_t* pos = nullptr); + + //Workaround for no implemenation of std::to_wstring in MinGW. + std::wstring to_wstring(long double); + std::wstring to_wstring(double); + std::wstring to_wstring(unsigned); + std::wstring to_wstring(int); + std::wstring to_wstring(long); + std::wstring to_wstring(unsigned long); + std::wstring to_wstring(long long); + std::wstring to_wstring(unsigned long long); + std::wstring to_wstring(float); + } #if defined(NANA_WINDOWS) diff --git a/include/nana/gui/layout_utility.hpp b/include/nana/gui/layout_utility.hpp index a963bbca..fae4f4c9 100644 --- a/include/nana/gui/layout_utility.hpp +++ b/include/nana/gui/layout_utility.hpp @@ -30,6 +30,7 @@ namespace nana /// Zoom the input_s to fit for ref_s void fit_zoom(const size& input_s, const size& ref_s, size& result_s); + size fit_zoom(const size& input_s, size ref_s); //zoom //@brief: Calculate the scaled rectangle by refer dst rectangle, that scale factor is same as that between scaled and refer. diff --git a/source/deploy.cpp b/source/deploy.cpp index 6017edfd..e9e0d5d2 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -133,6 +133,105 @@ namespace nana #endif } + std::wstring to_wstring(double v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(long double v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(unsigned v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(int v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(long v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(unsigned long v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(long long v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(unsigned long long v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + + std::wstring to_wstring(float v) + { +#ifdef NANA_MINGW + std::wstringstream ss; + ss << v; + return ss.str(); +#else + return std::to_wstring(v); +#endif + } + bool is_incomplete(const nana::string& str, unsigned pos) { #ifndef NANA_UNICODE diff --git a/source/gui/animation.cpp b/source/gui/animation.cpp index 0f4c1405..9ed5a7ea 100644 --- a/source/gui/animation.cpp +++ b/source/gui/animation.cpp @@ -36,12 +36,8 @@ namespace nana struct output_t { - drawing::diehard_t diehard; + drawing::diehard_t diehard{ nullptr }; std::vector points; - - output_t() - : diehard(nullptr) - {} }; struct framebuilder @@ -443,12 +439,14 @@ namespace nana for(auto thr : threads_) { std::lock_guardmutex)> privlock(thr->mutex); - - if ((thr->fps == p->fps) && (thr->performance_parameter / (thr->animations.size() + 1) <= 43.3)) + if (thr->fps == p->fps) { - p->thr_variable = thr; - thr->animations.push_back(p); - return; + if (thr->animations.empty() || (thr->performance_parameter * (1.0 + 1.0 / thr->animations.size()) <= 43.3)) + { + p->thr_variable = thr; + thr->animations.push_back(p); + return; + } } } diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 36c50e69..555fcbaf 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -1008,8 +1008,6 @@ namespace detail arg.evt_code = event_code::mouse_up; emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - //auto evt_ptr = msgwnd->together.events_ptr; //deprecated - if (fire_click) { arg.evt_code = event_code::click; diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index a13f3c82..09c9b776 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -611,20 +611,13 @@ namespace nana //get the longest value int longest = (std::abs((impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(impl->last < 0 ? impl->last * 10 : impl->last) ? impl->last : impl->begin); - std::wstringstream ss; - ss << longest; paint::graphics graph{ ::nana::size{ 10, 10 } }; - auto value_px = graph.text_extent_size(ss.str()).width + 34; + auto value_px = graph.text_extent_size(::nana::to_wstring(longest)).width + 34; impl->spinbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, value_px, 0 }); impl->spinbox.range(impl->begin, impl->last, impl->step); - //impl->spinbox.set_accept_integer(); //deprecated - //Workaround for no implementation of std::to_wstring by MinGW. - ss.str(L""); - ss.clear(); - ss << impl->value; - impl->spinbox.value(ss.str()); + impl->spinbox.value(::nana::to_wstring(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -698,20 +691,13 @@ namespace nana //get the longest value auto longest = (std::abs((impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(impl->last < 0 ? impl->last * 10 : impl->last) ? impl->last : impl->begin); - std::wstringstream ss; - ss << longest; paint::graphics graph{ ::nana::size{ 10, 10 } }; - auto value_px = graph.text_extent_size(ss.str()).width + 34; + auto value_px = graph.text_extent_size(::nana::to_wstring(longest)).width + 34; impl->spinbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, value_px, 0 }); impl->spinbox.range(impl->begin, impl->last, impl->step); - //impl->spinbox.set_accept_real(); //deprecated - //Workaround for no implementation of std::to_wstring by MinGW. - ss.str(L""); - ss.clear(); - ss << impl->value; - impl->spinbox.value(ss.str()); + impl->spinbox.value(::nana::to_wstring(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -859,9 +845,7 @@ namespace nana ::nana::string inputbox::date::value() const { - std::wstringstream ss; - ss << impl_->month << L'-' << impl_->day << L", " << impl_->year; - return ss.str(); + return nana::to_wstring(impl_->month) + L'-' + nana::to_wstring(impl_->day) + L", " + nana::to_wstring(impl_->year); } int inputbox::date::year() const @@ -907,22 +891,15 @@ namespace nana left += 104; impl->wdg_day.create(impl->dock, rectangle{ left, 0, 38, 0 }); impl->wdg_day.range(1, ::nana::date::month_days(today.year, today.month), 1); - //impl->wdg_day.set_accept_integer(); //deprecated left += 48; impl->wdg_year.create(impl->dock, rectangle{left, 0, 50, 0}); impl->wdg_year.range(1601, 9999, 1); - //impl->wdg_year.set_accept_integer(); //deprecated impl->wdg_month.option(today.month - 1); - std::wstringstream ss; - ss << today.day; - impl->wdg_day.value(ss.str()); - ss.str(L""); - ss.clear(); - ss << today.year; - impl->wdg_year.value(ss.str()); + impl->wdg_day.value(::nana::to_wstring(today.day)); + impl->wdg_year.value(::nana::to_wstring(today.year)); impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg) { @@ -962,10 +939,8 @@ namespace nana if (day > days) day = days; - - std::wstringstream ss; - ss << day; - impl->wdg_day.value(ss.str()); + + impl->wdg_day.value(::nana::to_wstring(day)); }; impl->wdg_year.events().text_changed.connect_unignorable(make_days); diff --git a/source/gui/widgets/date_chooser.cpp b/source/gui/widgets/date_chooser.cpp index bb0cede5..16b493c3 100644 --- a/source/gui/widgets/date_chooser.cpp +++ b/source/gui/widgets/date_chooser.cpp @@ -127,15 +127,13 @@ namespace nana if(graph.width() > 32 + border_size * 2) { - std::stringstream ss; - ss< - std::wstring to_wstring(Int n) - { - std::wstringstream ss; - ss << n; - return ss.str(); - } - //definition of iresolver/oresolver oresolver& oresolver::operator<<(bool n) { @@ -96,77 +87,66 @@ namespace nana } oresolver& oresolver::operator<<(short n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned short n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(int n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned int n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(long n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned long n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(long long n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned long long n) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(n)); + cells_.emplace_back(::nana::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(float f) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(f)); + cells_.emplace_back(::nana::to_wstring(f)); return *this; } oresolver& oresolver::operator<<(double f) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(f)); + cells_.emplace_back(::nana::to_wstring(f)); return *this; } oresolver& oresolver::operator<<(long double f) { - //A workaround, MinGW does not yet provide std::to_wstring - cells_.emplace_back(to_wstring(f)); + cells_.emplace_back(::nana::to_wstring(f)); return *this; } @@ -2373,7 +2353,7 @@ namespace nana if(x < essence_->scroll.offset_x) x = essence_->scroll.offset_x; else if(x > essence_->scroll.offset_x + static_cast(rect.width)) - x = essence_->scroll.offset_x + rect.width; + x = essence_->scroll.offset_x + static_cast(rect.width); size_type i = essence_->header.item_by_x(x); if(i == npos) @@ -2537,6 +2517,8 @@ namespace nana auto idx = essence_->scroll.offset_y; auto state = item_state::normal; + + const bool sort_enabled = (essence_->lister.sort_index() != npos); //Here draws a root categ or a first drawing is not a categ. if(idx.cat == 0 || !idx.is_category()) { @@ -2546,30 +2528,16 @@ namespace nana idx.item = 0; } - //Test whether the sort is enabled. - if(essence_->lister.sort_index() != npos) + std::size_t size = i_categ->items.size(); + for(std::size_t offs = essence_->scroll.offset_y.item; offs < size; ++offs, ++idx.item) { - std::size_t size = i_categ->items.size(); - for(std::size_t offs = essence_->scroll.offset_y.item; offs < size; ++offs, ++idx.item) - { - if(n-- == 0) break; - state = (tracker == idx ? item_state::highlighted : item_state::normal); + if(n-- == 0) break; + state = (tracker == idx ? item_state::highlighted : item_state::normal); - _m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, offs))], x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state); - y += essence_->item_size; - } - } - else - { - for(auto i = i_categ->items.cbegin() + essence_->scroll.offset_y.item; i != i_categ->items.cend(); ++i, ++idx.item) - { - if(n-- == 0) break; - state = (tracker == idx ? item_state::highlighted : item_state::normal); - - _m_draw_item(*i, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); - y += essence_->item_size; - } + _m_draw_item(i_categ->items[sort_enabled ? lister.absolute(index_pair(idx.cat, offs)) : offs], x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state); + y += essence_->item_size; } + ++i_categ; ++idx.cat; } @@ -2584,35 +2552,18 @@ namespace nana _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); y += essence_->item_size; - if(false == i_categ->expand) continue; + if(false == i_categ->expand) + continue; - //Test whether the sort is enabled. - if(essence_->lister.sort_index() != npos) + auto size = i_categ->items.size(); + for(decltype(size) pos = 0; pos < size; ++pos) { - auto size = i_categ->items.size(); - for(decltype(size) pos = 0; pos < size; ++pos) - { - if(n-- == 0) break; - state = (idx == tracker ? item_state::highlighted : item_state::normal); + if(n-- == 0) break; + state = (idx == tracker ? item_state::highlighted : item_state::normal); - _m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, pos))], x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); - y += essence_->item_size; - ++idx.item; - } - } - else - { - for(auto & m : i_categ->items) - { - if(n-- == 0) break; - - state = (idx == tracker ? item_state::highlighted : item_state::normal); - - _m_draw_item(m, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); - y += essence_->item_size; - - ++idx.item; - } + _m_draw_item(i_categ->items[sort_enabled ? lister.absolute(index_pair(idx.cat, pos)) : pos], x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); + y += essence_->item_size; + ++idx.item; } } @@ -2627,25 +2578,24 @@ namespace nana { bool sel = categ.selected(); if(sel && (categ.expand == false)) - bgcolor = nana::color(0xD5, 0xEF, 0xFC); + bgcolor = static_cast(0xD5EFFC); if (state == item_state::highlighted) - bgcolor = bgcolor.blend(::nana::color(0x99, 0xde, 0xfd), 0.8); + bgcolor = bgcolor.blend(static_cast(0x99defd), 0.8); auto graph = essence_->graph; - graph->set_color(bgcolor); - graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true); + graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true, bgcolor); + + color txt_color{ static_cast(0x3399) }; facade arrow("double"); arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south); ::nana::rectangle arrow_r{ x + 5, y + static_cast(essence_->item_size - 16) / 2, 16, 16 }; - arrow.draw(*graph, {}, static_cast(0x3399), arrow_r, element_state::normal); + arrow.draw(*graph, {}, txt_color, arrow_r, element_state::normal); - graph->string({ x + 20, y + txtoff }, categ.text, {0, 0x33, 0x99}); + graph->string({ x + 20, y + txtoff }, categ.text, txt_color); - std::stringstream ss; - ss<<'('<(categ.items.size())<<')'; - nana::string str = nana::charset(ss.str()); + ::nana::string str = L'(' + ::nana::to_wstring(categ.items.size()) + L')'; unsigned str_w = graph->text_extent_size(str).width; @@ -2655,7 +2605,7 @@ namespace nana if (x + 35 + text_s.width + str_w < x + width) { ::nana::point pos{ x + 30 + static_cast(text_s.width + str_w), y + static_cast(essence_->item_size) / 2 }; - graph->line(pos, { x + static_cast(width)-5, pos.y }, { 0x0, 0x33, 0x99 }); + graph->line(pos, { x + static_cast(width)-5, pos.y }, txt_color); } //Draw selecting inner rectangle if(sel && categ.expand == false) @@ -2845,7 +2795,7 @@ namespace nana auto & graph = *essence_->graph; auto size = graph.size(); //Draw Border - graph.rectangle(false, {0x9c, 0xb6, 0xc5}); + graph.rectangle(false, static_cast(0x9cb6c5)); graph.line({ 1, 1 }, {1, static_cast(size.height) - 2}, colors::white); graph.line({ static_cast(size.width) - 2, 1 }, { static_cast(size.width) - 2, static_cast(size.height) - 2 }); diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 94a11715..a662d294 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -73,9 +73,7 @@ namespace nana std::wstring value() const override { - std::wstringstream ss; - ss << value_; - return ss.str(); + return ::nana::to_wstring(value_); } bool value(const std::wstring& value_str, bool & diff) override diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index fc4a7d1b..ffbacb05 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -456,25 +456,13 @@ namespace drawerbase { textbox& textbox::from(int n) { -#ifdef NANA_UNICODE - std::wstringstream ss; -#else - std::stringstream ss; -#endif - ss << n; - _m_caption(ss.str()); + _m_caption(::nana::to_wstring(n)); return *this; } textbox& textbox::from(double d) { -#ifdef NANA_UNICODE - std::wstringstream ss; -#else - std::stringstream ss; -#endif - ss << d; - _m_caption(ss.str()); + _m_caption(::nana::to_wstring(d)); return *this; } From b755c24804544e1c3f267b476cbc55b6c76b1d30 Mon Sep 17 00:00:00 2001 From: Robert Hauck Date: Tue, 17 Feb 2015 10:47:49 +0100 Subject: [PATCH 09/23] - Disable annoying VS warnings - Option to enable multiprocessor build on VS - Move all options to CMake: - Unicode - Platform specs --- CMakeLists.txt | 53 ++++++++++++++++++++++++++++++++++++++++-- build/cmake/config.hpp | 34 +-------------------------- 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c85b7303..5eaf24ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,56 @@ project(nana) cmake_minimum_required(VERSION 2.8) -#find dependencies + +#Select platform automatically +if(WIN32) + add_definitions(-DNANA_WINDOWS) + add_definitions(-DPLATFORM_SPEC_HPP=) + + #Test if it is MINGW + if(MINGW) + add_definitions(-DNANA_MINGW) + add_definitions(-DSTD_CODECVT_NOT_SUPPORTED) + option(NANA_THREAD_NOT_SUPPORTED "Use this flag if MinGW version is older than 4.8.1" ON) + if(NANA_THREAD_NOT_SUPPORTED) + add_definitions(-DSTD_THREAD_NOT_SUPPORTED) + endif() + endif() +endif() +if(UNIX) + add_definitions(-DNANA_LINUX) + add_definitions(-DNANA_X11) + add_definitions(-DPLATFORM_SPEC_HPP=) + add_definitions(-DSTD_CODECVT_NOT_SUPPORTED) +endif() + + +#Global MSVC definitions +if(WIN32) + if(MSVC) + option(WIN32_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON) + if(WIN32_USE_MP) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + endif() + + # More MSVC specific compilation flags + add_definitions(-D_SCL_SECURE_NO_WARNINGS) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + endif(MSVC) +endif(WIN32) + + +#Unicode +option(NANA_UNICODE "Use Unicode Character Set" ON) +if(NANA_UNICODE) + add_definitions(-DNANA_UNICODE) + if(WIN32) + add_definitions(-DUNICODE -D_UNICODE) + endif() +endif() + + +#Find PNG if(UNIX) find_package(Freetype) if (FREETYPE_FOUND) @@ -29,7 +78,7 @@ endif() -#copy our new config.hpp (with removed PNG defines) +#Copy our new config.hpp (with removed defines) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/build/cmake/config.hpp ${CMAKE_SOURCE_DIR}/include/nana/) diff --git a/build/cmake/config.hpp b/build/cmake/config.hpp index 1436e7dc..08527a55 100644 --- a/build/cmake/config.hpp +++ b/build/cmake/config.hpp @@ -13,38 +13,6 @@ #ifndef NANA_CONFIG_HPP #define NANA_CONFIG_HPP -//Select platform automatically -#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -//Windows: - #define NANA_WINDOWS 1 - #define PLATFORM_SPEC_HPP - - //Test if it is MINGW - #if defined(__MINGW32__) - #define NANA_MINGW - #define STD_CODECVT_NOT_SUPPORTED - //#define STD_THREAD_NOT_SUPPORTED //Use this flag if MinGW version is older than 4.8.1 - #endif -#elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) -//Linux: - #define NANA_LINUX 1 - #define NANA_X11 1 - #define PLATFORM_SPEC_HPP - #define STD_CODECVT_NOT_SUPPORTED -#endif - -//Here defines some flags that tell Nana what features will be supported. - -#define NANA_UNICODE - -#if defined(NANA_UNICODE) && defined(NANA_WINDOWS) - #ifndef _UNICODE - #define _UNICODE - #endif - - #ifndef UNICODE - #define UNICODE - #endif -#endif +//All defines have been moved to the CMakelists.txt in the root directory. #endif //NANA_CONFIG_HPP From ef705bbb5ab77d86f4e8d05273e73ff93b664b71 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 17 Feb 2015 23:14:39 +0800 Subject: [PATCH 10/23] add tip string and mask character for inputbox::text --- include/nana/gui/msgbox.hpp | 5 +++++ source/gui/msgbox.cpp | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index fe6ae1ff..f153dcf2 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -149,6 +149,11 @@ namespace nana ~text(); + void tip_string(std::wstring tip); + void tip_string(std::string tip_utf8); + + void mask_character(wchar_t ch); + ::nana::string value() const; private: //Implementation of abstract_content diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 09c9b776..acf2ecfe 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -723,7 +723,9 @@ namespace nana //class text struct inputbox::text::implement { - ::nana::string value; + ::nana::string value; + ::nana::string tip; + wchar_t mask_character{0}; std::vector< ::nana::string> options; ::nana::string label_text; @@ -749,6 +751,21 @@ namespace nana //Instance for impl_ because implmenet is incomplete type at the point of declaration inputbox::text::~text(){} + void inputbox::text::tip_string(std::wstring tip) + { + impl_->tip = std::move(tip); + } + + void inputbox::text::tip_string(std::string tip_utf8) + { + impl_->tip = ::nana::charset(tip_utf8, ::nana::unicode::utf8); + } + + void inputbox::text::mask_character(wchar_t ch) + { + impl_->mask_character = ch; + } + ::nana::string inputbox::text::value() const { return impl_->value; @@ -774,6 +791,8 @@ namespace nana if (impl->options.empty()) { impl->textbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, 0, 0 }); + impl->textbox.tip_string(impl->tip); + impl->textbox.mask(impl->mask_character); } else { @@ -970,7 +989,6 @@ namespace nana void inputbox::_m_fetch_args(std::vector&) {} - bool inputbox::_m_open(std::vector& contents, bool modal) { std::vector each_pixels; From baa8f4a9e9470ac46b1afa0f6dc8505f83748f53 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 23 Feb 2015 01:23:34 +0800 Subject: [PATCH 11/23] fixed an integer overflow issue --- source/gui/layout_utility.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/gui/layout_utility.cpp b/source/gui/layout_utility.cpp index a190b714..94d8dd0f 100644 --- a/source/gui/layout_utility.cpp +++ b/source/gui/layout_utility.cpp @@ -1,6 +1,7 @@ /* * Utility Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -17,11 +18,11 @@ namespace nana //overlap test if overlaped between r1 and r2 bool overlap(const rectangle& r1, const rectangle& r2) { - if(r1.y + int(r1.height) <= r2.y) return false; - if(r1.y >= int(r2.y + r2.height)) return false; + if (r1.y + long long(r1.height) <= r2.y) return false; + if(r1.y >= r2.y + long long(r2.height)) return false; - if(int(r1.x + r1.width) <= r2.x) return false; - if(r1.x >= int(r2.x + r2.width)) return false; + if(r1.x + long long(r1.width) <= r2.x) return false; + if(r1.x >= r2.x + long long(r2.width)) return false; return true; } @@ -60,7 +61,11 @@ namespace nana zoom(ir, op_ir, dr, op_dr); - if(false == covered(op_dr, good_dr)) + if (covered(op_dr, good_dr)) + { + overlap({ op_dr }, good_dr, op_dr); + } + else { op_dr = good_dr; zoom(dr, good_dr, ir, op_ir); From 723dea218d803e7142abdb1b7a77c8e111f274c3 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 23 Feb 2015 01:43:23 +0800 Subject: [PATCH 12/23] improve nana::picture --- include/nana/gui/widgets/picture.hpp | 60 ++---- include/nana/paint/graphics.hpp | 1 + source/gui/widgets/picture.cpp | 307 ++++++++------------------- source/paint/graphics.cpp | 5 + 4 files changed, 111 insertions(+), 262 deletions(-) diff --git a/include/nana/gui/widgets/picture.hpp b/include/nana/gui/widgets/picture.hpp index 5c9b5f97..712bb167 100644 --- a/include/nana/gui/widgets/picture.hpp +++ b/include/nana/gui/widgets/picture.hpp @@ -17,59 +17,39 @@ namespace nana { - namespace xpicture + namespace drawerbase { - class picture_drawer: public drawer_trigger + namespace picture { - public: - picture_drawer(); - void attached(widget_reference, graph_reference) override; - void load(const nana::char_t* file); - void load(const nana::paint::image&); - void set_shadow_background(const ::nana::color& from, const ::nana::color& to, bool horizontal); - bool bgstyle(bool is_stretch, nana::arrange, int beg, int end); - private: - void refresh(graph_reference) override; - void _m_draw_background(); - private: - widget* widget_; - nana::paint::graphics* graph_; + struct implement; - struct + class drawer : public drawer_trigger { - ::nana::color gradual_from; - ::nana::color gradual_to; - bool horizontal; - }bground_; + public: + drawer(); + ~drawer(); + void attached(widget_reference, graph_reference) override; + private: + void refresh(graph_reference) override; + void _m_draw_background(); + public: + implement * const impl_; + }; + }//end namespace picture + }//end namespace drawerbase - struct back_image_tag - { - nana::paint::image image; - bool is_stretch; - nana::arrange arg; - int beg, end; - }backimg_; - - }; - - }//end namespace xpicture /// Rectangle area for displaying a bitmap file class picture - : public widget_object + : public widget_object { public: picture(); picture(window, bool visible); - picture(window, const rectangle& = rectangle(), bool visible = true); + picture(window, const rectangle& ={}, bool visible = true); - void load(const nana::paint::image&); + void load(nana::paint::image); - /// Sets the background image style. - void bgstyle(bool stretchable, ///< if false the other arguments will be ignored - nana::arrange arg, ///< stretching the image horizontally or vertically - int beg, ///< specify the stretchy area of image. - int end ///< specify the stretchy area of image. - ); + void stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom); /// Fills a gradual-change color in background. If One of colors is invisible or clr_from is equal to clr_to, it draws background in bgcolor. void set_gradual_background(const ::nana::color& clr_from, const ::nana::color& clr_to, bool horizontal); diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index b14a4cb7..aac4712a 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -128,6 +128,7 @@ namespace nana unsigned height() const; ///< Returns the height of the off-screen buffer. ::nana::size size() const; void setsta(); ///< Clears the status if the graphics object had been changed + void set_changed(); void release(); void save_as_file(const char*); diff --git a/source/gui/widgets/picture.cpp b/source/gui/widgets/picture.cpp index 7571d709..4446dff1 100644 --- a/source/gui/widgets/picture.cpp +++ b/source/gui/widgets/picture.cpp @@ -1,6 +1,7 @@ /* * A Picture Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -13,244 +14,83 @@ #include #include +#include namespace nana { - namespace xpicture + namespace drawerbase { - - //class picture_drawer - picture_drawer::picture_drawer():graph_(nullptr) + namespace picture + { + struct implement { - bground_.horizontal = true; - backimg_.arg = nana::arrange::unknown; - backimg_.beg = backimg_.end = 0; - } + widget* wdg_ptr{nullptr}; + paint::graphics* graph_ptr{nullptr}; - void picture_drawer::attached(widget_reference& widget, graph_reference graph) - { - widget_ = &widget; - graph_ = &graph; - } - void picture_drawer::load(const nana::char_t* file) - { - backimg_.image.open(file); - } - - void picture_drawer::load(const nana::paint::image& img) - { - backimg_.image = img; - } - - void picture_drawer::set_shadow_background(const ::nana::color& from, const ::nana::color& to, bool horizontal) - { - bground_.gradual_from = from; - bground_.gradual_to = to; - bground_.horizontal = horizontal; - - _m_draw_background(); - } - - bool picture_drawer::bgstyle(bool is_stretch, nana::arrange arg, int beg, int end) - { - if(backimg_.image) + struct gradual_bground_tag { - backimg_.is_stretch = is_stretch; - backimg_.arg = arg; + ::nana::color gradual_from; + ::nana::color gradual_to; + bool horizontal{true}; + }gradual_bground; - if(arg == nana::arrange::horizontal_vertical) return false; + struct back_image_tag + { + paint::image image; + std::unique_ptr bground; + }backimg; + }; - if(beg < 0) beg = 0; - if(end < beg) end = beg; - if((backimg_.beg == beg) && (backimg_.end == end)) return false; - - nana::size imgsize = backimg_.image.size(); - unsigned scale = (arg == nana::arrange::horizontal ? imgsize.width : imgsize.height); - - if(beg < 0) - beg = 0; - else if(static_cast(beg) >= scale) - beg = static_cast(scale) - 1; - - if(end < beg) - end = beg; - else if(static_cast(end) >= scale) - end = static_cast(scale) - 1; - - backimg_.beg = beg; - backimg_.end = end; - return true; - } - - backimg_.arg = nana::arrange::unknown; - return false; + //class drawer + drawer::drawer() :impl_(new implement) + { } - void picture_drawer::refresh(graph_reference graph) + drawer::~drawer() { - if(graph.changed()) + delete impl_; + } + + void drawer::attached(widget_reference& wdg, graph_reference graph) + { + impl_->wdg_ptr = &wdg; + impl_->graph_ptr = &graph; + } + + void drawer::refresh(graph_reference graph) + { + if (!graph.changed()) + return; + + if (!impl_->backimg.bground) { _m_draw_background(); - if(backimg_.image.empty() == false) - { - nana::size imgsize = backimg_.image.size(); - nana::size gsize = graph.size(); - - switch(backimg_.arg) - { - case nana::arrange::unknown: - backimg_.image.paste(graph, 0, 0); - break; - case nana::arrange::horizontal: - if(backimg_.beg < backimg_.end) - { - unsigned block_tail = imgsize.width - backimg_.end; - - if(backimg_.beg) - backimg_.image.paste(nana::rectangle(0, 0, backimg_.beg, imgsize.height), graph, nana::point()); - - if(block_tail) - backimg_.image.paste(nana::rectangle(static_cast(imgsize.width - block_tail), 0, block_tail, imgsize.height), graph, nana::point(gsize.width - block_tail, 0)); - - if(backimg_.beg < backimg_.end) - { - unsigned fixed_size = backimg_.beg + block_tail; - if(fixed_size < gsize.width) - { - if(false == backimg_.is_stretch) - { - unsigned imgarea = backimg_.end - backimg_.beg; - fixed_size = gsize.width - fixed_size; - - nana::rectangle r(backimg_.beg, 0, imgarea, imgsize.height); - nana::point p_dst(backimg_.beg, 0); - - while(imgarea < fixed_size) - { - backimg_.image.paste(r, graph, p_dst); - p_dst.x += static_cast(imgarea); - fixed_size -= imgarea; - } - if(fixed_size) - { - r.width = fixed_size; - backimg_.image.paste(r, graph, p_dst); - } - } - else - backimg_.image.stretch(nana::rectangle(backimg_.beg, 0, imgsize.width - fixed_size, imgsize.height), graph, nana::rectangle(backimg_.beg, 0, gsize.width - fixed_size, imgsize.height)); - } - } - } - else - { - if(false == backimg_.is_stretch) - { - int x = 0; - while(x < static_cast(gsize.width)) - { - backimg_.image.paste(graph, x, 0); - x += static_cast(imgsize.width); - } - } - else - backimg_.image.stretch(imgsize, graph, nana::size(gsize.width, imgsize.height)); - } - break; - case nana::arrange::vertical: - if(backimg_.beg < backimg_.end) - { - unsigned block_tail = imgsize.height - backimg_.end; - - if(backimg_.beg) - backimg_.image.paste(nana::rectangle(0, 0, imgsize.width, static_cast(backimg_.beg)), graph, nana::point()); - - if(block_tail) - backimg_.image.paste(nana::rectangle(0, static_cast(imgsize.height - block_tail), imgsize.width, block_tail), graph, nana::point(0, gsize.height - block_tail)); - - if(backimg_.beg < backimg_.end) - { - unsigned fixed_size = backimg_.beg + block_tail; - if(fixed_size < gsize.height) - { - if(false == backimg_.is_stretch) - { - unsigned imgarea = backimg_.end - backimg_.beg; - fixed_size = gsize.height - fixed_size; - - nana::rectangle r(0, backimg_.beg, imgsize.width, imgarea); - nana::point pos(0, backimg_.beg); - - while(imgarea < fixed_size) - { - backimg_.image.paste(r, graph, pos); - pos.y += static_cast(imgarea); - fixed_size -= imgarea; - } - if(fixed_size) - { - r.height = fixed_size; - backimg_.image.paste(r, graph, pos); - } - } - else - backimg_.image.stretch(nana::rectangle(0, backimg_.beg, imgsize.width, imgsize.height - fixed_size), graph, nana::rectangle(0, backimg_.beg, imgsize.width, gsize.height - fixed_size)); - } - } - } - else - { - if(false == backimg_.is_stretch) - { - int y = 0; - while(y < static_cast(gsize.height)) - { - backimg_.image.paste(graph, 0, y); - y += static_cast(imgsize.height); - } - } - else - backimg_.image.stretch(imgsize, graph, nana::rectangle(0, 0, imgsize.width, gsize.height)); - } - break; - case nana::arrange::horizontal_vertical: - if(backimg_.is_stretch == false) - { - int y = 0; - while(y < static_cast(gsize.height)) - { - int x = 0; - while(x < static_cast(gsize.width)) - { - backimg_.image.paste(graph, x, y); - x += static_cast(imgsize.width); - } - y += static_cast(imgsize.height); - } - } - else - backimg_.image.stretch(imgsize, graph, gsize); - break; - } - } + impl_->backimg.image.paste(graph, 0, 0); } + else + impl_->backimg.bground->draw(graph, {}, {}, graph.size(), element_state::normal); + + graph.setsta(); } - void picture_drawer::_m_draw_background() + void drawer::_m_draw_background() { - if(graph_ && (bground_mode::basic != API::effects_bground_mode(*widget_))) + auto graph = impl_->graph_ptr; + if (graph && (bground_mode::basic != API::effects_bground_mode(*impl_->wdg_ptr))) { - if (bground_.gradual_from.invisible() || bground_.gradual_to.invisible()) - graph_->rectangle(true, widget_->bgcolor()); - else if(bground_.gradual_from == bground_.gradual_to) - graph_->rectangle(true, bground_.gradual_from); + auto & bground = impl_->gradual_bground; + if (bground.gradual_from.invisible() || bground.gradual_to.invisible()) + graph->rectangle(true, impl_->wdg_ptr->bgcolor()); + else if (bground.gradual_from == bground.gradual_to) + graph->rectangle(true, bground.gradual_from); else - graph_->gradual_rectangle(graph_->size(), bground_.gradual_from, bground_.gradual_to, !bground_.horizontal); + graph->gradual_rectangle(graph->size(), bground.gradual_from, bground.gradual_to, !bground.horizontal); } } - //end class picture_drawer - }//end namespace xpicture + //end class drawer + }//end namespace picture + }//end namespace drawerbase //class picture picture::picture(){} @@ -265,21 +105,44 @@ namespace nana create(wd, r, visible); } - void picture::load(const nana::paint::image& img) + void picture::load(nana::paint::image img) { - get_drawer_trigger().load(img); + auto& backimg = get_drawer_trigger().impl_->backimg; + backimg.image = std::move(img); + + if (backimg.bground) + backimg.bground->image(backimg.image, true, {}); + + get_drawer_trigger().impl_->graph_ptr->set_changed(); API::refresh_window(*this); } - void picture::bgstyle(bool stretchable, nana::arrange arg, int beg, int end) + void picture::stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom) { - if(get_drawer_trigger().bgstyle(stretchable, arg, beg, end)) - API::refresh_window(*this); + if (!handle()) + return; + + auto & backimg = get_drawer_trigger().impl_->backimg; + if (!backimg.bground) + { + backimg.bground.reset(new element::bground); + backimg.bground->states({ element_state::normal }); + backimg.bground->image(backimg.image, true, {}); + } + + backimg.bground->stretch_parts(left, top, right, bottom); + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); } void picture::set_gradual_background(const ::nana::color& from, const ::nana::color& to, bool horizontal) { - get_drawer_trigger().set_shadow_background(from, to, horizontal); + auto & bground = get_drawer_trigger().impl_->gradual_bground; + bground.gradual_from = from; + bground.gradual_to = to; + bground.horizontal = horizontal; + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); } void picture::transparent(bool enabled) diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index f8649ca5..8e61e8dd 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -800,6 +800,11 @@ namespace paint changed_ = false; } + void graphics::set_changed() + { + changed_ = true; + } + void graphics::release() { dwptr_.reset(); From d7a0d6f7d37d9d8c2b7c9404a7a56a35b1669b5a Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 23 Feb 2015 01:45:00 +0800 Subject: [PATCH 13/23] support of display images in inputbox --- include/nana/gui/msgbox.hpp | 11 ++-- source/gui/msgbox.cpp | 113 +++++++++++++++++++++++++++--------- 2 files changed, 93 insertions(+), 31 deletions(-) diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index f153dcf2..173893af 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -100,7 +100,7 @@ namespace nana virtual const ::nana::string& label() const = 0; virtual window create(window, unsigned label_px) = 0; - virtual unsigned fixed_pixels() const = 0; + virtual unsigned fixed_pixels() const; }; public: class integer @@ -116,7 +116,6 @@ namespace nana //Implementation of abstract_content const ::nana::string& label() const override; window create(window, unsigned label_px) override; - unsigned fixed_pixels() const override; private: std::unique_ptr impl_; }; @@ -134,7 +133,6 @@ namespace nana //Implementation of abstract_content const ::nana::string& label() const override; window create(window, unsigned label_px) override; - unsigned fixed_pixels() const override; private: std::unique_ptr impl_; }; @@ -159,7 +157,6 @@ namespace nana //Implementation of abstract_content const ::nana::string& label() const override; window create(window, unsigned label_px) override; - unsigned fixed_pixels() const override; private: std::unique_ptr impl_; }; @@ -177,17 +174,20 @@ namespace nana int year() const; int month() const; //[1, 12] int day() const; //[1, 31] - unsigned fixed_pixels() const override; private: //Implementation of abstract_content const ::nana::string& label() const override; window create(window, unsigned label_px) override; + unsigned fixed_pixels() const override; private: std::unique_ptr impl_; }; inputbox(window, ::nana::string description, ::nana::string title = ::nana::string()); + void image(::nana::paint::image, bool is_left); + void image_v(::nana::paint::image, bool is_top); + template bool show(Args&& ... args) { @@ -230,6 +230,7 @@ namespace nana ::nana::string description_; ::nana::string title_; std::function verifier_; + ::nana::paint::image images_[4]; }; }//end namespace nana diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index acf2ecfe..e864a3ca 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -474,7 +475,7 @@ namespace nana : public ::nana::form { public: - inputbox_window(window owner, const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) + inputbox_window(window owner, paint::image (&imgs)[4], const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) : form(owner, API::make_center(owner, 500, 300), appear::decorate<>()) { desc_.create(*this); @@ -501,8 +502,8 @@ namespace nana unsigned height = 20 + desc_extent.height + 10 + 38; place_.bind(*this); - std::stringstream ss; - ss << "margin=10 vert 27) px = each_height[i]; - ss << ""; + ss_content << ""; height += px + 1; } - ss << ">>"; - - place_.div(ss.str().data()); - place_["desc"] << desc_; - place_["buttons"] << btn_ok_ << btn_cancel_; + ss_content << ">>>"; if (desc_extent.width < 170) desc_extent.width = 170; @@ -528,7 +525,67 @@ namespace nana if (desc_extent.width < fixed_pixels) desc_extent.width = fixed_pixels; - size({ desc_extent.width + 20, height }); + desc_extent.width += 20; + + ::nana::size img_sz[4]; + + if (imgs[2]) //Left + { + auto & sz = img_sz[2]; + sz = imgs[2].size(); + sz.width = static_cast(double(sz.width) * (double(height) / double(sz.height))); + desc_extent.width += sz.width; + } + + if (imgs[3]) //Right + { + auto & sz = img_sz[3]; + sz = imgs[3].size(); + sz.width = static_cast(double(sz.width) * (double(height) / double(sz.height))); + desc_extent.width += sz.width; + } + + if (imgs[0]) //Top + { + auto & sz = img_sz[0]; + sz = imgs[0].size(); + sz.height = static_cast(double(sz.height) * (double(desc_extent.width) / double(sz.width))); + height += sz.height; + } + + if (imgs[1]) //Bottom + { + auto & sz = img_sz[1]; + sz = imgs[1].size(); + sz.height = static_cast(double(sz.height) * (double(desc_extent.width) / double(sz.width))); + height += sz.height; + } + + std::stringstream ss; + ss << "vert<"<>"; + + place_.div(ss.str().data()); + place_["desc"] << desc_; + place_["buttons"] << btn_ok_ << btn_cancel_; + + const char * img_fields[4] = {"img_top", "img_bottom", "img_left", "img_right"}; + + for (int i = 0; i < 4; ++i) + { + if (imgs[i]) + { + images_[i].create(*this, true); + images_[i].load(imgs[i]); + //images_[i].bgstyle(true, ::nana::arrange::horizontal_vertical, 0, 0); + images_[i].stretchable(0, 0, 0, 0); + place_[img_fields[i]] << images_[i]; + place_.field_display(img_fields[i], true); + } + else + place_.field_display(img_fields[i], false); + } + + size({desc_extent.width, height }); caption(title); } @@ -558,8 +615,14 @@ namespace nana bool valid_input_{ false }; ::nana::place place_; std::function verifier_; + ::nana::picture images_[4]; }; + unsigned inputbox::abstract_content::fixed_pixels() const + { + return 0; + } + //class integer struct inputbox::integer::implement { @@ -632,11 +695,6 @@ namespace nana return impl->dock; } - - unsigned inputbox::integer::fixed_pixels() const - { - return 0; - } //end class integer @@ -712,11 +770,6 @@ namespace nana return impl->dock; } - - unsigned inputbox::real::fixed_pixels() const - { - return 0; - } //end class real @@ -830,11 +883,6 @@ namespace nana }); return impl->dock; } - - unsigned inputbox::text::fixed_pixels() const - { - return 0; - } //end class text @@ -876,6 +924,7 @@ namespace nana { return impl_->month; } + int inputbox::date::day() const { return impl_->day; @@ -981,6 +1030,18 @@ namespace nana title_(std::move(title)) {} + void inputbox::image(::nana::paint::image img, bool is_left) + { + auto pos = (is_left ? 2 : 3); + images_[pos] = std::move(img); + } + + void inputbox::image_v(::nana::paint::image img, bool is_top) + { + auto pos = (is_top ? 0 : 1); + images_[pos] = std::move(img); + } + void inputbox::verify(std::function verifier) { verifier_ = std::move(verifier); @@ -1007,7 +1068,7 @@ namespace nana each_pixels.push_back(px.height); } - inputbox_window input_wd(owner_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels); + inputbox_window input_wd(owner_, images_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels); std::vector inputs; for (auto p : contents) From 022f7168c0b59ec974445e5fa6bfa92bc2f19bcf Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 23 Feb 2015 18:05:18 +0800 Subject: [PATCH 14/23] improve picture widget stretchable mode --- include/nana/gui/widgets/picture.hpp | 16 ++- source/gui/layout_utility.cpp | 13 +++ source/gui/widgets/picture.cpp | 158 ++++++++++++++++++++++++--- 3 files changed, 170 insertions(+), 17 deletions(-) diff --git a/include/nana/gui/widgets/picture.hpp b/include/nana/gui/widgets/picture.hpp index 712bb167..7b7b7487 100644 --- a/include/nana/gui/widgets/picture.hpp +++ b/include/nana/gui/widgets/picture.hpp @@ -17,6 +17,8 @@ namespace nana { + class picture; + namespace drawerbase { namespace picture @@ -25,6 +27,7 @@ namespace nana class drawer : public drawer_trigger { + friend class ::nana::picture; public: drawer(); ~drawer(); @@ -32,7 +35,7 @@ namespace nana private: void refresh(graph_reference) override; void _m_draw_background(); - public: + private: implement * const impl_; }; }//end namespace picture @@ -47,12 +50,19 @@ namespace nana picture(window, bool visible); picture(window, const rectangle& ={}, bool visible = true); - void load(nana::paint::image); + void load(::nana::paint::image, const rectangle& valid_area = {}); + /// Sets the align of image. + void align(align, align_v); + + /// Enables the image to be stretched to the widget size. void stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom); + /// Enables/disable the image to be stretched without changing aspect ratio. + void stretchable(bool); + /// Fills a gradual-change color in background. If One of colors is invisible or clr_from is equal to clr_to, it draws background in bgcolor. - void set_gradual_background(const ::nana::color& clr_from, const ::nana::color& clr_to, bool horizontal); + void set_gradual_background(const color& clr_from, const color& clr_to, bool horizontal); void transparent(bool); bool transparent() const; }; diff --git a/source/gui/layout_utility.cpp b/source/gui/layout_utility.cpp index 94d8dd0f..7f72db0c 100644 --- a/source/gui/layout_utility.cpp +++ b/source/gui/layout_utility.cpp @@ -246,6 +246,19 @@ namespace nana result_s = ref_s; } + size fit_zoom(const size& input_s, size ref_s) + { + double rate_input = double(input_s.width) / double(input_s.height); + double rate_ref = double(ref_s.width) / double(ref_s.height); + + if (rate_input < rate_ref) + ref_s.width = static_cast(ref_s.height * rate_input); + else if (rate_input > rate_ref) + ref_s.height = static_cast(ref_s.width / rate_input); + + return ref_s; + } + void zoom(const rectangle& ref, const rectangle& scaled, const rectangle& ref_dst, rectangle& r) { double rate_x = (scaled.x - ref.x) / double(ref.width); diff --git a/source/gui/widgets/picture.cpp b/source/gui/widgets/picture.cpp index 4446dff1..83bb3d9d 100644 --- a/source/gui/widgets/picture.cpp +++ b/source/gui/widgets/picture.cpp @@ -38,7 +38,11 @@ namespace nana struct back_image_tag { paint::image image; - std::unique_ptr bground; + rectangle valid_area; + ::nana::align align_horz{ ::nana::align::left }; + ::nana::align_v align_vert{ ::nana::align_v::top }; + std::unique_ptr bground; //If it is not a null ptr, the widget is stretchable mode + bool stretchable{ false }; //If it is true, the widget is stretchable mode without changing aspect ratio. }backimg; }; @@ -63,13 +67,92 @@ namespace nana if (!graph.changed()) return; - if (!impl_->backimg.bground) + auto graphsize = graph.size(); + + auto & backimg = impl_->backimg; + + if (!backimg.bground) { - _m_draw_background(); - impl_->backimg.image.paste(graph, 0, 0); + auto valid_area = backimg.valid_area; + if (valid_area.empty()) + valid_area = backimg.image.size(); + + if (backimg.stretchable) + { + auto fit_size = fit_zoom({ valid_area.width, valid_area.height }, graphsize); + //::nana::point pos{ int(graphsize.width - fit_size.width), int(graphsize.height - fit_size.height) }; + ::nana::point pos; + + if (fit_size.width != graphsize.width) + { + switch (backimg.align_horz) + { + case ::nana::align::left: break; + case ::nana::align::center: + pos.x = (int(graphsize.width) - int(fit_size.width)) / 2; + break; + case ::nana::align::right: + pos.x = int(graphsize.width) - int(fit_size.width); + break; + } + } + else if (fit_size.height != graphsize.height) + { + switch (backimg.align_vert) + { + case ::nana::align_v::top: break; + case ::nana::align_v::center: + pos.y = (int(graphsize.height) - int(fit_size.height)) / 2; + break; + case ::nana::align_v::bottom: + pos.y = int(graphsize.height) - int(fit_size.height); + break; + } + } + + if (fit_size.width < graphsize.width || fit_size.height < graphsize.height) + _m_draw_background(); + + backimg.image.stretch(valid_area, graph, { pos, fit_size }); + } + else + { + //The point in which position the image to be drawn. + ::nana::point pos; + + switch (backimg.align_horz) + { + case ::nana::align::left: break; + case ::nana::align::center: + pos.x = (int(graphsize.width) - int(valid_area.width)) / 2; + break; + case ::nana::align::right: + pos.x = int(graphsize.width) - int(valid_area.width); + break; + } + + switch (backimg.align_vert) + { + case ::nana::align_v::top: break; + case ::nana::align_v::center: + pos.y = (int(graphsize.height) - int(valid_area.height)) / 2; + break; + case ::nana::align_v::bottom: + pos.y = int(graphsize.height) - int(valid_area.height); + break; + } + + if (valid_area.width < graphsize.width || valid_area.height < graphsize.height) + _m_draw_background(); + + backimg.image.paste(valid_area, graph, pos); + } } else - impl_->backimg.bground->draw(graph, {}, {}, graph.size(), element_state::normal); + { + color invalid_clr_for_call; + backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, graphsize, element_state::normal); + } graph.setsta(); } @@ -105,16 +188,40 @@ namespace nana create(wd, r, visible); } - void picture::load(nana::paint::image img) + void picture::load(::nana::paint::image img, const ::nana::rectangle& valid_area) { + internal_scope_guard lock; auto& backimg = get_drawer_trigger().impl_->backimg; backimg.image = std::move(img); + backimg.valid_area = valid_area; if (backimg.bground) - backimg.bground->image(backimg.image, true, {}); + backimg.bground->image(backimg.image, true, valid_area); - get_drawer_trigger().impl_->graph_ptr->set_changed(); - API::refresh_window(*this); + if (handle()) + { + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); + } + } + + void picture::align(::nana::align horz, align_v vert) + { + internal_scope_guard lock; + + auto& backimg = get_drawer_trigger().impl_->backimg; + + if (backimg.align_horz == horz && backimg.align_vert == vert) + return; + + backimg.align_horz = horz; + backimg.align_vert = vert; + + if (handle()) + { + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); + } } void picture::stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom) @@ -122,17 +229,37 @@ namespace nana if (!handle()) return; + internal_scope_guard lock; auto & backimg = get_drawer_trigger().impl_->backimg; if (!backimg.bground) { backimg.bground.reset(new element::bground); backimg.bground->states({ element_state::normal }); - backimg.bground->image(backimg.image, true, {}); + backimg.bground->image(backimg.image, true, backimg.valid_area); } backimg.bground->stretch_parts(left, top, right, bottom); - get_drawer_trigger().impl_->graph_ptr->set_changed(); - API::refresh_window(*this); + backimg.stretchable = false; + if (handle()) + { + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); + } + } + + void picture::stretchable(bool enables) + { + internal_scope_guard lock; + + auto & backimg = get_drawer_trigger().impl_->backimg; + backimg.bground.reset(); + + backimg.stretchable = enables; + if (handle()) + { + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); + } } void picture::set_gradual_background(const ::nana::color& from, const ::nana::color& to, bool horizontal) @@ -141,8 +268,11 @@ namespace nana bground.gradual_from = from; bground.gradual_to = to; bground.horizontal = horizontal; - get_drawer_trigger().impl_->graph_ptr->set_changed(); - API::refresh_window(*this); + if (handle()) + { + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); + } } void picture::transparent(bool enabled) From f454a965be38d1451c222a70f56d80d91adc09c6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 24 Feb 2015 17:03:17 +0800 Subject: [PATCH 15/23] improve inputbox --- include/nana/gui/msgbox.hpp | 23 ++++++++++++-- include/nana/gui/widgets/picture.hpp | 2 +- source/gui/msgbox.cpp | 45 +++++++++++++++++++++------- source/gui/widgets/picture.cpp | 3 -- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index 173893af..6aa6f020 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -183,10 +183,28 @@ namespace nana std::unique_ptr impl_; }; + class path + : public abstract_content + { + struct implement; + public: + path(::nana::string label, ::nana::string init_path = ::nana::string()); + ~path(); + + ::nana::string value() const; + private: + //Implementation of abstract_content + const ::nana::string& label() const override; + window create(window, unsigned label_px) override; + unsigned fixed_pixels() const override; + private: + std::unique_ptr impl_; + }; + inputbox(window, ::nana::string description, ::nana::string title = ::nana::string()); - void image(::nana::paint::image, bool is_left); - void image_v(::nana::paint::image, bool is_top); + void image(::nana::paint::image, bool is_left, const rectangle& valid_area = {}); + void image_v(::nana::paint::image, bool is_top, const rectangle& valid_area = {}); template bool show(Args&& ... args) @@ -231,6 +249,7 @@ namespace nana ::nana::string title_; std::function verifier_; ::nana::paint::image images_[4]; + ::nana::rectangle valid_areas_[4]; }; }//end namespace nana diff --git a/include/nana/gui/widgets/picture.hpp b/include/nana/gui/widgets/picture.hpp index 7b7b7487..33c67552 100644 --- a/include/nana/gui/widgets/picture.hpp +++ b/include/nana/gui/widgets/picture.hpp @@ -46,7 +46,7 @@ namespace nana : public widget_object { public: - picture(); + picture() = default; picture(window, bool visible); picture(window, const rectangle& ={}, bool visible = true); diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index e864a3ca..b4fb8b30 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -475,7 +475,7 @@ namespace nana : public ::nana::form { public: - inputbox_window(window owner, paint::image (&imgs)[4], const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) + inputbox_window(window owner, paint::image (&imgs)[4], ::nana::rectangle (&valid_areas)[4], const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) : form(owner, API::make_center(owner, 500, 300), appear::decorate<>()) { desc_.create(*this); @@ -532,7 +532,13 @@ namespace nana if (imgs[2]) //Left { auto & sz = img_sz[2]; - sz = imgs[2].size(); + if (!valid_areas[2].empty()) + { + sz.width = valid_areas[2].width; + sz.height = valid_areas[2].height; + } + else + sz = imgs[2].size(); sz.width = static_cast(double(sz.width) * (double(height) / double(sz.height))); desc_extent.width += sz.width; } @@ -540,7 +546,13 @@ namespace nana if (imgs[3]) //Right { auto & sz = img_sz[3]; - sz = imgs[3].size(); + if (!valid_areas[3].empty()) + { + sz.width = valid_areas[3].width; + sz.height = valid_areas[3].height; + } + else + sz = imgs[3].size(); sz.width = static_cast(double(sz.width) * (double(height) / double(sz.height))); desc_extent.width += sz.width; } @@ -548,7 +560,13 @@ namespace nana if (imgs[0]) //Top { auto & sz = img_sz[0]; - sz = imgs[0].size(); + if (!valid_areas[0].empty()) + { + sz.width = valid_areas[0].width; + sz.height = valid_areas[0].height; + } + else + sz = imgs[0].size(); sz.height = static_cast(double(sz.height) * (double(desc_extent.width) / double(sz.width))); height += sz.height; } @@ -556,7 +574,13 @@ namespace nana if (imgs[1]) //Bottom { auto & sz = img_sz[1]; - sz = imgs[1].size(); + if (!valid_areas[1].empty()) + { + sz.width = valid_areas[1].width; + sz.height = valid_areas[1].height; + } + else + sz = imgs[1].size(); sz.height = static_cast(double(sz.height) * (double(desc_extent.width) / double(sz.width))); height += sz.height; } @@ -575,8 +599,7 @@ namespace nana if (imgs[i]) { images_[i].create(*this, true); - images_[i].load(imgs[i]); - //images_[i].bgstyle(true, ::nana::arrange::horizontal_vertical, 0, 0); + images_[i].load(imgs[i], valid_areas[i]); images_[i].stretchable(0, 0, 0, 0); place_[img_fields[i]] << images_[i]; place_.field_display(img_fields[i], true); @@ -1030,16 +1053,18 @@ namespace nana title_(std::move(title)) {} - void inputbox::image(::nana::paint::image img, bool is_left) + void inputbox::image(::nana::paint::image img, bool is_left, const rectangle& valid_area) { auto pos = (is_left ? 2 : 3); images_[pos] = std::move(img); + valid_areas_[pos] = valid_area; } - void inputbox::image_v(::nana::paint::image img, bool is_top) + void inputbox::image_v(::nana::paint::image img, bool is_top, const rectangle& valid_area) { auto pos = (is_top ? 0 : 1); images_[pos] = std::move(img); + valid_areas_[pos] = valid_area; } void inputbox::verify(std::function verifier) @@ -1068,7 +1093,7 @@ namespace nana each_pixels.push_back(px.height); } - inputbox_window input_wd(owner_, images_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels); + inputbox_window input_wd(owner_, images_, valid_areas_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels); std::vector inputs; for (auto p : contents) diff --git a/source/gui/widgets/picture.cpp b/source/gui/widgets/picture.cpp index 83bb3d9d..b9912cc7 100644 --- a/source/gui/widgets/picture.cpp +++ b/source/gui/widgets/picture.cpp @@ -80,7 +80,6 @@ namespace nana if (backimg.stretchable) { auto fit_size = fit_zoom({ valid_area.width, valid_area.height }, graphsize); - //::nana::point pos{ int(graphsize.width - fit_size.width), int(graphsize.height - fit_size.height) }; ::nana::point pos; if (fit_size.width != graphsize.width) @@ -176,8 +175,6 @@ namespace nana }//end namespace drawerbase //class picture - picture::picture(){} - picture::picture(window wd, bool visible) { create(wd, rectangle(), visible); From c2cb89f024a266a2d29d77ba503b7ede16eca0bd Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 25 Feb 2015 01:00:27 +0800 Subject: [PATCH 16/23] improve inputbox fix some inputbox issues add a new inputbox::path class --- include/nana/gui/filebox.hpp | 31 +++++++++-- include/nana/gui/msgbox.hpp | 5 +- source/gui/filebox.cpp | 35 +++++++++++- source/gui/msgbox.cpp | 102 ++++++++++++++++++++++++++++++++++- 4 files changed, 164 insertions(+), 9 deletions(-) diff --git a/include/nana/gui/filebox.hpp b/include/nana/gui/filebox.hpp index 7dcbb225..d60ec5c2 100644 --- a/include/nana/gui/filebox.hpp +++ b/include/nana/gui/filebox.hpp @@ -1,19 +1,42 @@ +/* + * Filebox + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/gui/filebox.hpp + */ + #ifndef NANA_GUI_FILEBOX_HPP #define NANA_GUI_FILEBOX_HPP -#include +#include +#include +#include namespace nana { /// Create an Open or Save dialog box to let user select the name of a file. class filebox - : nana::noncopyable { struct implement; - public: - typedef std::vector> filters; + filebox(filebox&&) = delete; + filebox& operator=(filebox&&) = delete; + public: + using filters = std::vector>; + + filebox(bool is_open_mode); filebox(window owner, bool is_open_mode); + filebox(const filebox&); ~filebox(); + filebox& operator=(const filebox&); + + /// Change owner window + void owner(window); + /** @brief specify a title for the dialog * @param string a text for title */ diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index 6aa6f020..6fbec87c 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -14,7 +14,7 @@ #define NANA_GUI_MSGBOX_HPP #include -#include +#include namespace nana { @@ -188,7 +188,7 @@ namespace nana { struct implement; public: - path(::nana::string label, ::nana::string init_path = ::nana::string()); + path(::nana::string label, const ::nana::filebox&); ~path(); ::nana::string value() const; @@ -196,7 +196,6 @@ namespace nana //Implementation of abstract_content const ::nana::string& label() const override; window create(window, unsigned label_px) override; - unsigned fixed_pixels() const override; private: std::unique_ptr impl_; }; diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index f8937e38..78a40a3f 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -1,4 +1,16 @@ -#include +/* +* Filebox +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file: nana/gui/filebox.cpp +*/ + +#include #include #if defined(NANA_WINDOWS) @@ -858,6 +870,11 @@ namespace nana std::vector filters; }; + filebox::filebox(bool is_openmode) + : filebox(nullptr, is_openmode) + { + } + filebox::filebox(window owner, bool open) : impl_(new implement) { @@ -874,11 +891,27 @@ namespace nana #endif } + filebox::filebox(const filebox& other) + : impl_(new implement(*other.impl_)) + {} + filebox::~filebox() { delete impl_; } + filebox& filebox::operator=(const filebox& other) + { + if (this != &other) + *impl_ = *other.impl_; + return *this; + } + + void filebox::owner(window wd) + { + impl_->owner = wd; + } + nana::string filebox::title(nana::string s) { impl_->title.swap(s); diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index b4fb8b30..7f71376b 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -676,6 +676,9 @@ namespace nana int inputbox::integer::value() const { + if (!impl_->spinbox.empty()) + return impl_->spinbox.to_int(); + return impl_->value; } @@ -751,6 +754,9 @@ namespace nana double inputbox::real::value() const { + if (!impl_->spinbox.empty()) + return impl_->spinbox.to_double(); + return impl_->value; } @@ -788,7 +794,7 @@ namespace nana impl->spinbox.events().destroy.connect_unignorable([impl] { - impl->value = impl->spinbox.to_int(); + impl->value = impl->spinbox.to_double(); }); return impl->dock; @@ -844,6 +850,11 @@ namespace nana ::nana::string inputbox::text::value() const { + if (!impl_->textbox.empty()) + return impl_->textbox.caption(); + else if (!impl_->combox.empty()) + return impl_->combox.caption(); + return impl_->value; } @@ -869,6 +880,7 @@ namespace nana impl->textbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, 0, 0 }); impl->textbox.tip_string(impl->tip); impl->textbox.mask(impl->mask_character); + impl->textbox.multi_lines(false); } else { @@ -940,16 +952,23 @@ namespace nana int inputbox::date::year() const { + if (!impl_->wdg_year.empty()) + return impl_->wdg_year.to_int(); + return impl_->year; } int inputbox::date::month() const { + if (!impl_->wdg_month.empty()) + return impl_->wdg_month.option() + 1; return impl_->month; } int inputbox::date::day() const { + if (!impl_->wdg_day.empty()) + return impl_->wdg_day.to_int(); return impl_->day; } @@ -1046,6 +1065,87 @@ namespace nana } //end class date + //class path + struct inputbox::path::implement + { + filebox fbox; + + ::nana::string value; + ::nana::string label_text; + ::nana::panel dock; + ::nana::label label; + ::nana::textbox path_edit; + ::nana::button browse; + + implement(const filebox& fb, ::nana::string&& labelstr) + : fbox(fb), label_text(std::move(labelstr)) + {} + }; + + inputbox::path::path(::nana::string label, const filebox& fb) + : impl_(new implement(fb, std::move(label))) + { + } + + //Instance for impl_ because implmenet is incomplete type at the point of declaration + inputbox::path::~path(){} + + ::nana::string inputbox::path::value() const + { + if (!impl_->path_edit.empty()) + return impl_->path_edit.caption(); + + return impl_->value; + } + + //Implementation of abstract_content + const ::nana::string& inputbox::path::label() const + { + return impl_->label_text; + } + + window inputbox::path::create(window wd, unsigned label_px) + { + auto impl = impl_.get(); + impl->dock.create(wd); + + impl->label.create(impl->dock, rectangle{ 0, 0, label_px, 0 }); + impl->label.text_align(::nana::align::right, ::nana::align_v::center); + impl->label.caption(impl->label_text); + impl->label.format(true); + + impl->path_edit.create(impl->dock, rectangle{static_cast(label_px + 10), 0, 0, 0}); + impl->path_edit.caption(impl->fbox.path()); + impl->path_edit.multi_lines(false); + + impl->browse.create(impl->dock); + impl->browse.i18n(i18n_eval("Browse")); + impl->browse.events().click([wd, impl] + { + impl->fbox.owner(wd); + if (impl->fbox.show()) + { + impl->value = impl->fbox.file(); + impl->path_edit.caption(impl->value); + } + }); + + impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg) + { + impl->label.size({ label_px, arg.height }); + impl->path_edit.size({arg.width - label_px - 75, arg.height}); + impl->browse.move({static_cast(arg.width - 60), 0, 60, arg.height}); + }); + + impl->path_edit.events().destroy.connect_unignorable([impl] + { + impl->value = impl->path_edit.caption(); + }); + + return impl->dock; + } + //end class path + inputbox::inputbox(window owner, ::nana::string desc, ::nana::string title) : owner_{ owner }, From aa179dbfd9d3a63ec596e38aecd3526a299b14ba Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 25 Feb 2015 17:18:13 +0800 Subject: [PATCH 17/23] fix slider knob precision issue --- source/gui/widgets/slider.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index e0ca0442..23af12a4 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -198,12 +198,12 @@ namespace nana unsigned vcur() const { - return attr_.vcur; + return static_cast(attr_.vcur); } void resize() { - this->_m_mk_slider_pos_by_value(); + _m_mk_slider_pos_by_value(); attr_.adorn_pos = attr_.pos; } @@ -338,16 +338,18 @@ namespace nana unsigned move_step(bool forward) { - unsigned cmpvalue = attr_.vcur; + unsigned cmpvalue = static_cast(attr_.vcur); + auto value = cmpvalue; if(forward) { - if(attr_.vcur) - --attr_.vcur; + if (value) + --value; } - else if(attr_.vcur < attr_.vmax) - ++attr_.vcur; + else if (value < attr_.vmax) + ++value; - if(cmpvalue != attr_.vcur) + attr_.vcur = value; + if (cmpvalue != value) { _m_mk_slider_pos_by_value(); draw(); @@ -436,32 +438,29 @@ namespace nana return static_cast(_m_scale() * attr_.vcur / attr_.vmax); } - unsigned _m_mk_slider_value_by_pos() + void _m_mk_slider_value_by_pos() { if(_m_scale()) { - auto cmpvalue = attr_.vcur; - attr_.vcur = static_cast(attr_.pos * attr_.vmax / _m_scale()); - if (cmpvalue != attr_.vcur) + auto cmpvalue = static_cast(attr_.vcur); + attr_.vcur = (attr_.pos * attr_.vmax / _m_scale()); + if (cmpvalue != static_cast(attr_.vcur)) _m_emit_value_changed(); } - return attr_.vcur; } - int _m_mk_slider_pos_by_value() + void _m_mk_slider_pos_by_value() { attr_.pos = double(_m_scale()) * attr_.vcur / attr_.vmax; if(slider_state_.trace == slider_state_.TraceNone) attr_.adorn_pos = attr_.pos; - - return static_cast(attr_.pos); } unsigned _m_value_by_pos(double pos) const { if(_m_scale()) - return static_cast(pos * attr_.vmax / _m_scale()); + return static_cast(pos * attr_.vmax / _m_scale()); return 0; } @@ -548,7 +547,7 @@ namespace nana style dir; unsigned border; unsigned vmax; - unsigned vcur; + double vcur; double pos; bool is_draw_adorn; double adorn_pos; From 0d8daca12f25af0b4ca7e550a534c34a3579445d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 25 Feb 2015 18:18:33 +0800 Subject: [PATCH 18/23] fix intercept of system key to respone Alt+F4 --- source/gui/detail/win32/bedrock.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 36c50e69..7ffb056a 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -1342,6 +1342,7 @@ namespace detail else if(brock.get_menu()) brock.remove_menu(); } + def_window_proc = true; break; case WM_SYSKEYUP: if(brock.set_keyboard_shortkey(false) == false) @@ -1358,6 +1359,7 @@ namespace detail brock.emit(event_code::key_release, msgwnd, arg, true, &context); } } + def_window_proc = true; break; case WM_KEYDOWN: if(msgwnd->flags.enabled) From e721cfa51f121aa497b9cbb4a1009229d5ee7100 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 25 Feb 2015 22:15:02 +0800 Subject: [PATCH 19/23] support of unimplemented std::regex --- source/basic_types.cpp | 141 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/source/basic_types.cpp b/source/basic_types.cpp index f8bb0823..d02d497f 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -11,7 +11,11 @@ */ #include +#if defined(USE_STD_REGEX) #include +#else +#include +#endif #include namespace nana @@ -60,10 +64,46 @@ namespace nana a_ = 1.0; } +#if !defined(USE_STD_REGEX) + std::string read_number(std::string& str, std::size_t& pos) + { + pos = str.find_first_of("0123456789", pos); + if (pos == str.npos) + return{}; + + auto end = str.find_first_not_of("0123456789", pos + 1); + //integer part + if (end == str.npos) + { + pos = end; + return str.substr(pos); + } + + if (str[end] == '.') + { + auto decimal_end = str.find_first_not_of("0123456789", end + 1); + if ((decimal_end == str.npos) || (decimal_end == end + 1)) //Because of missing % + return{}; + + end = decimal_end; + } + + auto ch = str[end]; + if (ch == '%' || ch == ' ' || ch == ',' || ch == ')') + { + auto start = pos; + pos = end + (ch == '%' ? 1 : 0); + return str.substr(start, pos - start); + } + return{}; + } +#endif + //Initializes the color with a CSS-like string //contributor: BigDave(mortis2007 at hotmail co uk) //date: February 3, 2015 //maintainor: Jinhao, extended the support of CSS-spec + color::color(std::string css_color) : a_(1.0) { @@ -135,6 +175,7 @@ namespace nana has_alpha = true; } +#if defined(USE_STD_REGEX) std::regex pat; std::regex_iterator i, end; auto type_name = css_color.substr(pos, 3); @@ -222,6 +263,106 @@ namespace nana throw std::invalid_argument(excpt_what); //invalid alpha value a_ = ::nana::stod(i->str()); } +#else + auto type_name = css_color.substr(pos, 3); + pos = css_color.find_first_not_of(' ', type_end); + if (pos == css_color.npos || css_color[pos] != '(') + throw std::invalid_argument(excpt_what); + + auto str = read_number(css_color, ++pos); + if (str.empty()) + throw std::invalid_argument(excpt_what); + + if ("rgb" == type_name) + { + std::vector rgb; + + rgb.emplace_back(std::move(str)); + + const bool is_real = (rgb.back().back() == '%'); + + for (int i = 0; i < 2; ++i) + { + pos = css_color.find_first_not_of(' ', pos); + if (pos == css_color.npos || css_color[pos] != ',') + throw std::invalid_argument(excpt_what); + + str = read_number(css_color, ++pos); + if (str.empty()) + throw std::invalid_argument(excpt_what); + + rgb.emplace_back(std::move(str)); + if (rgb.size() == 3) + break; + } + + if (rgb.size() != 3) + throw std::invalid_argument(excpt_what); + + if (is_real) + { + auto pr = ::nana::stod(rgb[0].substr(0, rgb[0].size() - 1)); + r_ = (pr > 100 ? 255.0 : 2.55 * pr); + + pr = ::nana::stod(rgb[1].substr(0, rgb[1].size() - 1)); + g_ = (pr > 100 ? 255.0 : 2.55 * pr); + + pr = ::nana::stod(rgb[2].substr(0, rgb[2].size() - 1)); + b_ = (pr > 100 ? 255.0 : 2.55 * pr); + } + else + { + r_ = ::nana::stod(rgb[0]); + if (r_ > 255.0) r_ = 255; + + g_ = ::nana::stod(rgb[1]); + if (g_ > 255.0) g_ = 255; + + b_ = ::nana::stod(rgb[2]); + if (b_ > 255.0) b_ = 255; + } + } + else if ("hsl" == type_name) + { + if (str.back() == '%') + throw std::invalid_argument(excpt_what); + + auto h = ::nana::stod(str); + + pos = css_color.find_first_not_of(' ', pos); + if (pos == css_color.npos || css_color[pos] != ',') + throw std::invalid_argument(excpt_what); + + str = read_number(css_color, ++pos); + if (str.empty() || str.back() != '%') + throw std::invalid_argument(excpt_what); + + auto s = ::nana::stod(str.substr(0, str.size() - 1)); + + pos = css_color.find_first_not_of(' ', pos); + if (pos == css_color.npos || css_color[pos] != ',') + throw std::invalid_argument(excpt_what); + + str = read_number(css_color, ++pos); + if (str.empty() || str.back() != '%') + throw std::invalid_argument(excpt_what); + + auto l = ::nana::stod(str.substr(0, str.size() - 1)); + + from_hsl(h, s / 100, l / 100); + } + else + throw std::invalid_argument(excpt_what); //invalid color type + + if (has_alpha) + { + str = read_number(css_color, ++pos); + if (str.empty() || str.back() == '%') + throw std::invalid_argument(excpt_what); //invalid alpha value + + a_ = ::nana::stod(str); + } +#endif } color& color::from_rgb(unsigned red, unsigned green, unsigned blue) From d3d46705f32334af171c2778a424a6efbfd64d55 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 26 Feb 2015 00:37:49 +0800 Subject: [PATCH 20/23] stop intercepting the WM_SYSCHAR keys --- source/gui/detail/win32/bedrock.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 7ffb056a..9e41c349 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -1322,6 +1322,7 @@ namespace detail arg.ignore = false; brock.emit(event_code::shortkey, msgwnd, arg, true, &context); } + def_window_proc = true; break; case WM_SYSKEYDOWN: if(brock.whether_keyboard_shortkey() == false) From 9fbe14e2debeeac9a57f0a89c3a6496c3bf97c88 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 26 Feb 2015 02:35:19 +0800 Subject: [PATCH 21/23] code reviews --- include/nana/deploy.hpp | 71 +++++-- include/nana/gui/widgets/listbox.hpp | 1 - source/basic_types.cpp | 22 +- source/deploy.cpp | 301 ++++++++++++++++++++------- source/gui/msgbox.cpp | 16 +- source/gui/widgets/date_chooser.cpp | 4 +- source/gui/widgets/listbox.cpp | 102 +++------ source/gui/widgets/spinbox.cpp | 6 +- source/gui/widgets/textbox.cpp | 4 +- source/internationalization.cpp | 2 +- 10 files changed, 329 insertions(+), 200 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index e59e0d85..0862a7a3 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -21,6 +21,56 @@ #undef NANA_WINDOWS #endif +//Implement workarounds for MinGW +#if defined(NANA_MINGW) +namespace std +{ + //Workaround for no implemenation of std::stoi in MinGW. + int stoi(const std::string&, std::size_t * pos = nullptr, int base = 10); + int stoi(const std::wstring&, std::size_t* pos = nullptr, int base = 10); + + //Workaround for no implemenation of std::stof in MinGW. + float stof(const std::string&, std::size_t * pos = nullptr); + float stof(const std::wstring&, std::size_t* pos = nullptr); + + //Workaround for no implemenation of std::stod in MinGW. + double stod(const std::string&, std::size_t * pos = nullptr); + double stod(const std::wstring&, std::size_t* pos = nullptr); + + //Workaround for no implemenation of std::stold in MinGW. + long double stold(const std::string&, std::size_t * pos = nullptr); + long double stold(const std::wstring&, std::size_t* pos = nullptr); + + //Workaround for no implemenation of std::stol in MinGW. + long stol(const std::string&, std::size_t* pos = nullptr, int base = 10); + long stol(const std::wstring&, std::size_t* pos = nullptr, int base = 10); + + //Workaround for no implemenation of std::stoll in MinGW. + long long stoll(const std::string&, std::size_t* pos = nullptr, int base = 10); + long long stoll(const std::wstring&, std::size_t* pos = nullptr, int base = 10); + + //Workaround for no implemenation of std::stoul in MinGW. + unsigned long stoul(const std::string&, std::size_t* pos = nullptr, int base = 10); + unsigned long stoul(const std::wstring&, std::size_t* pos = nullptr, int base = 10); + + //Workaround for no implemenation of std::stoull in MinGW. + unsigned long long stoull(const std::string&, std::size_t* pos = nullptr, int base = 10); + unsigned long long stoull(const std::wstring&, std::size_t* pos = nullptr, int base = 10); + + //Workaround for no implemenation of std::to_wstring in MinGW. + std::wstring to_wstring(long double); + std::wstring to_wstring(double); + std::wstring to_wstring(unsigned); + std::wstring to_wstring(int); + std::wstring to_wstring(long); + std::wstring to_wstring(unsigned long); + std::wstring to_wstring(long long); + std::wstring to_wstring(unsigned long long); + std::wstring to_wstring(float); +} +#endif + + #ifndef NANA_UNICODE namespace nana { @@ -40,28 +90,7 @@ namespace nana { std::size_t strlen(const char_t* str); - double strtod(const char_t* str, char_t** endptr); char_t* strcpy(char_t* dest, const char_t* source); - - //Workaround for no implemenation of std::stoi in MinGW. - int stoi(const std::string&, std::size_t * pos = nullptr, int base = 10); - int stoi(const std::wstring&, std::size_t* pos = nullptr, int base = 10); - - //Workaround for no implemenation of std::stod in MinGW. - double stod(const std::string&, std::size_t * pos = nullptr); - double stod(const std::wstring&, std::size_t* pos = nullptr); - - //Workaround for no implemenation of std::to_wstring in MinGW. - std::wstring to_wstring(long double); - std::wstring to_wstring(double); - std::wstring to_wstring(unsigned); - std::wstring to_wstring(int); - std::wstring to_wstring(long); - std::wstring to_wstring(unsigned long); - std::wstring to_wstring(long long); - std::wstring to_wstring(unsigned long long); - std::wstring to_wstring(float); - } #if defined(NANA_WINDOWS) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 8274d3e3..1bc087be 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -558,7 +558,6 @@ By \a clicking on a header the list get \a reordered, first up, and then down al private: drawerbase::listbox::essence_t & _m_ess() const; nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const; - size_type _m_headers() const; drawerbase::listbox::category_t* _m_at_key(std::shared_ptr); void _m_ease_key(nana::detail::key_interface*); }; diff --git a/source/basic_types.cpp b/source/basic_types.cpp index d02d497f..b49dc0bb 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -125,7 +125,7 @@ namespace nana if ((endpos - pos != 4) && (endpos - pos != 7)) throw std::invalid_argument(excpt_what); - auto n = ::nana::stoi(css_color.substr(pos + 1, endpos - pos - 1), nullptr, 16); + auto n = std::stoi(css_color.substr(pos + 1, endpos - pos - 1), nullptr, 16); if (endpos - pos == 4) { @@ -301,24 +301,24 @@ namespace nana if (is_real) { - auto pr = ::nana::stod(rgb[0].substr(0, rgb[0].size() - 1)); + auto pr = std::stod(rgb[0].substr(0, rgb[0].size() - 1)); r_ = (pr > 100 ? 255.0 : 2.55 * pr); - pr = ::nana::stod(rgb[1].substr(0, rgb[1].size() - 1)); + pr = std::stod(rgb[1].substr(0, rgb[1].size() - 1)); g_ = (pr > 100 ? 255.0 : 2.55 * pr); - pr = ::nana::stod(rgb[2].substr(0, rgb[2].size() - 1)); + pr = std::stod(rgb[2].substr(0, rgb[2].size() - 1)); b_ = (pr > 100 ? 255.0 : 2.55 * pr); } else { - r_ = ::nana::stod(rgb[0]); + r_ = std::stod(rgb[0]); if (r_ > 255.0) r_ = 255; - g_ = ::nana::stod(rgb[1]); + g_ = std::stod(rgb[1]); if (g_ > 255.0) g_ = 255; - b_ = ::nana::stod(rgb[2]); + b_ = std::stod(rgb[2]); if (b_ > 255.0) b_ = 255; } } @@ -327,7 +327,7 @@ namespace nana if (str.back() == '%') throw std::invalid_argument(excpt_what); - auto h = ::nana::stod(str); + auto h = std::stod(str); pos = css_color.find_first_not_of(' ', pos); if (pos == css_color.npos || css_color[pos] != ',') @@ -337,7 +337,7 @@ namespace nana if (str.empty() || str.back() != '%') throw std::invalid_argument(excpt_what); - auto s = ::nana::stod(str.substr(0, str.size() - 1)); + auto s = std::stod(str.substr(0, str.size() - 1)); pos = css_color.find_first_not_of(' ', pos); if (pos == css_color.npos || css_color[pos] != ',') @@ -347,7 +347,7 @@ namespace nana if (str.empty() || str.back() != '%') throw std::invalid_argument(excpt_what); - auto l = ::nana::stod(str.substr(0, str.size() - 1)); + auto l = std::stod(str.substr(0, str.size() - 1)); from_hsl(h, s / 100, l / 100); } @@ -360,7 +360,7 @@ namespace nana if (str.empty() || str.back() == '%') throw std::invalid_argument(excpt_what); //invalid alpha value - a_ = ::nana::stod(str); + a_ = std::stod(str); } #endif } diff --git a/source/deploy.cpp b/source/deploy.cpp index e9e0d5d2..b2d053f4 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -15,6 +15,7 @@ #include #include #include + #if defined(NANA_WINDOWS) #include #elif defined(NANA_LINUX) @@ -22,38 +23,12 @@ #include PLATFORM_SPEC_HPP #endif -namespace nana +#if defined(NANA_MINGW) +#include +namespace std { - std::size_t strlen(const char_t* str) - { -#if defined(NANA_UNICODE) - return ::wcslen(str); -#else - return ::strlen(str); -#endif - } - - double strtod(const char_t* str, char_t** endptr) - { -#if defined(NANA_UNICODE) - return ::wcstod(str, endptr); -#else - return ::strtod(str, endptr); -#endif - } - - char_t* strcpy(char_t* dest, const char_t* source) - { -#if defined(NANA_UNICODE) - return ::wcscpy(dest, source); -#else - return ::strcpy(dest, source); -#endif - } - int stoi(const std::string& str, std::size_t * pos, int base) { -#if defined(NANA_MINGW) auto sptr = str.c_str(); char *end; errno = 0; @@ -67,14 +42,10 @@ namespace nana if (pos) *pos = (std::size_t)(end - sptr); return ((int)result); -#else - return std::stoi(str, pos, base); -#endif } int stoi(const std::wstring& str, std::size_t* pos, int base) { -#if defined(NANA_MINGW) auto sptr = str.data(); wchar_t *end; errno = 0; @@ -88,14 +59,42 @@ namespace nana if (pos) *pos = (std::size_t)(end - sptr); return ((int)result); -#else - return std::stoi(str, pos, base); -#endif + } + + float stof(const std::string& str, std::size_t * pos) + { + auto *ptr = str.data(); + errno = 0; + char *end; + auto result = std::strtof(ptr, &end); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stof argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + float stof(const std::wstring& str, std::size_t* pos) + { + auto *ptr = str.data(); + errno = 0; + wchar_t *end; + auto result = std::wcstof(ptr, &end); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stof argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; } double stod(const std::string& str, std::size_t * pos) { -#ifdef NANA_MINGW auto *ptr = str.data(); errno = 0; char *end; @@ -108,14 +107,10 @@ namespace nana if (pos) *pos = (std::size_t)(end - ptr); return result; -#else - return std::stod(str, pos); -#endif } double stod(const std::wstring& str, std::size_t* pos) { -#ifdef NANA_MINGW auto *ptr = str.data(); errno = 0; wchar_t *end; @@ -128,110 +123,258 @@ namespace nana if (pos) *pos = (std::size_t)(end - ptr); return result; -#else - return std::stod(str, pos); -#endif + } + + long double stold(const std::string& str, std::size_t * pos) + { + auto *ptr = str.data(); + errno = 0; + char *end; + auto result = std::strtold(ptr, &end); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stold argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long double stold(const std::wstring& str, std::size_t* pos) + { + auto *ptr = str.data(); + errno = 0; + wchar_t *end; + auto result = std::wcstold(ptr, &end); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stold argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long stol(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char *end; + auto result = std::strtol(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stol argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long stol(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t *end; + auto result = std::wcstol(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stol argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + //Workaround for no implemenation of std::stoll in MinGW. + long long stoll(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char* end; + auto result = std::strtoll(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoll argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long long stoll(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t* end; + auto result = std::wcstoll(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoll argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + unsigned long long stoull(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char* end; + auto result = std::strtoull(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoull argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + unsigned long long stoull(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t* end; + auto result = std::wcstoull(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoull argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + //Workaround for no implemenation of std::stoul in MinGW. + unsigned long stoul(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char* end; + auto result = std::strtoul(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoul argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + unsigned long stoul(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t* end; + auto result = std::wcstoul(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoul argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; } std::wstring to_wstring(double v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(long double v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(unsigned v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(int v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(long v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(unsigned long v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(long long v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(unsigned long long v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); -#else - return std::to_wstring(v); -#endif } std::wstring to_wstring(float v) { -#ifdef NANA_MINGW std::wstringstream ss; ss << v; return ss.str(); + } +} +#endif + +namespace nana +{ + std::size_t strlen(const char_t* str) + { +#if defined(NANA_UNICODE) + return ::wcslen(str); #else - return std::to_wstring(v); -#endif + return ::strlen(str); +#endif } + char_t* strcpy(char_t* dest, const char_t* source) + { +#if defined(NANA_UNICODE) + return ::wcscpy(dest, source); +#else + return ::strcpy(dest, source); +#endif + } +} + +namespace nana +{ bool is_incomplete(const nana::string& str, unsigned pos) { #ifndef NANA_UNICODE diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 7f71376b..e43a5ee7 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -701,12 +701,12 @@ namespace nana //get the longest value int longest = (std::abs((impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(impl->last < 0 ? impl->last * 10 : impl->last) ? impl->last : impl->begin); paint::graphics graph{ ::nana::size{ 10, 10 } }; - auto value_px = graph.text_extent_size(::nana::to_wstring(longest)).width + 34; + auto value_px = graph.text_extent_size(std::to_wstring(longest)).width + 34; impl->spinbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, value_px, 0 }); impl->spinbox.range(impl->begin, impl->last, impl->step); - impl->spinbox.value(::nana::to_wstring(impl->value)); + impl->spinbox.value(std::to_wstring(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -779,12 +779,12 @@ namespace nana //get the longest value auto longest = (std::abs((impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(impl->last < 0 ? impl->last * 10 : impl->last) ? impl->last : impl->begin); paint::graphics graph{ ::nana::size{ 10, 10 } }; - auto value_px = graph.text_extent_size(::nana::to_wstring(longest)).width + 34; + auto value_px = graph.text_extent_size(std::to_wstring(longest)).width + 34; impl->spinbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, value_px, 0 }); impl->spinbox.range(impl->begin, impl->last, impl->step); - impl->spinbox.value(::nana::to_wstring(impl->value)); + impl->spinbox.value(std::to_wstring(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -947,7 +947,7 @@ namespace nana ::nana::string inputbox::date::value() const { - return nana::to_wstring(impl_->month) + L'-' + nana::to_wstring(impl_->day) + L", " + nana::to_wstring(impl_->year); + return std::to_wstring(impl_->month) + L'-' + std::to_wstring(impl_->day) + L", " + std::to_wstring(impl_->year); } int inputbox::date::year() const @@ -1008,8 +1008,8 @@ namespace nana impl->wdg_month.option(today.month - 1); - impl->wdg_day.value(::nana::to_wstring(today.day)); - impl->wdg_year.value(::nana::to_wstring(today.year)); + impl->wdg_day.value(std::to_wstring(today.day)); + impl->wdg_year.value(std::to_wstring(today.year)); impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg) { @@ -1050,7 +1050,7 @@ namespace nana if (day > days) day = days; - impl->wdg_day.value(::nana::to_wstring(day)); + impl->wdg_day.value(std::to_wstring(day)); }; impl->wdg_year.events().text_changed.connect_unignorable(make_days); diff --git a/source/gui/widgets/date_chooser.cpp b/source/gui/widgets/date_chooser.cpp index 16b493c3..3f1818ca 100644 --- a/source/gui/widgets/date_chooser.cpp +++ b/source/gui/widgets/date_chooser.cpp @@ -133,7 +133,7 @@ namespace nana str = ::nana::internationalization()(monthstr[chmonth_.month - 1]); str += STR(" "); } - str += ::nana::to_wstring(chmonth_.year); + str += std::to_wstring(chmonth_.year); nana::size txt_s = graph.text_extent_size(str); @@ -203,7 +203,7 @@ namespace nana void trigger::_m_draw_pos(drawing_basis & dbasis, graph_reference graph, int x, int y, int number, bool primary, bool sel) { - _m_draw_pos(dbasis, graph, x, y, ::nana::to_wstring(number), primary, sel); + _m_draw_pos(dbasis, graph, x, y, std::to_wstring(number), primary, sel); } void trigger::_m_draw_ex_days(drawing_basis & dbasis, graph_reference graph, int begx, int begy, bool before) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8d3ab0c4..7d1bec1b 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include namespace nana @@ -87,66 +86,66 @@ namespace nana } oresolver& oresolver::operator<<(short n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned short n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(int n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned int n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(long n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned long n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(long long n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(unsigned long long n) { - cells_.emplace_back(::nana::to_wstring(n)); + cells_.emplace_back(std::to_wstring(n)); return *this; } oresolver& oresolver::operator<<(float f) { - cells_.emplace_back(::nana::to_wstring(f)); + cells_.emplace_back(std::to_wstring(f)); return *this; } oresolver& oresolver::operator<<(double f) { - cells_.emplace_back(::nana::to_wstring(f)); + cells_.emplace_back(std::to_wstring(f)); return *this; } oresolver& oresolver::operator<<(long double f) { - cells_.emplace_back(::nana::to_wstring(f)); + cells_.emplace_back(std::to_wstring(f)); return *this; } @@ -201,117 +200,82 @@ namespace nana iresolver& iresolver::operator>>(bool& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = (std::stoi(cells_[pos_++].text) == 0); return *this; } iresolver& iresolver::operator>>(short& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stoi(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(unsigned short& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = static_cast(std::stoul(cells_[pos_++].text)); return *this; } iresolver& iresolver::operator>>(int& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stoi(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(unsigned int& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stoul(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(long& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stol(cells_[pos_++].text); return *this; } + iresolver& iresolver::operator>>(unsigned long& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stoul(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(long long& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stoll(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(unsigned long long& n) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> n; - } + n = std::stoull(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(float& f) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> f; - } + f = std::stof(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(double& f) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> f; - } + f = std::stod(cells_[pos_++].text); return *this; } iresolver& iresolver::operator>>(long double& f) { if (pos_ < cells_.size()) - { - std::wstringstream ss(cells_[pos_++].text); - ss >> f; - } + f = std::stold(cells_[pos_++].text); return *this; } @@ -1183,8 +1147,9 @@ namespace nana } } - void item_checked(selection& vec) const + selection item_checked() const { + selection vec; index_pair id; for(auto & cat : list_) { @@ -1197,6 +1162,7 @@ namespace nana } ++id.cat; } + return vec; } void select_range(index_pair fr, index_pair to, bool sel) @@ -2595,7 +2561,7 @@ namespace nana graph->string({ x + 20, y + txtoff }, categ.text, txt_color); - ::nana::string str = L'(' + ::nana::to_wstring(categ.items.size()) + L')'; + ::nana::string str = L'(' + std::to_wstring(categ.items.size()) + L')'; unsigned str_w = graph->text_extent_size(str).width; @@ -3699,8 +3665,7 @@ namespace nana auto & ess = _m_ess(); if (ess.lister.insert(pos, std::move(text))) { - window wd = handle(); - if (false == API::empty_window(wd)) + if (! empty()) { auto & item = ess.lister.at(pos); item.bgcolor = bgcolor(); @@ -3722,9 +3687,7 @@ namespace nana auto listbox::checked() const -> selection { - selection s; - _m_ess().lister.item_checked(s); - return std::move(s); + return _m_ess().lister.item_checked(); } void listbox::clear(size_type cat) @@ -3891,11 +3854,6 @@ namespace nana return _m_ess().lister.anyobj(index_pair{cat, index}, allocate_if_empty); } - auto listbox::_m_headers() const -> size_type - { - return _m_ess().header.cont().size(); - } - drawerbase::listbox::category_t* listbox::_m_at_key(std::shared_ptr ptr) { auto & ess = _m_ess(); diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index a662d294..c99367ae 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -73,7 +73,7 @@ namespace nana std::wstring value() const override { - return ::nana::to_wstring(value_); + return std::to_wstring(value_); } bool value(const std::wstring& value_str, bool & diff) override @@ -663,12 +663,12 @@ namespace nana int spinbox::to_int() const { - return ::nana::stoi(value()); + return std::stoi(value()); } double spinbox::to_double() const { - return ::nana::stod(value()); + return std::stod(value()); } void spinbox::modifier(std::wstring prefix, std::wstring suffix) diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index ffbacb05..cd30dafe 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -456,13 +456,13 @@ namespace drawerbase { textbox& textbox::from(int n) { - _m_caption(::nana::to_wstring(n)); + _m_caption(std::to_wstring(n)); return *this; } textbox& textbox::from(double d) { - _m_caption(::nana::to_wstring(d)); + _m_caption(std::to_wstring(d)); return *this; } diff --git a/source/internationalization.cpp b/source/internationalization.cpp index 30908ce7..fd8a9b9c 100644 --- a/source/internationalization.cpp +++ b/source/internationalization.cpp @@ -343,7 +343,7 @@ namespace nana erase_n = str.size() - offset; //If there is not a parameter for %argNNN, the %argNNN will be erased. - std::size_t arg = static_cast(::nana::stoi(str.substr(offset + 4, arg_n))); + std::size_t arg = static_cast(std::stoi(str.substr(offset + 4, arg_n))); if (arg_strs && arg < arg_strs->size()) str.replace(offset, erase_n, (*arg_strs)[arg]); From 42af0010201c982a7625d49af94548fe949f5326 Mon Sep 17 00:00:00 2001 From: Ryan Gonzalez Date: Thu, 26 Feb 2015 19:00:03 -0600 Subject: [PATCH 22/23] Fix Linux builds --- include/nana/paint/detail/image_bmp.hpp | 10 +++++----- source/gui/layout_utility.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/nana/paint/detail/image_bmp.hpp b/include/nana/paint/detail/image_bmp.hpp index e7b27c35..f5493881 100644 --- a/include/nana/paint/detail/image_bmp.hpp +++ b/include/nana/paint/detail/image_bmp.hpp @@ -82,7 +82,7 @@ namespace nana{ namespace paint return false; std::unique_ptr buffer(new char[static_cast(size)]); - + ifs.read(buffer.get(), size); if(size == ifs.gcount()) { @@ -94,7 +94,7 @@ namespace nana{ namespace paint //Bitmap file is 4byte-aligned for each line. std::size_t bytes_per_line; - const std::size_t height_pixels = abs(info->bmiHeader.biHeight); + const std::size_t height_pixels = std::abs(info->bmiHeader.biHeight); if(0 == info->bmiHeader.biSizeImage) bytes_per_line = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) >> 3); else @@ -204,7 +204,7 @@ namespace nana{ namespace paint d = dpend; s -= bytes_per_line; } - } + } } else if(2 == info->bmiHeader.biBitCount) { @@ -257,7 +257,7 @@ namespace nana{ namespace paint d = dpend; s -= bytes_per_line; } - } + } } else if(1 == info->bmiHeader.biBitCount) { @@ -310,7 +310,7 @@ namespace nana{ namespace paint d = dpend; s -= bytes_per_line; } - } + } } } } diff --git a/source/gui/layout_utility.cpp b/source/gui/layout_utility.cpp index 7f72db0c..d59e89c3 100644 --- a/source/gui/layout_utility.cpp +++ b/source/gui/layout_utility.cpp @@ -18,11 +18,11 @@ namespace nana //overlap test if overlaped between r1 and r2 bool overlap(const rectangle& r1, const rectangle& r2) { - if (r1.y + long long(r1.height) <= r2.y) return false; - if(r1.y >= r2.y + long long(r2.height)) return false; + if (r1.y + (long long)(r1.height) <= r2.y) return false; + if(r1.y >= r2.y + (long long)(r2.height)) return false; - if(r1.x + long long(r1.width) <= r2.x) return false; - if(r1.x >= r2.x + long long(r2.width)) return false; + if(r1.x + (long long)(r1.width) <= r2.x) return false; + if(r1.x >= r2.x + (long long)(r2.width)) return false; return true; } @@ -255,7 +255,7 @@ namespace nana ref_s.width = static_cast(ref_s.height * rate_input); else if (rate_input > rate_ref) ref_s.height = static_cast(ref_s.width / rate_input); - + return ref_s; } From 0df28e13e14513c04b31091a06fb418d3f7e4aa9 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 1 Mar 2015 22:40:16 +0800 Subject: [PATCH 23/23] minor revision --- include/nana/gui/detail/window_manager.hpp | 6 +++--- include/nana/gui/widgets/form.hpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index 2e07ac31..37c9c150 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -118,9 +118,9 @@ namespace detail bool available(core_window_t *, core_window_t*); bool available(native_window_type); - core_window_t* create_root(core_window_t* owner, bool nested, rectangle, const appearance&, widget*); - core_window_t* create_widget(core_window_t* parent, const rectangle&, bool is_lite, widget*); - core_window_t* create_frame(core_window_t* parent, const rectangle&, widget*); + core_window_t* create_root(core_window_t*, bool nested, rectangle, const appearance&, widget*); + core_window_t* create_widget(core_window_t*, const rectangle&, bool is_lite, widget*); + core_window_t* create_frame(core_window_t*, const rectangle&, widget*); bool insert_frame(core_window_t* frame, native_window); bool insert_frame(core_window_t* frame, core_window_t*); void close(core_window_t*); diff --git a/include/nana/gui/widgets/form.hpp b/include/nana/gui/widgets/form.hpp index 0f64c54a..79ec3f6b 100644 --- a/include/nana/gui/widgets/form.hpp +++ b/include/nana/gui/widgets/form.hpp @@ -1,7 +1,7 @@ /* * A Form Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -37,7 +37,7 @@ namespace nana class form: public widget_object { public: - typedef ::nana::appear appear; + using appear = ::nana::appear; /// Creates a window at the point and size specified by rect, and with the specified appearance. Creates a form owned by the desktop. form(const rectangle& = API::make_center(300, 200), const appearance& = {}); //Default constructor @@ -53,7 +53,7 @@ namespace nana class nested_form : public widget_object { public: - typedef ::nana::appear appear; + using appear = ::nana::appear; nested_form(const form&, const rectangle& = {}, const appearance& = {}); nested_form(const nested_form&, const rectangle& = {}, const appearance& = {});