diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..87593cf6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,127 @@ +# CMake configuration for Nana +# Author: Andrew Kornilov(https://github.com/ierofant) +# Contributor: +# Robert Hauck - Enable support for PNG/Freetype + +project(nana) +cmake_minimum_required(VERSION 2.8) + + +#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) + include_directories( ${FREETYPE_INCLUDE_DIRS}) + endif() +endif() + +option(NANA_ENABLE_PNG "Enable the use of PNG" ON) +if(NANA_ENABLE_PNG) + add_definitions(-DNANA_ENABLE_PNG) + + 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 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) + +if(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") +endif(CMAKE_COMPILER_IS_GNUCXX) + +include_directories(${NANA_INCLUDE_DIR}) +aux_source_directory(${NANA_SOURCE_DIR} NANA_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/detail NANA_DETAIL_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/filesystem NANA_FILESYSTEM_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/audio NANA_AUDIO_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/audio/detail NANA_AUDIO_DETAIL_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/gui NANA_GUI_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/gui/detail NANA_GUI_DETAIL_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/gui/widgets NANA_GUI_WIDGETS_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/gui/widgets/skeletons NANA_GUI_WIDGETS_SKELETONS_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/paint NANA_PAINT_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/paint/detail NANA_PAINT_DETAIL_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/system NANA_SYSTEM_SOURCE) +aux_source_directory(${NANA_SOURCE_DIR}/threads NANA_THREADS_SOURCE) + +add_library(${PROJECT_NAME} ${NANA_SOURCE} + ${NANA_DETAIL_SOURCE} + ${NANA_FILESYSTEM_SOURCE} + ${NANA_AUDIO_SOURCE} + ${NANA_AUDIO_DETAIL_SOURCE} + ${NANA_GUI_SOURCE} + ${NANA_GUI_DETAIL_SOURCE} + ${NANA_GUI_WIDGETS_SOURCE} + ${NANA_GUI_WIDGETS_SKELETONS_SOURCE} + ${NANA_PAINT_SOURCE} + ${NANA_PAINT_DETAIL_SOURCE} + ${NANA_SYSTEM_SOURCE} + ${NANA_THREADS_SOURCE}) + + +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) \ No newline at end of file diff --git a/build/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt deleted file mode 100644 index e04ee417..00000000 --- a/build/cmake/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# CMake configuration for Nana -# Author: ierofant(https://github.com/ierofant) - -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}) - -set(NANA_SOURCE_DIR ${CMAKE_SOURCE_DIR}/source) -set(NANA_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) - -if(CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") -endif(CMAKE_COMPILER_IS_GNUCXX) - -include_directories(${NANA_INCLUDE_DIR}) -aux_source_directory(${NANA_SOURCE_DIR} NANA_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/detail NANA_DETAIL_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/filesystem NANA_FILESYSTEM_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/audio NANA_AUDIO_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/audio/detail NANA_AUDIO_DETAIL_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/gui NANA_GUI_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/gui/detail NANA_GUI_DETAIL_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/gui/widgets NANA_GUI_WIDGETS_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/gui/widgets/skeletons NANA_GUI_WIDGETS_SKELETONS_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/paint NANA_PAINT_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/paint/detail NANA_PAINT_DETAIL_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/system NANA_SYSTEM_SOURCE) -aux_source_directory(${NANA_SOURCE_DIR}/threads NANA_THREADS_SOURCE) - -add_library(${PROJECT_NAME} ${NANA_SOURCE} - ${NANA_DETAIL_SOURCE} - ${NANA_FILESYSTEM_SOURCE} - ${NANA_AUDIO_SOURCE} - ${NANA_AUDIO_DETAIL_SOURCE} - ${NANA_GUI_SOURCE} - ${NANA_GUI_DETAIL_SOURCE} - ${NANA_GUI_WIDGETS_SOURCE} - ${NANA_GUI_WIDGETS_SKELETONS_SOURCE} - ${NANA_PAINT_SOURCE} - ${NANA_PAINT_DETAIL_SOURCE} - ${NANA_SYSTEM_SOURCE} - ${NANA_THREADS_SOURCE}) - - -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) -install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) \ No newline at end of file diff --git a/build/cmake/config.hpp b/build/cmake/config.hpp new file mode 100644 index 00000000..08527a55 --- /dev/null +++ b/build/cmake/config.hpp @@ -0,0 +1,18 @@ +/* + * 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 + +//All defines have been moved to the CMakelists.txt in the root directory. + +#endif //NANA_CONFIG_HPP diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index d417d06d..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,16 +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); } #if defined(NANA_WINDOWS) 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/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/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/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/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index fe6ae1ff..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 { @@ -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_; }; @@ -149,12 +147,16 @@ 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 const ::nana::string& label() const override; window create(window, unsigned label_px) override; - unsigned fixed_pixels() const override; private: std::unique_ptr impl_; }; @@ -172,7 +174,24 @@ namespace nana int year() const; int month() const; //[1, 12] int day() const; //[1, 31] + 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_; + }; + + class path + : public abstract_content + { + struct implement; + public: + path(::nana::string label, const ::nana::filebox&); + ~path(); + + ::nana::string value() const; private: //Implementation of abstract_content const ::nana::string& label() const override; @@ -183,6 +202,9 @@ namespace nana inputbox(window, ::nana::string description, ::nana::string title = ::nana::string()); + 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) { @@ -225,6 +247,8 @@ namespace nana ::nana::string description_; ::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/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& = {}); 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/include/nana/gui/widgets/picture.hpp b/include/nana/gui/widgets/picture.hpp index 5c9b5f97..33c67552 100644 --- a/include/nana/gui/widgets/picture.hpp +++ b/include/nana/gui/widgets/picture.hpp @@ -17,62 +17,52 @@ namespace nana { - namespace xpicture + class picture; + + 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_; + friend class ::nana::picture; + public: + drawer(); + ~drawer(); + void attached(widget_reference, graph_reference) override; + private: + void refresh(graph_reference) override; + void _m_draw_background(); + private: + 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() = default; 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, const rectangle& valid_area = {}); - /// 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. - ); + /// 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/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/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/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/basic_types.cpp b/source/basic_types.cpp index f8bb0823..b49dc0bb 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) { @@ -85,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) { @@ -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 = std::stod(rgb[0].substr(0, rgb[0].size() - 1)); + r_ = (pr > 100 ? 255.0 : 2.55 * pr); + + pr = std::stod(rgb[1].substr(0, rgb[1].size() - 1)); + g_ = (pr > 100 ? 255.0 : 2.55 * pr); + + pr = std::stod(rgb[2].substr(0, rgb[2].size() - 1)); + b_ = (pr > 100 ? 255.0 : 2.55 * pr); + } + else + { + r_ = std::stod(rgb[0]); + if (r_ > 255.0) r_ = 255; + + g_ = std::stod(rgb[1]); + if (g_ > 255.0) g_ = 255; + + b_ = std::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 = std::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 = std::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 = std::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_ = std::stod(str); + } +#endif } color& color::from_rgb(unsigned red, unsigned green, unsigned blue) diff --git a/source/deploy.cpp b/source/deploy.cpp index 6017edfd..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,11 +123,258 @@ namespace nana if (pos) *pos = (std::size_t)(end - ptr); return result; + } + + long double stold(const std::string& str, std::size_t * pos) + { + auto *ptr = str.data(); + errno = 0; + char *end; + auto result = std::strtold(ptr, &end); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stold argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long double stold(const std::wstring& str, std::size_t* pos) + { + auto *ptr = str.data(); + errno = 0; + wchar_t *end; + auto result = std::wcstold(ptr, &end); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stold argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long stol(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char *end; + auto result = std::strtol(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stol argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long stol(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t *end; + auto result = std::wcstol(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stol argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + //Workaround for no implemenation of std::stoll in MinGW. + long long stoll(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char* end; + auto result = std::strtoll(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoll argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + long long stoll(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t* end; + auto result = std::wcstoll(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoll argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + unsigned long long stoull(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char* end; + auto result = std::strtoull(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoull argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + unsigned long long stoull(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t* end; + auto result = std::wcstoull(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoull argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + //Workaround for no implemenation of std::stoul in MinGW. + unsigned long stoul(const std::string& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + char* end; + auto result = std::strtoul(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoul argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + unsigned long stoul(const std::wstring& str, std::size_t* pos, int base) + { + auto *ptr = str.data(); + errno = 0; + wchar_t* end; + auto result = std::wcstoul(ptr, &end, base); + + if (ptr == end) + throw std::invalid_argument("invalid stod argument"); + if (errno == ERANGE) + throw std::out_of_range("stoul argument out of range"); + if (pos) + *pos = (std::size_t)(end - ptr); + return result; + } + + std::wstring to_wstring(double v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(long double v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(unsigned v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(int v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(long v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(unsigned long v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(long long v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(unsigned long long v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } + + std::wstring to_wstring(float v) + { + std::wstringstream ss; + ss << v; + return ss.str(); + } +} +#endif + +namespace nana +{ + std::size_t strlen(const char_t* str) + { +#if defined(NANA_UNICODE) + return ::wcslen(str); #else - return std::stod(str, pos); + 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/animation.cpp b/source/gui/animation.cpp index a8165470..9ed5a7ea 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 @@ -35,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 @@ -48,11 +45,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 +58,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 +304,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 +332,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 +351,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 +371,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 +433,80 @@ 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->animations.push_back(p); - return thr; + 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; + } } } 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 +552,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 +567,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 +644,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/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 36c50e69..7820227c 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; @@ -1322,6 +1320,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) @@ -1342,6 +1341,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 +1358,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) 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/layout_utility.cpp b/source/gui/layout_utility.cpp index a190b714..d59e89c3 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); @@ -241,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/msgbox.cpp b/source/gui/msgbox.cpp index a13f3c82..e43a5ee7 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], ::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); @@ -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,90 @@ 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]; + 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; + } + + if (imgs[3]) //Right + { + auto & sz = img_sz[3]; + 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; + } + + if (imgs[0]) //Top + { + auto & sz = img_sz[0]; + 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; + } + + if (imgs[1]) //Bottom + { + auto & sz = img_sz[1]; + 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; + } + + 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], valid_areas[i]); + 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 +638,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 { @@ -590,6 +676,9 @@ namespace nana int inputbox::integer::value() const { + if (!impl_->spinbox.empty()) + return impl_->spinbox.to_int(); + return impl_->value; } @@ -611,20 +700,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(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.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(std::to_wstring(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -639,11 +721,6 @@ namespace nana return impl->dock; } - - unsigned inputbox::integer::fixed_pixels() const - { - return 0; - } //end class integer @@ -677,6 +754,9 @@ namespace nana double inputbox::real::value() const { + if (!impl_->spinbox.empty()) + return impl_->spinbox.to_double(); + return impl_->value; } @@ -698,20 +778,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(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.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(std::to_wstring(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -721,23 +794,20 @@ namespace nana impl->spinbox.events().destroy.connect_unignorable([impl] { - impl->value = impl->spinbox.to_int(); + impl->value = impl->spinbox.to_double(); }); return impl->dock; } - - unsigned inputbox::real::fixed_pixels() const - { - return 0; - } //end class real //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; @@ -763,8 +833,28 @@ 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 { + if (!impl_->textbox.empty()) + return impl_->textbox.caption(); + else if (!impl_->combox.empty()) + return impl_->combox.caption(); + return impl_->value; } @@ -788,6 +878,9 @@ 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); + impl->textbox.multi_lines(false); } else { @@ -825,11 +918,6 @@ namespace nana }); return impl->dock; } - - unsigned inputbox::text::fixed_pixels() const - { - return 0; - } //end class text @@ -859,22 +947,28 @@ namespace nana ::nana::string inputbox::date::value() const { - std::wstringstream ss; - ss << impl_->month << L'-' << impl_->day << L", " << impl_->year; - return ss.str(); + return std::to_wstring(impl_->month) + L'-' + std::to_wstring(impl_->day) + L", " + std::to_wstring(impl_->year); } 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; } @@ -907,22 +1001,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(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) { @@ -962,10 +1049,8 @@ namespace nana if (day > days) day = days; - - std::wstringstream ss; - ss << day; - impl->wdg_day.value(ss.str()); + + impl->wdg_day.value(std::to_wstring(day)); }; impl->wdg_year.events().text_changed.connect_unignorable(make_days); @@ -980,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 }, @@ -987,6 +1153,20 @@ namespace nana title_(std::move(title)) {} + 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, 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) { verifier_ = std::move(verifier); @@ -995,7 +1175,6 @@ namespace nana void inputbox::_m_fetch_args(std::vector&) {} - bool inputbox::_m_open(std::vector& contents, bool modal) { std::vector each_pixels; @@ -1014,7 +1193,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_, 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/date_chooser.cpp b/source/gui/widgets/date_chooser.cpp index bb0cede5..3f1818ca 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< #include #include -#include #include namespace nana @@ -79,15 +78,6 @@ namespace nana } //end struct cell - //A workaround, MinGW does not yet provide std::to_wstring - template - 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 +86,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(std::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(std::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(std::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(std::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(std::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(std::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(std::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(std::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(std::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(std::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(std::to_wstring(f)); return *this; } @@ -221,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; } @@ -1203,8 +1147,9 @@ namespace nana } } - void item_checked(selection& vec) const + selection item_checked() const { + selection vec; index_pair id; for(auto & cat : list_) { @@ -1217,6 +1162,7 @@ namespace nana } ++id.cat; } + return vec; } void select_range(index_pair fr, index_pair to, bool sel) @@ -2373,7 +2319,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 +2483,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 +2494,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 +2518,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 +2544,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'(' + std::to_wstring(categ.items.size()) + L')'; unsigned str_w = graph->text_extent_size(str).width; @@ -2655,7 +2571,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 +2761,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 }); @@ -3749,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(); @@ -3772,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) @@ -3941,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/picture.cpp b/source/gui/widgets/picture.cpp index 7571d709..b9912cc7 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,248 +14,167 @@ #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; + 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; + }; - 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; + + auto graphsize = graph.size(); + + auto & backimg = impl_->backimg; + + if (!backimg.bground) { - _m_draw_background(); - if(backimg_.image.empty() == false) + auto valid_area = backimg.valid_area; + if (valid_area.empty()) + valid_area = backimg.image.size(); + + if (backimg.stretchable) { - nana::size imgsize = backimg_.image.size(); - nana::size gsize = graph.size(); + auto fit_size = fit_zoom({ valid_area.width, valid_area.height }, graphsize); + ::nana::point pos; - switch(backimg_.arg) + if (fit_size.width != graphsize.width) { - case nana::arrange::unknown: - backimg_.image.paste(graph, 0, 0); + 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::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); + 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 + { + color invalid_clr_for_call; + backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, graphsize, 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(){} - picture::picture(window wd, bool visible) { create(wd, rectangle(), visible); @@ -265,21 +185,91 @@ namespace nana create(wd, r, visible); } - void picture::load(const nana::paint::image& img) + void picture::load(::nana::paint::image img, const ::nana::rectangle& valid_area) { - get_drawer_trigger().load(img); - API::refresh_window(*this); + 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, valid_area); + + if (handle()) + { + 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::align(::nana::align horz, align_v vert) { - if(get_drawer_trigger().bgstyle(stretchable, arg, beg, end)) + 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) + { + 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.valid_area); + } + + backimg.bground->stretch_parts(left, top, right, bottom); + 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) { - 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; + if (handle()) + { + get_drawer_trigger().impl_->graph_ptr->set_changed(); + API::refresh_window(*this); + } } void picture::transparent(bool enabled) 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); } 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; diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 94a11715..c99367ae 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 std::to_wstring(value_); } bool value(const std::wstring& value_str, bool & diff) override @@ -665,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 fc4a7d1b..cd30dafe 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(std::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(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]); 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();