Merge branch 'develop'

This commit is contained in:
Jinhao 2015-03-01 22:45:54 +08:00
commit 70dabd9687
31 changed files with 1430 additions and 735 deletions

127
CMakeLists.txt Normal file
View File

@ -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=<nana/detail/win32/platform_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=<nana/detail/linux_X11/platform_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)

View File

@ -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)

18
build/cmake/config.hpp Normal file
View File

@ -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

View File

@ -21,6 +21,56 @@
#undef NANA_WINDOWS #undef NANA_WINDOWS
#endif #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 #ifndef NANA_UNICODE
namespace nana namespace nana
{ {
@ -40,16 +90,7 @@
namespace nana namespace nana
{ {
std::size_t strlen(const char_t* str); 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); 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) #if defined(NANA_WINDOWS)

View File

@ -1,6 +1,7 @@
/* /*
* An Animation Implementation * 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. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -27,15 +28,13 @@ namespace nana
friend class animation; friend class animation;
public: public:
/// function which builds frames. /// function which builds frames.
typedef std::function<bool(std::size_t pos, paint::graphics&, nana::size&)> framebuilder; using framebuilder = std::function<bool(std::size_t pos, paint::graphics&, nana::size&)>;
struct impl; struct impl;
public: public:
frameset(); frameset();
void push_back(const paint::image&); ///< Inserts frames at the end. void push_back(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(framebuilder&& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates.
private: private:
std::shared_ptr<impl> impl_; std::shared_ptr<impl> impl_;
}; };
@ -51,9 +50,9 @@ namespace nana
struct impl; struct impl;
class performance_manager; class performance_manager;
public: 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) void branch(const std::string& name, const frameset& frms)
{ {
@ -75,6 +74,9 @@ namespace nana
void pause(); void pause();
void output(window wd, const nana::point& pos); void output(window wd, const nana::point& pos);
void fps(std::size_t n);
std::size_t fps() const;
private: private:
impl * impl_; impl * impl_;
}; };

View File

@ -118,9 +118,9 @@ namespace detail
bool available(core_window_t *, core_window_t*); bool available(core_window_t *, core_window_t*);
bool available(native_window_type); bool available(native_window_type);
core_window_t* create_root(core_window_t* owner, bool nested, rectangle, const appearance&, widget*); core_window_t* create_root(core_window_t*, 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_widget(core_window_t*, const rectangle&, bool is_lite, widget*);
core_window_t* create_frame(core_window_t* parent, const rectangle&, 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, native_window);
bool insert_frame(core_window_t* frame, core_window_t*); bool insert_frame(core_window_t* frame, core_window_t*);
void close(core_window_t*); void close(core_window_t*);

View File

@ -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 #ifndef NANA_GUI_FILEBOX_HPP
#define NANA_GUI_FILEBOX_HPP #define NANA_GUI_FILEBOX_HPP
#include <nana/gui/wvl.hpp> #include <nana/gui/basis.hpp>
#include <vector>
#include <utility>
namespace nana namespace nana
{ /// Create an Open or Save dialog box to let user select the name of a file. { /// Create an Open or Save dialog box to let user select the name of a file.
class filebox class filebox
: nana::noncopyable
{ {
struct implement; struct implement;
public:
typedef std::vector<std::pair<nana::string, nana::string>> filters;
filebox(filebox&&) = delete;
filebox& operator=(filebox&&) = delete;
public:
using filters = std::vector<std::pair<nana::string, nana::string>>;
filebox(bool is_open_mode);
filebox(window owner, bool is_open_mode); filebox(window owner, bool is_open_mode);
filebox(const filebox&);
~filebox(); ~filebox();
filebox& operator=(const filebox&);
/// Change owner window
void owner(window);
/** @brief specify a title for the dialog /** @brief specify a title for the dialog
* @param string a text for title * @param string a text for title
*/ */

View File

@ -30,6 +30,7 @@ namespace nana
/// Zoom the input_s to fit for ref_s /// Zoom the input_s to fit for ref_s
void fit_zoom(const size& input_s, const size& ref_s, size& result_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 //zoom
//@brief: Calculate the scaled rectangle by refer dst rectangle, that scale factor is same as that between scaled and refer. //@brief: Calculate the scaled rectangle by refer dst rectangle, that scale factor is same as that between scaled and refer.

View File

@ -14,7 +14,7 @@
#define NANA_GUI_MSGBOX_HPP #define NANA_GUI_MSGBOX_HPP
#include <sstream> #include <sstream>
#include <nana/gui/basis.hpp> #include <nana/gui/filebox.hpp>
namespace nana namespace nana
{ {
@ -100,7 +100,7 @@ namespace nana
virtual const ::nana::string& label() const = 0; virtual const ::nana::string& label() const = 0;
virtual window create(window, unsigned label_px) = 0; virtual window create(window, unsigned label_px) = 0;
virtual unsigned fixed_pixels() const = 0; virtual unsigned fixed_pixels() const;
}; };
public: public:
class integer class integer
@ -116,7 +116,6 @@ namespace nana
//Implementation of abstract_content //Implementation of abstract_content
const ::nana::string& label() const override; const ::nana::string& label() const override;
window create(window, unsigned label_px) override; window create(window, unsigned label_px) override;
unsigned fixed_pixels() const override;
private: private:
std::unique_ptr<implement> impl_; std::unique_ptr<implement> impl_;
}; };
@ -134,7 +133,6 @@ namespace nana
//Implementation of abstract_content //Implementation of abstract_content
const ::nana::string& label() const override; const ::nana::string& label() const override;
window create(window, unsigned label_px) override; window create(window, unsigned label_px) override;
unsigned fixed_pixels() const override;
private: private:
std::unique_ptr<implement> impl_; std::unique_ptr<implement> impl_;
}; };
@ -149,12 +147,16 @@ namespace nana
~text(); ~text();
void tip_string(std::wstring tip);
void tip_string(std::string tip_utf8);
void mask_character(wchar_t ch);
::nana::string value() const; ::nana::string value() const;
private: private:
//Implementation of abstract_content //Implementation of abstract_content
const ::nana::string& label() const override; const ::nana::string& label() const override;
window create(window, unsigned label_px) override; window create(window, unsigned label_px) override;
unsigned fixed_pixels() const override;
private: private:
std::unique_ptr<implement> impl_; std::unique_ptr<implement> impl_;
}; };
@ -172,7 +174,24 @@ namespace nana
int year() const; int year() const;
int month() const; //[1, 12] int month() const; //[1, 12]
int day() const; //[1, 31] 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; unsigned fixed_pixels() const override;
private:
std::unique_ptr<implement> impl_;
};
class path
: public abstract_content
{
struct implement;
public:
path(::nana::string label, const ::nana::filebox&);
~path();
::nana::string value() const;
private: private:
//Implementation of abstract_content //Implementation of abstract_content
const ::nana::string& label() const override; const ::nana::string& label() const override;
@ -183,6 +202,9 @@ namespace nana
inputbox(window, ::nana::string description, ::nana::string title = ::nana::string()); 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<typename ...Args> template<typename ...Args>
bool show(Args&& ... args) bool show(Args&& ... args)
{ {
@ -225,6 +247,8 @@ namespace nana
::nana::string description_; ::nana::string description_;
::nana::string title_; ::nana::string title_;
std::function<bool(window)> verifier_; std::function<bool(window)> verifier_;
::nana::paint::image images_[4];
::nana::rectangle valid_areas_[4];
}; };
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/* /*
* A Form Implementation * A Form Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -37,7 +37,7 @@ namespace nana
class form: public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension> class form: public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension>
{ {
public: 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. /// 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 form(const rectangle& = API::make_center(300, 200), const appearance& = {}); //Default constructor
@ -53,7 +53,7 @@ namespace nana
class nested_form : public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension> class nested_form : public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension>
{ {
public: public:
typedef ::nana::appear appear; using appear = ::nana::appear;
nested_form(const form&, const rectangle& = {}, const appearance& = {}); nested_form(const form&, const rectangle& = {}, const appearance& = {});
nested_form(const nested_form&, const rectangle& = {}, const appearance& = {}); nested_form(const nested_form&, const rectangle& = {}, const appearance& = {});

View File

@ -558,7 +558,6 @@ By \a clicking on a header the list get \a reordered, first up, and then down al
private: private:
drawerbase::listbox::essence_t & _m_ess() const; drawerbase::listbox::essence_t & _m_ess() const;
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) 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<nana::detail::key_interface>); drawerbase::listbox::category_t* _m_at_key(std::shared_ptr<nana::detail::key_interface>);
void _m_ease_key(nana::detail::key_interface*); void _m_ease_key(nana::detail::key_interface*);
}; };

View File

@ -17,62 +17,52 @@
namespace nana namespace nana
{ {
namespace xpicture class picture;
namespace drawerbase
{ {
class picture_drawer: public drawer_trigger namespace picture
{ {
public: struct implement;
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 class drawer : public drawer_trigger
{ {
::nana::color gradual_from; friend class ::nana::picture;
::nana::color gradual_to; public:
bool horizontal; drawer();
}bground_; ~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 /// Rectangle area for displaying a bitmap file
class picture class picture
: public widget_object<category::widget_tag, xpicture::picture_drawer> : public widget_object<category::widget_tag, drawerbase::picture::drawer>
{ {
public: public:
picture(); picture() = default;
picture(window, bool visible); 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. /// Sets the align of image.
void bgstyle(bool stretchable, ///< if false the other arguments will be ignored void align(align, align_v);
nana::arrange arg, ///< stretching the image horizontally or vertically
int beg, ///< specify the stretchy area of image. /// Enables the image to be stretched to the widget size.
int end ///< specify the stretchy area of image. 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. /// 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); void transparent(bool);
bool transparent() const; bool transparent() const;
}; };

View File

@ -44,7 +44,6 @@ namespace nana
widget * widget_{nullptr}; widget * widget_{nullptr};
nana::paint::graphics* graph_{nullptr}; nana::paint::graphics* graph_{nullptr};
unsigned draw_width_{static_cast<unsigned>(-1)}; unsigned draw_width_{static_cast<unsigned>(-1)};
//bool has_value_{true}; //deprecated
bool unknown_{false}; bool unknown_{false};
unsigned max_{100}; unsigned max_{100};
unsigned value_{0}; unsigned value_{0};

View File

@ -82,7 +82,7 @@ namespace nana{ namespace paint
return false; return false;
std::unique_ptr<char[]> buffer(new char[static_cast<int>(size)]); std::unique_ptr<char[]> buffer(new char[static_cast<int>(size)]);
ifs.read(buffer.get(), size); ifs.read(buffer.get(), size);
if(size == ifs.gcount()) if(size == ifs.gcount())
{ {
@ -94,7 +94,7 @@ namespace nana{ namespace paint
//Bitmap file is 4byte-aligned for each line. //Bitmap file is 4byte-aligned for each line.
std::size_t bytes_per_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) if(0 == info->bmiHeader.biSizeImage)
bytes_per_line = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) >> 3); bytes_per_line = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) >> 3);
else else
@ -204,7 +204,7 @@ namespace nana{ namespace paint
d = dpend; d = dpend;
s -= bytes_per_line; s -= bytes_per_line;
} }
} }
} }
else if(2 == info->bmiHeader.biBitCount) else if(2 == info->bmiHeader.biBitCount)
{ {
@ -257,7 +257,7 @@ namespace nana{ namespace paint
d = dpend; d = dpend;
s -= bytes_per_line; s -= bytes_per_line;
} }
} }
} }
else if(1 == info->bmiHeader.biBitCount) else if(1 == info->bmiHeader.biBitCount)
{ {
@ -310,7 +310,7 @@ namespace nana{ namespace paint
d = dpend; d = dpend;
s -= bytes_per_line; s -= bytes_per_line;
} }
} }
} }
} }
} }

View File

@ -128,6 +128,7 @@ namespace nana
unsigned height() const; ///< Returns the height of the off-screen buffer. unsigned height() const; ///< Returns the height of the off-screen buffer.
::nana::size size() const; ::nana::size size() const;
void setsta(); ///< Clears the status if the graphics object had been changed void setsta(); ///< Clears the status if the graphics object had been changed
void set_changed();
void release(); void release();
void save_as_file(const char*); void save_as_file(const char*);

View File

@ -11,7 +11,11 @@
*/ */
#include <nana/basic_types.hpp> #include <nana/basic_types.hpp>
#if defined(USE_STD_REGEX)
#include <regex> #include <regex>
#else
#include <vector>
#endif
#include <algorithm> #include <algorithm>
namespace nana namespace nana
@ -60,10 +64,46 @@ namespace nana
a_ = 1.0; 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 //Initializes the color with a CSS-like string
//contributor: BigDave(mortis2007 at hotmail co uk) //contributor: BigDave(mortis2007 at hotmail co uk)
//date: February 3, 2015 //date: February 3, 2015
//maintainor: Jinhao, extended the support of CSS-spec //maintainor: Jinhao, extended the support of CSS-spec
color::color(std::string css_color) color::color(std::string css_color)
: a_(1.0) : a_(1.0)
{ {
@ -85,7 +125,7 @@ namespace nana
if ((endpos - pos != 4) && (endpos - pos != 7)) if ((endpos - pos != 4) && (endpos - pos != 7))
throw std::invalid_argument(excpt_what); 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) if (endpos - pos == 4)
{ {
@ -135,6 +175,7 @@ namespace nana
has_alpha = true; has_alpha = true;
} }
#if defined(USE_STD_REGEX)
std::regex pat; std::regex pat;
std::regex_iterator<std::string::iterator> i, end; std::regex_iterator<std::string::iterator> i, end;
auto type_name = css_color.substr(pos, 3); auto type_name = css_color.substr(pos, 3);
@ -222,6 +263,106 @@ namespace nana
throw std::invalid_argument(excpt_what); //invalid alpha value throw std::invalid_argument(excpt_what); //invalid alpha value
a_ = ::nana::stod(i->str()); 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<std::string> 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) color& color::from_rgb(unsigned red, unsigned green, unsigned blue)

View File

@ -15,6 +15,7 @@
#include <nana/deploy.hpp> #include <nana/deploy.hpp>
#include <cstdlib> #include <cstdlib>
#include <stdexcept> #include <stdexcept>
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include <windows.h> #include <windows.h>
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
@ -22,38 +23,12 @@
#include PLATFORM_SPEC_HPP #include PLATFORM_SPEC_HPP
#endif #endif
namespace nana #if defined(NANA_MINGW)
#include <sstream>
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) int stoi(const std::string& str, std::size_t * pos, int base)
{ {
#if defined(NANA_MINGW)
auto sptr = str.c_str(); auto sptr = str.c_str();
char *end; char *end;
errno = 0; errno = 0;
@ -67,14 +42,10 @@ namespace nana
if (pos) if (pos)
*pos = (std::size_t)(end - sptr); *pos = (std::size_t)(end - sptr);
return ((int)result); return ((int)result);
#else
return std::stoi(str, pos, base);
#endif
} }
int stoi(const std::wstring& str, std::size_t* pos, int base) int stoi(const std::wstring& str, std::size_t* pos, int base)
{ {
#if defined(NANA_MINGW)
auto sptr = str.data(); auto sptr = str.data();
wchar_t *end; wchar_t *end;
errno = 0; errno = 0;
@ -88,14 +59,42 @@ namespace nana
if (pos) if (pos)
*pos = (std::size_t)(end - sptr); *pos = (std::size_t)(end - sptr);
return ((int)result); 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) double stod(const std::string& str, std::size_t * pos)
{ {
#ifdef NANA_MINGW
auto *ptr = str.data(); auto *ptr = str.data();
errno = 0; errno = 0;
char *end; char *end;
@ -108,14 +107,10 @@ namespace nana
if (pos) if (pos)
*pos = (std::size_t)(end - ptr); *pos = (std::size_t)(end - ptr);
return result; return result;
#else
return std::stod(str, pos);
#endif
} }
double stod(const std::wstring& str, std::size_t* pos) double stod(const std::wstring& str, std::size_t* pos)
{ {
#ifdef NANA_MINGW
auto *ptr = str.data(); auto *ptr = str.data();
errno = 0; errno = 0;
wchar_t *end; wchar_t *end;
@ -128,11 +123,258 @@ namespace nana
if (pos) if (pos)
*pos = (std::size_t)(end - ptr); *pos = (std::size_t)(end - ptr);
return result; 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 #else
return std::stod(str, pos); return ::strlen(str);
#endif #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) bool is_incomplete(const nana::string& str, unsigned pos)
{ {
#ifndef NANA_UNICODE #ifndef NANA_UNICODE

View File

@ -1,6 +1,7 @@
/* /*
* An Animation Implementation * 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. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -35,12 +36,8 @@ namespace nana
struct output_t struct output_t
{ {
drawing::diehard_t diehard; drawing::diehard_t diehard{ nullptr };
std::vector<nana::point> points; std::vector<nana::point> points;
output_t()
: diehard(nullptr)
{}
}; };
struct framebuilder struct framebuilder
@ -48,11 +45,7 @@ namespace nana
std::size_t length; std::size_t length;
std::function<bool(std::size_t, paint::graphics&, nana::size&)> frbuilder; std::function<bool(std::size_t, paint::graphics&, nana::size&)> frbuilder;
framebuilder(const std::function<bool(std::size_t, paint::graphics&, nana::size&)>& f, std::size_t l) framebuilder(std::function<bool(std::size_t, paint::graphics&, nana::size&)> f, std::size_t l)
: length(l), frbuilder(f)
{}
framebuilder(std::size_t l, std::function<bool(std::size_t, paint::graphics&, nana::size)>&& f)
: length(l), frbuilder(std::move(f)) : length(l), frbuilder(std::move(f))
{} {}
}; };
@ -65,28 +58,16 @@ namespace nana
framebuilder framebuilder
}; };
frame(const paint::image& r) frame(paint::image img)
: type(kind::oneshot) : type(kind::oneshot)
{ {
u.oneshot = new paint::image(r); u.oneshot = new paint::image(std::move(img));
} }
frame(paint::image&& r) frame(std::function<bool(std::size_t, paint::graphics&, nana::size&)> frbuilder, std::size_t length)
: type(kind::oneshot)
{
u.oneshot = new paint::image(std::move(r));
}
frame(const std::function<bool(std::size_t, paint::graphics&, nana::size&)>& frbuilder, std::size_t length)
: type(kind::framebuilder) : type(kind::framebuilder)
{ {
u.frbuilder = new framebuilder(frbuilder, length); u.frbuilder = new framebuilder(std::move(frbuilder), length);
}
frame(std::function<bool(std::size_t, paint::graphics&, nana::size&)>&& frbuilder, std::size_t length)
: type(kind::framebuilder)
{
u.frbuilder = new framebuilder(frbuilder, length);
} }
frame(const frame& r) frame(const frame& r)
@ -323,29 +304,15 @@ namespace nana
: impl_(new impl) : 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(); bool located = impl_->this_frame != impl_->frames.end();
impl_->frames.emplace_back(m); impl_->frames.emplace_back(std::move(img));
if(false == located) if(false == located)
impl_->this_frame = impl_->frames.begin(); impl_->this_frame = impl_->frames.begin();
} }
void frameset::push_back(paint::image&& m) void frameset::push_back(framebuilder fb, std::size_t length)
{
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)
{ {
impl_->frames.emplace_back(std::move(fb), length); impl_->frames.emplace_back(std::move(fb), length);
if(1 == impl_->frames.size()) if(1 == impl_->frames.size())
@ -365,10 +332,14 @@ namespace nana
std::size_t active; //The number of active animations std::size_t active; //The number of active animations
std::shared_ptr<std::thread> thread; std::shared_ptr<std::thread> thread;
std::size_t fps;
double interval; //milliseconds between 2 frames.
double performance_parameter; 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); void close(impl* p);
bool empty() const; bool empty() const;
private: private:
@ -380,8 +351,9 @@ namespace nana
struct animation::impl struct animation::impl
{ {
bool looped; bool looped{false};
volatile bool paused; volatile bool paused{true};
std::size_t fps;
std::list<frameset> framesets; std::list<frameset> framesets;
std::map<std::string, branch_t> branches; std::map<std::string, branch_t> branches;
@ -399,17 +371,21 @@ namespace nana
static performance_manager * perf_manager; static performance_manager * perf_manager;
impl() impl(std::size_t fps)
: looped(false), paused(true) : fps(fps)
{ {
state.this_frameset = framesets.begin(); state.this_frameset = framesets.begin();
if (!perf_manager)
{ {
nana::internal_scope_guard lock; nana::internal_scope_guard lock;
if(nullptr == perf_manager) if (!perf_manager)
perf_manager = new performance_manager; {
auto pm = new performance_manager;
perf_manager = pm;
}
} }
thr_variable = perf_manager->insert(this); perf_manager->insert(this);
} }
~impl() ~impl()
@ -457,46 +433,80 @@ namespace nana
};//end struct animation::impl };//end struct animation::impl
//class animation::performance_manager //class animation::performance_manager
auto animation::performance_manager::insert(impl* p) -> thread_variable * void animation::performance_manager::insert(impl* p)
{ {
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
for(auto thr : threads_) for(auto thr : threads_)
{ {
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex); std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
if (thr->fps == p->fps)
if(thr->performance_parameter / (thr->animations.size() + 1) <= 43.3)
{ {
thr->animations.push_back(p); if (thr->animations.empty() || (thr->performance_parameter * (1.0 + 1.0 / thr->animations.size()) <= 43.3))
return thr; {
p->thr_variable = thr;
thr->animations.push_back(p);
return;
}
} }
} }
auto thr = new thread_variable; auto thr = new thread_variable;
thr->animations.push_back(p); thr->animations.push_back(p);
thr->performance_parameter = 0.0; thr->performance_parameter = 0.0;
thr->fps = p->fps;
thr->interval = 1000.0 / double(p->fps);
thr->thread = std::make_shared<std::thread>([this, thr]() thr->thread = std::make_shared<std::thread>([this, thr]()
{ {
_m_perf_thread(thr); _m_perf_thread(thr);
}); });
threads_.push_back(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<decltype(mutex_)> 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_guard<decltype(thr->mutex)> 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) void animation::performance_manager::close(impl* p)
{ {
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
for(auto thr : threads_) auto i = std::find(threads_.begin(), threads_.end(), p->thr_variable);
{ if (i == threads_.end())
std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex); return;
auto i = std::find(thr->animations.begin(), thr->animations.end(), p); auto thr = *i;
if(i != thr->animations.end()) std::lock_guard<decltype(thr->mutex)> privlock(thr->mutex);
{
thr->animations.erase(i); auto u = std::find(thr->animations.begin(), thr->animations.end(), p);
return; if(u != thr->animations.end())
} thr->animations.erase(u);
}
} }
bool animation::performance_manager::empty() const bool animation::performance_manager::empty() const
@ -542,8 +552,8 @@ namespace nana
if(thrvar->active) if(thrvar->active)
{ {
thrvar->performance_parameter = tmpiece.calc(); thrvar->performance_parameter = tmpiece.calc();
if(thrvar->performance_parameter < 43.4) if(thrvar->performance_parameter < thrvar->interval)
nana::system::sleep(static_cast<unsigned>(43.4 - thrvar->performance_parameter)); nana::system::sleep(static_cast<unsigned>(thrvar->interval - thrvar->performance_parameter));
} }
else else
{ {
@ -557,15 +567,15 @@ namespace nana
} }
//end class animation::performance_manager //end class animation::performance_manager
animation::animation() animation::animation(std::size_t fps)
: impl_(new impl) : 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()) if(1 == impl_->framesets.size())
impl_->state.this_frameset = impl_->framesets.begin(); impl_->state.this_frameset = impl_->framesets.begin();
} }
@ -634,6 +644,19 @@ namespace nana
} }
output.points.push_back(pos); 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 //end class animation

View File

@ -1008,8 +1008,6 @@ namespace detail
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); emit_drawer(&drawer::mouse_up, msgwnd, arg, &context);
//auto evt_ptr = msgwnd->together.events_ptr; //deprecated
if (fire_click) if (fire_click)
{ {
arg.evt_code = event_code::click; arg.evt_code = event_code::click;
@ -1322,6 +1320,7 @@ namespace detail
arg.ignore = false; arg.ignore = false;
brock.emit(event_code::shortkey, msgwnd, arg, true, &context); brock.emit(event_code::shortkey, msgwnd, arg, true, &context);
} }
def_window_proc = true;
break; break;
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
if(brock.whether_keyboard_shortkey() == false) if(brock.whether_keyboard_shortkey() == false)
@ -1342,6 +1341,7 @@ namespace detail
else if(brock.get_menu()) else if(brock.get_menu())
brock.remove_menu(); brock.remove_menu();
} }
def_window_proc = true;
break; break;
case WM_SYSKEYUP: case WM_SYSKEYUP:
if(brock.set_keyboard_shortkey(false) == false) if(brock.set_keyboard_shortkey(false) == false)
@ -1358,6 +1358,7 @@ namespace detail
brock.emit(event_code::key_release, msgwnd, arg, true, &context); brock.emit(event_code::key_release, msgwnd, arg, true, &context);
} }
} }
def_window_proc = true;
break; break;
case WM_KEYDOWN: case WM_KEYDOWN:
if(msgwnd->flags.enabled) if(msgwnd->flags.enabled)

View File

@ -1,4 +1,16 @@
#include <nana/gui/filebox.hpp> /*
* 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 <nana/gui.hpp>
#include <nana/filesystem/fs_utility.hpp> #include <nana/filesystem/fs_utility.hpp>
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
@ -858,6 +870,11 @@ namespace nana
std::vector<filter> filters; std::vector<filter> filters;
}; };
filebox::filebox(bool is_openmode)
: filebox(nullptr, is_openmode)
{
}
filebox::filebox(window owner, bool open) filebox::filebox(window owner, bool open)
: impl_(new implement) : impl_(new implement)
{ {
@ -874,11 +891,27 @@ namespace nana
#endif #endif
} }
filebox::filebox(const filebox& other)
: impl_(new implement(*other.impl_))
{}
filebox::~filebox() filebox::~filebox()
{ {
delete impl_; 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) nana::string filebox::title(nana::string s)
{ {
impl_->title.swap(s); impl_->title.swap(s);

View File

@ -1,6 +1,7 @@
/* /*
* Utility Implementation * 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. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -17,11 +18,11 @@ namespace nana
//overlap test if overlaped between r1 and r2 //overlap test if overlaped between r1 and r2
bool overlap(const rectangle& r1, const rectangle& r2) bool overlap(const rectangle& r1, const rectangle& r2)
{ {
if(r1.y + int(r1.height) <= r2.y) return false; if (r1.y + (long long)(r1.height) <= r2.y) return false;
if(r1.y >= int(r2.y + r2.height)) 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 + (long long)(r1.width) <= r2.x) return false;
if(r1.x >= int(r2.x + r2.width)) return false; if(r1.x >= r2.x + (long long)(r2.width)) return false;
return true; return true;
} }
@ -60,7 +61,11 @@ namespace nana
zoom(ir, op_ir, dr, op_dr); 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; op_dr = good_dr;
zoom(dr, good_dr, ir, op_ir); zoom(dr, good_dr, ir, op_ir);
@ -241,6 +246,19 @@ namespace nana
result_s = ref_s; 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<unsigned>(ref_s.height * rate_input);
else if (rate_input > rate_ref)
ref_s.height = static_cast<unsigned>(ref_s.width / rate_input);
return ref_s;
}
void zoom(const rectangle& ref, const rectangle& scaled, const rectangle& ref_dst, rectangle& r) void zoom(const rectangle& ref, const rectangle& scaled, const rectangle& ref_dst, rectangle& r)
{ {
double rate_x = (scaled.x - ref.x) / double(ref.width); double rate_x = (scaled.x - ref.x) / double(ref.width);

View File

@ -17,6 +17,7 @@
#include <nana/gui/widgets/combox.hpp> #include <nana/gui/widgets/combox.hpp>
#include <nana/gui/widgets/textbox.hpp> #include <nana/gui/widgets/textbox.hpp>
#include <nana/gui/widgets/panel.hpp> #include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/picture.hpp>
#include <nana/gui/place.hpp> #include <nana/gui/place.hpp>
#include <nana/datetime.hpp> #include <nana/datetime.hpp>
#include <nana/internationalization.hpp> #include <nana/internationalization.hpp>
@ -474,7 +475,7 @@ namespace nana
: public ::nana::form : public ::nana::form
{ {
public: public:
inputbox_window(window owner, const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector<unsigned>& 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<unsigned>& each_height)
: form(owner, API::make_center(owner, 500, 300), appear::decorate<>()) : form(owner, API::make_center(owner, 500, 300), appear::decorate<>())
{ {
desc_.create(*this); desc_.create(*this);
@ -501,8 +502,8 @@ namespace nana
unsigned height = 20 + desc_extent.height + 10 + 38; unsigned height = 20 + desc_extent.height + 10 + 38;
place_.bind(*this); place_.bind(*this);
std::stringstream ss; std::stringstream ss_content;
ss << "margin=10 vert <desc weight=" << desc_extent.height << "><vert margin=[10]"; ss_content << "<margin=10 vert <desc weight=" << desc_extent.height << "><vert margin=[10]";
for (std::size_t i = 0; i < contents; ++i) for (std::size_t i = 0; i < contents; ++i)
{ {
@ -510,16 +511,12 @@ namespace nana
if (each_height[i] > 27) if (each_height[i] > 27)
px = each_height[i]; px = each_height[i];
ss << "<weight="<<px<<" margin=[3] input_" << i << ">"; ss_content << "<weight=" << px << " margin=[3] input_" << i << ">";
height += px + 1; height += px + 1;
} }
ss << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>"; ss_content << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>>";
place_.div(ss.str().data());
place_["desc"] << desc_;
place_["buttons"] << btn_ok_ << btn_cancel_;
if (desc_extent.width < 170) if (desc_extent.width < 170)
desc_extent.width = 170; desc_extent.width = 170;
@ -528,7 +525,90 @@ namespace nana
if (desc_extent.width < fixed_pixels) if (desc_extent.width < fixed_pixels)
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<size::value_type>(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<size::value_type>(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<size::value_type>(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<size::value_type>(double(sz.height) * (double(desc_extent.width) / double(sz.width)));
height += sz.height;
}
std::stringstream ss;
ss << "vert<img_top weight="<<img_sz[0].height<<"><<img_left weight="<<img_sz[2].width<<">"<<ss_content.str()<<"<img_right weight="<<img_sz[3].width<<">><img_bottom weight="<<img_sz[1].height<<">";
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); caption(title);
} }
@ -558,8 +638,14 @@ namespace nana
bool valid_input_{ false }; bool valid_input_{ false };
::nana::place place_; ::nana::place place_;
std::function<bool(window)> verifier_; std::function<bool(window)> verifier_;
::nana::picture images_[4];
}; };
unsigned inputbox::abstract_content::fixed_pixels() const
{
return 0;
}
//class integer //class integer
struct inputbox::integer::implement struct inputbox::integer::implement
{ {
@ -590,6 +676,9 @@ namespace nana
int inputbox::integer::value() const int inputbox::integer::value() const
{ {
if (!impl_->spinbox.empty())
return impl_->spinbox.to_int();
return impl_->value; return impl_->value;
} }
@ -611,20 +700,13 @@ namespace nana
//get the longest value //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); 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 } }; 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<int>(label_px + 10), 0, value_px, 0 }); impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
impl->spinbox.range(impl->begin, impl->last, impl->step); 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. impl->spinbox.value(std::to_wstring(impl->value));
ss.str(L"");
ss.clear();
ss << impl->value;
impl->spinbox.value(ss.str());
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) 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; return impl->dock;
} }
unsigned inputbox::integer::fixed_pixels() const
{
return 0;
}
//end class integer //end class integer
@ -677,6 +754,9 @@ namespace nana
double inputbox::real::value() const double inputbox::real::value() const
{ {
if (!impl_->spinbox.empty())
return impl_->spinbox.to_double();
return impl_->value; return impl_->value;
} }
@ -698,20 +778,13 @@ namespace nana
//get the longest value //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); 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 } }; 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<int>(label_px + 10), 0, value_px, 0 }); impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
impl->spinbox.range(impl->begin, impl->last, impl->step); 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. impl->spinbox.value(std::to_wstring(impl->value));
ss.str(L"");
ss.clear();
ss << impl->value;
impl->spinbox.value(ss.str());
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) 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->spinbox.events().destroy.connect_unignorable([impl]
{ {
impl->value = impl->spinbox.to_int(); impl->value = impl->spinbox.to_double();
}); });
return impl->dock; return impl->dock;
} }
unsigned inputbox::real::fixed_pixels() const
{
return 0;
}
//end class real //end class real
//class text //class text
struct inputbox::text::implement struct inputbox::text::implement
{ {
::nana::string value; ::nana::string value;
::nana::string tip;
wchar_t mask_character{0};
std::vector< ::nana::string> options; std::vector< ::nana::string> options;
::nana::string label_text; ::nana::string label_text;
@ -763,8 +833,28 @@ namespace nana
//Instance for impl_ because implmenet is incomplete type at the point of declaration //Instance for impl_ because implmenet is incomplete type at the point of declaration
inputbox::text::~text(){} 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 ::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; return impl_->value;
} }
@ -788,6 +878,9 @@ namespace nana
if (impl->options.empty()) if (impl->options.empty())
{ {
impl->textbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, 0, 0 }); impl->textbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, 0, 0 });
impl->textbox.tip_string(impl->tip);
impl->textbox.mask(impl->mask_character);
impl->textbox.multi_lines(false);
} }
else else
{ {
@ -825,11 +918,6 @@ namespace nana
}); });
return impl->dock; return impl->dock;
} }
unsigned inputbox::text::fixed_pixels() const
{
return 0;
}
//end class text //end class text
@ -859,22 +947,28 @@ namespace nana
::nana::string inputbox::date::value() const ::nana::string inputbox::date::value() const
{ {
std::wstringstream ss; return std::to_wstring(impl_->month) + L'-' + std::to_wstring(impl_->day) + L", " + std::to_wstring(impl_->year);
ss << impl_->month << L'-' << impl_->day << L", " << impl_->year;
return ss.str();
} }
int inputbox::date::year() const int inputbox::date::year() const
{ {
if (!impl_->wdg_year.empty())
return impl_->wdg_year.to_int();
return impl_->year; return impl_->year;
} }
int inputbox::date::month() const int inputbox::date::month() const
{ {
if (!impl_->wdg_month.empty())
return impl_->wdg_month.option() + 1;
return impl_->month; return impl_->month;
} }
int inputbox::date::day() const int inputbox::date::day() const
{ {
if (!impl_->wdg_day.empty())
return impl_->wdg_day.to_int();
return impl_->day; return impl_->day;
} }
@ -907,22 +1001,15 @@ namespace nana
left += 104; left += 104;
impl->wdg_day.create(impl->dock, rectangle{ left, 0, 38, 0 }); 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.range(1, ::nana::date::month_days(today.year, today.month), 1);
//impl->wdg_day.set_accept_integer(); //deprecated
left += 48; left += 48;
impl->wdg_year.create(impl->dock, rectangle{left, 0, 50, 0}); impl->wdg_year.create(impl->dock, rectangle{left, 0, 50, 0});
impl->wdg_year.range(1601, 9999, 1); impl->wdg_year.range(1601, 9999, 1);
//impl->wdg_year.set_accept_integer(); //deprecated
impl->wdg_month.option(today.month - 1); impl->wdg_month.option(today.month - 1);
std::wstringstream ss; impl->wdg_day.value(std::to_wstring(today.day));
ss << today.day; impl->wdg_year.value(std::to_wstring(today.year));
impl->wdg_day.value(ss.str());
ss.str(L"");
ss.clear();
ss << today.year;
impl->wdg_year.value(ss.str());
impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg) impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg)
{ {
@ -962,10 +1049,8 @@ namespace nana
if (day > days) if (day > days)
day = days; day = days;
std::wstringstream ss; impl->wdg_day.value(std::to_wstring(day));
ss << day;
impl->wdg_day.value(ss.str());
}; };
impl->wdg_year.events().text_changed.connect_unignorable(make_days); impl->wdg_year.events().text_changed.connect_unignorable(make_days);
@ -980,6 +1065,87 @@ namespace nana
} }
//end class date //end class date
//class path
struct inputbox::path::implement
{
filebox fbox;
::nana::string value;
::nana::string label_text;
::nana::panel<false> 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<int>(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<int>(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) inputbox::inputbox(window owner, ::nana::string desc, ::nana::string title)
: owner_{ owner }, : owner_{ owner },
@ -987,6 +1153,20 @@ namespace nana
title_(std::move(title)) 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<bool(window)> verifier) void inputbox::verify(std::function<bool(window)> verifier)
{ {
verifier_ = std::move(verifier); verifier_ = std::move(verifier);
@ -995,7 +1175,6 @@ namespace nana
void inputbox::_m_fetch_args(std::vector<abstract_content*>&) void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
{} {}
bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal) bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
{ {
std::vector<unsigned> each_pixels; std::vector<unsigned> each_pixels;
@ -1014,7 +1193,7 @@ namespace nana
each_pixels.push_back(px.height); 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<window> inputs; std::vector<window> inputs;
for (auto p : contents) for (auto p : contents)

View File

@ -127,15 +127,13 @@ namespace nana
if(graph.width() > 32 + border_size * 2) if(graph.width() > 32 + border_size * 2)
{ {
std::stringstream ss;
ss<<chmonth_.year;
nana::string str; nana::string str;
if(page_ == page::date) if(page_ == page::date)
{ {
str += ::nana::internationalization()(monthstr[chmonth_.month - 1]); str = ::nana::internationalization()(monthstr[chmonth_.month - 1]);
str += STR(" "); str += STR(" ");
} }
str += nana::charset(ss.str()); str += std::to_wstring(chmonth_.year);
nana::size txt_s = graph.text_extent_size(str); nana::size txt_s = graph.text_extent_size(str);
@ -205,10 +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) void trigger::_m_draw_pos(drawing_basis & dbasis, graph_reference graph, int x, int y, int number, bool primary, bool sel)
{ {
//The C++ library comes with MinGW does not provide std::to_wstring() conversion _m_draw_pos(dbasis, graph, x, y, std::to_wstring(number), primary, sel);
std::wstringstream ss;
ss<<number;
_m_draw_pos(dbasis, graph, x, y, nana::charset(ss.str()), primary, sel);
} }
void trigger::_m_draw_ex_days(drawing_basis & dbasis, graph_reference graph, int begx, int begy, bool before) void trigger::_m_draw_ex_days(drawing_basis & dbasis, graph_reference graph, int begx, int begy, bool before)

View File

@ -18,7 +18,6 @@
#include <list> #include <list>
#include <deque> #include <deque>
#include <stdexcept> #include <stdexcept>
#include <sstream>
#include <algorithm> #include <algorithm>
namespace nana namespace nana
@ -79,15 +78,6 @@ namespace nana
} }
//end struct cell //end struct cell
//A workaround, MinGW does not yet provide std::to_wstring
template<typename Int>
std::wstring to_wstring(Int n)
{
std::wstringstream ss;
ss << n;
return ss.str();
}
//definition of iresolver/oresolver //definition of iresolver/oresolver
oresolver& oresolver::operator<<(bool n) oresolver& oresolver::operator<<(bool n)
{ {
@ -96,77 +86,66 @@ namespace nana
} }
oresolver& oresolver::operator<<(short n) oresolver& oresolver::operator<<(short n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(unsigned short n) oresolver& oresolver::operator<<(unsigned short n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(int n) oresolver& oresolver::operator<<(int n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(unsigned int n) oresolver& oresolver::operator<<(unsigned int n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(long n) oresolver& oresolver::operator<<(long n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(unsigned long n) oresolver& oresolver::operator<<(unsigned long n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(long long n) oresolver& oresolver::operator<<(long long n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(unsigned long long n) oresolver& oresolver::operator<<(unsigned long long n)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(n));
cells_.emplace_back(to_wstring(n));
return *this; return *this;
} }
oresolver& oresolver::operator<<(float f) oresolver& oresolver::operator<<(float f)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(f));
cells_.emplace_back(to_wstring(f));
return *this; return *this;
} }
oresolver& oresolver::operator<<(double f) oresolver& oresolver::operator<<(double f)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(f));
cells_.emplace_back(to_wstring(f));
return *this; return *this;
} }
oresolver& oresolver::operator<<(long double f) oresolver& oresolver::operator<<(long double f)
{ {
//A workaround, MinGW does not yet provide std::to_wstring cells_.emplace_back(std::to_wstring(f));
cells_.emplace_back(to_wstring(f));
return *this; return *this;
} }
@ -221,117 +200,82 @@ namespace nana
iresolver& iresolver::operator>>(bool& n) iresolver& iresolver::operator>>(bool& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = (std::stoi(cells_[pos_++].text) == 0);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(short& n) iresolver& iresolver::operator>>(short& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stoi(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(unsigned short& n) iresolver& iresolver::operator>>(unsigned short& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = static_cast<unsigned short>(std::stoul(cells_[pos_++].text));
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(int& n) iresolver& iresolver::operator>>(int& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stoi(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(unsigned int& n) iresolver& iresolver::operator>>(unsigned int& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stoul(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(long& n) iresolver& iresolver::operator>>(long& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stol(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(unsigned long& n) iresolver& iresolver::operator>>(unsigned long& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stoul(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(long long& n) iresolver& iresolver::operator>>(long long& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stoll(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(unsigned long long& n) iresolver& iresolver::operator>>(unsigned long long& n)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ n = std::stoull(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> n;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(float& f) iresolver& iresolver::operator>>(float& f)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ f = std::stof(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> f;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(double& f) iresolver& iresolver::operator>>(double& f)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ f = std::stod(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> f;
}
return *this; return *this;
} }
iresolver& iresolver::operator>>(long double& f) iresolver& iresolver::operator>>(long double& f)
{ {
if (pos_ < cells_.size()) if (pos_ < cells_.size())
{ f = std::stold(cells_[pos_++].text);
std::wstringstream ss(cells_[pos_++].text);
ss >> f;
}
return *this; return *this;
} }
@ -1203,8 +1147,9 @@ namespace nana
} }
} }
void item_checked(selection& vec) const selection item_checked() const
{ {
selection vec;
index_pair id; index_pair id;
for(auto & cat : list_) for(auto & cat : list_)
{ {
@ -1217,6 +1162,7 @@ namespace nana
} }
++id.cat; ++id.cat;
} }
return vec;
} }
void select_range(index_pair fr, index_pair to, bool sel) void select_range(index_pair fr, index_pair to, bool sel)
@ -2373,7 +2319,7 @@ namespace nana
if(x < essence_->scroll.offset_x) if(x < essence_->scroll.offset_x)
x = essence_->scroll.offset_x; x = essence_->scroll.offset_x;
else if(x > essence_->scroll.offset_x + static_cast<int>(rect.width)) else if(x > essence_->scroll.offset_x + static_cast<int>(rect.width))
x = essence_->scroll.offset_x + rect.width; x = essence_->scroll.offset_x + static_cast<int>(rect.width);
size_type i = essence_->header.item_by_x(x); size_type i = essence_->header.item_by_x(x);
if(i == npos) if(i == npos)
@ -2537,6 +2483,8 @@ namespace nana
auto idx = essence_->scroll.offset_y; auto idx = essence_->scroll.offset_y;
auto state = item_state::normal; 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. //Here draws a root categ or a first drawing is not a categ.
if(idx.cat == 0 || !idx.is_category()) if(idx.cat == 0 || !idx.is_category())
{ {
@ -2546,30 +2494,16 @@ namespace nana
idx.item = 0; idx.item = 0;
} }
//Test whether the sort is enabled. std::size_t size = i_categ->items.size();
if(essence_->lister.sort_index() != npos) for(std::size_t offs = essence_->scroll.offset_y.item; offs < size; ++offs, ++idx.item)
{ {
std::size_t size = i_categ->items.size(); if(n-- == 0) break;
for(std::size_t offs = essence_->scroll.offset_y.item; offs < size; ++offs, ++idx.item) 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); _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; 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;
}
} }
++i_categ; ++i_categ;
++idx.cat; ++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); _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state);
y += essence_->item_size; y += essence_->item_size;
if(false == i_categ->expand) continue; if(false == i_categ->expand)
continue;
//Test whether the sort is enabled. auto size = i_categ->items.size();
if(essence_->lister.sort_index() != npos) for(decltype(size) pos = 0; pos < size; ++pos)
{ {
auto size = i_categ->items.size(); if(n-- == 0) break;
for(decltype(size) pos = 0; pos < size; ++pos) 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); _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; y += essence_->item_size;
++idx.item; ++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;
}
} }
} }
@ -2627,25 +2544,24 @@ namespace nana
{ {
bool sel = categ.selected(); bool sel = categ.selected();
if(sel && (categ.expand == false)) if(sel && (categ.expand == false))
bgcolor = nana::color(0xD5, 0xEF, 0xFC); bgcolor = static_cast<color_rgb>(0xD5EFFC);
if (state == item_state::highlighted) if (state == item_state::highlighted)
bgcolor = bgcolor.blend(::nana::color(0x99, 0xde, 0xfd), 0.8); bgcolor = bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8);
auto graph = essence_->graph; auto graph = essence_->graph;
graph->set_color(bgcolor); graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true, bgcolor);
graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true);
color txt_color{ static_cast<color_rgb>(0x3399) };
facade<element::arrow> arrow("double"); facade<element::arrow> arrow("double");
arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south); arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south);
::nana::rectangle arrow_r{ x + 5, y + static_cast<int>(essence_->item_size - 16) / 2, 16, 16 }; ::nana::rectangle arrow_r{ x + 5, y + static_cast<int>(essence_->item_size - 16) / 2, 16, 16 };
arrow.draw(*graph, {}, static_cast<color_rgb>(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; ::nana::string str = L'(' + std::to_wstring(categ.items.size()) + L')';
ss<<'('<<static_cast<unsigned>(categ.items.size())<<')';
nana::string str = nana::charset(ss.str());
unsigned str_w = graph->text_extent_size(str).width; 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) if (x + 35 + text_s.width + str_w < x + width)
{ {
::nana::point pos{ x + 30 + static_cast<int>(text_s.width + str_w), y + static_cast<int>(essence_->item_size) / 2 }; ::nana::point pos{ x + 30 + static_cast<int>(text_s.width + str_w), y + static_cast<int>(essence_->item_size) / 2 };
graph->line(pos, { x + static_cast<int>(width)-5, pos.y }, { 0x0, 0x33, 0x99 }); graph->line(pos, { x + static_cast<int>(width)-5, pos.y }, txt_color);
} }
//Draw selecting inner rectangle //Draw selecting inner rectangle
if(sel && categ.expand == false) if(sel && categ.expand == false)
@ -2845,7 +2761,7 @@ namespace nana
auto & graph = *essence_->graph; auto & graph = *essence_->graph;
auto size = graph.size(); auto size = graph.size();
//Draw Border //Draw Border
graph.rectangle(false, {0x9c, 0xb6, 0xc5}); graph.rectangle(false, static_cast<color_rgb>(0x9cb6c5));
graph.line({ 1, 1 }, {1, static_cast<int>(size.height) - 2}, colors::white); graph.line({ 1, 1 }, {1, static_cast<int>(size.height) - 2}, colors::white);
graph.line({ static_cast<int>(size.width) - 2, 1 }, { static_cast<int>(size.width) - 2, static_cast<int>(size.height) - 2 }); graph.line({ static_cast<int>(size.width) - 2, 1 }, { static_cast<int>(size.width) - 2, static_cast<int>(size.height) - 2 });
@ -3749,8 +3665,7 @@ namespace nana
auto & ess = _m_ess(); auto & ess = _m_ess();
if (ess.lister.insert(pos, std::move(text))) if (ess.lister.insert(pos, std::move(text)))
{ {
window wd = handle(); if (! empty())
if (false == API::empty_window(wd))
{ {
auto & item = ess.lister.at(pos); auto & item = ess.lister.at(pos);
item.bgcolor = bgcolor(); item.bgcolor = bgcolor();
@ -3772,9 +3687,7 @@ namespace nana
auto listbox::checked() const -> selection auto listbox::checked() const -> selection
{ {
selection s; return _m_ess().lister.item_checked();
_m_ess().lister.item_checked(s);
return std::move(s);
} }
void listbox::clear(size_type cat) void listbox::clear(size_type cat)
@ -3941,11 +3854,6 @@ namespace nana
return _m_ess().lister.anyobj(index_pair{cat, index}, allocate_if_empty); 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<nana::detail::key_interface> ptr) drawerbase::listbox::category_t* listbox::_m_at_key(std::shared_ptr<nana::detail::key_interface> ptr)
{ {
auto & ess = _m_ess(); auto & ess = _m_ess();

View File

@ -1,6 +1,7 @@
/* /*
* A Picture Implementation * 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. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -13,248 +14,167 @@
#include <nana/gui/widgets/picture.hpp> #include <nana/gui/widgets/picture.hpp>
#include <nana/paint/image.hpp> #include <nana/paint/image.hpp>
#include <nana/gui/element.hpp>
namespace nana namespace nana
{ {
namespace xpicture namespace drawerbase
{ {
namespace picture
//class picture_drawer {
picture_drawer::picture_drawer():graph_(nullptr) struct implement
{ {
bground_.horizontal = true; widget* wdg_ptr{nullptr};
backimg_.arg = nana::arrange::unknown; paint::graphics* graph_ptr{nullptr};
backimg_.beg = backimg_.end = 0;
}
void picture_drawer::attached(widget_reference& widget, graph_reference graph)
{
widget_ = &widget;
graph_ = &graph;
}
void picture_drawer::load(const nana::char_t* file) struct gradual_bground_tag
{
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)
{ {
backimg_.is_stretch = is_stretch; ::nana::color gradual_from;
backimg_.arg = arg; ::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<element::bground> 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; //class drawer
if(end < beg) end = beg; drawer::drawer() :impl_(new implement)
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<unsigned>(beg) >= scale)
beg = static_cast<int>(scale) - 1;
if(end < beg)
end = beg;
else if(static_cast<unsigned>(end) >= scale)
end = static_cast<int>(scale) - 1;
backimg_.beg = beg;
backimg_.end = end;
return true;
}
backimg_.arg = nana::arrange::unknown;
return false;
} }
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(); auto valid_area = backimg.valid_area;
if(backimg_.image.empty() == false) if (valid_area.empty())
valid_area = backimg.image.size();
if (backimg.stretchable)
{ {
nana::size imgsize = backimg_.image.size(); auto fit_size = fit_zoom({ valid_area.width, valid_area.height }, graphsize);
nana::size gsize = graph.size(); ::nana::point pos;
switch(backimg_.arg) if (fit_size.width != graphsize.width)
{ {
case nana::arrange::unknown: switch (backimg.align_horz)
backimg_.image.paste(graph, 0, 0); {
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; break;
case nana::arrange::horizontal: case ::nana::align::right:
if(backimg_.beg < backimg_.end) pos.x = int(graphsize.width) - int(valid_area.width);
{
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<int>(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<int>(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<int>(gsize.width))
{
backimg_.image.paste(graph, x, 0);
x += static_cast<int>(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<unsigned>(backimg_.beg)), graph, nana::point());
if(block_tail)
backimg_.image.paste(nana::rectangle(0, static_cast<int>(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<int>(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<int>(gsize.height))
{
backimg_.image.paste(graph, 0, y);
y += static_cast<int>(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<int>(gsize.height))
{
int x = 0;
while(x < static_cast<int>(gsize.width))
{
backimg_.image.paste(graph, x, y);
x += static_cast<int>(imgsize.width);
}
y += static_cast<int>(imgsize.height);
}
}
else
backimg_.image.stretch(imgsize, graph, gsize);
break; 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()) auto & bground = impl_->gradual_bground;
graph_->rectangle(true, widget_->bgcolor()); if (bground.gradual_from.invisible() || bground.gradual_to.invisible())
else if(bground_.gradual_from == bground_.gradual_to) graph->rectangle(true, impl_->wdg_ptr->bgcolor());
graph_->rectangle(true, bground_.gradual_from); else if (bground.gradual_from == bground.gradual_to)
graph->rectangle(true, bground.gradual_from);
else 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 class drawer
}//end namespace xpicture }//end namespace picture
}//end namespace drawerbase
//class picture //class picture
picture::picture(){}
picture::picture(window wd, bool visible) picture::picture(window wd, bool visible)
{ {
create(wd, rectangle(), visible); create(wd, rectangle(), visible);
@ -265,21 +185,91 @@ namespace nana
create(wd, r, visible); 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); internal_scope_guard lock;
API::refresh_window(*this); 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); 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) 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) void picture::transparent(bool enabled)

View File

@ -108,7 +108,7 @@ namespace nana
{ {
rectangle r = graph.size(); rectangle r = graph.size();
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true); 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); graph.frame_rectangle(r, lt, lt, rb, rb);
} }

View File

@ -198,12 +198,12 @@ namespace nana
unsigned vcur() const unsigned vcur() const
{ {
return attr_.vcur; return static_cast<unsigned>(attr_.vcur);
} }
void resize() void resize()
{ {
this->_m_mk_slider_pos_by_value(); _m_mk_slider_pos_by_value();
attr_.adorn_pos = attr_.pos; attr_.adorn_pos = attr_.pos;
} }
@ -338,16 +338,18 @@ namespace nana
unsigned move_step(bool forward) unsigned move_step(bool forward)
{ {
unsigned cmpvalue = attr_.vcur; unsigned cmpvalue = static_cast<unsigned>(attr_.vcur);
auto value = cmpvalue;
if(forward) if(forward)
{ {
if(attr_.vcur) if (value)
--attr_.vcur; --value;
} }
else if(attr_.vcur < attr_.vmax) else if (value < attr_.vmax)
++attr_.vcur; ++value;
if(cmpvalue != attr_.vcur) attr_.vcur = value;
if (cmpvalue != value)
{ {
_m_mk_slider_pos_by_value(); _m_mk_slider_pos_by_value();
draw(); draw();
@ -436,32 +438,29 @@ namespace nana
return static_cast<int>(_m_scale() * attr_.vcur / attr_.vmax); return static_cast<int>(_m_scale() * attr_.vcur / attr_.vmax);
} }
unsigned _m_mk_slider_value_by_pos() void _m_mk_slider_value_by_pos()
{ {
if(_m_scale()) if(_m_scale())
{ {
auto cmpvalue = attr_.vcur; auto cmpvalue = static_cast<int>(attr_.vcur);
attr_.vcur = static_cast<unsigned>(attr_.pos * attr_.vmax / _m_scale()); attr_.vcur = (attr_.pos * attr_.vmax / _m_scale());
if (cmpvalue != attr_.vcur) if (cmpvalue != static_cast<int>(attr_.vcur))
_m_emit_value_changed(); _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; attr_.pos = double(_m_scale()) * attr_.vcur / attr_.vmax;
if(slider_state_.trace == slider_state_.TraceNone) if(slider_state_.trace == slider_state_.TraceNone)
attr_.adorn_pos = attr_.pos; attr_.adorn_pos = attr_.pos;
return static_cast<int>(attr_.pos);
} }
unsigned _m_value_by_pos(double pos) const unsigned _m_value_by_pos(double pos) const
{ {
if(_m_scale()) if(_m_scale())
return static_cast<int>(pos * attr_.vmax / _m_scale()); return static_cast<unsigned>(pos * attr_.vmax / _m_scale());
return 0; return 0;
} }
@ -548,7 +547,7 @@ namespace nana
style dir; style dir;
unsigned border; unsigned border;
unsigned vmax; unsigned vmax;
unsigned vcur; double vcur;
double pos; double pos;
bool is_draw_adorn; bool is_draw_adorn;
double adorn_pos; double adorn_pos;

View File

@ -73,9 +73,7 @@ namespace nana
std::wstring value() const override std::wstring value() const override
{ {
std::wstringstream ss; return std::to_wstring(value_);
ss << value_;
return ss.str();
} }
bool value(const std::wstring& value_str, bool & diff) override bool value(const std::wstring& value_str, bool & diff) override
@ -665,12 +663,12 @@ namespace nana
int spinbox::to_int() const int spinbox::to_int() const
{ {
return ::nana::stoi(value()); return std::stoi(value());
} }
double spinbox::to_double() const double spinbox::to_double() const
{ {
return ::nana::stod(value()); return std::stod(value());
} }
void spinbox::modifier(std::wstring prefix, std::wstring suffix) void spinbox::modifier(std::wstring prefix, std::wstring suffix)

View File

@ -456,25 +456,13 @@ namespace drawerbase {
textbox& textbox::from(int n) textbox& textbox::from(int n)
{ {
#ifdef NANA_UNICODE _m_caption(std::to_wstring(n));
std::wstringstream ss;
#else
std::stringstream ss;
#endif
ss << n;
_m_caption(ss.str());
return *this; return *this;
} }
textbox& textbox::from(double d) textbox& textbox::from(double d)
{ {
#ifdef NANA_UNICODE _m_caption(std::to_wstring(d));
std::wstringstream ss;
#else
std::stringstream ss;
#endif
ss << d;
_m_caption(ss.str());
return *this; return *this;
} }

View File

@ -343,7 +343,7 @@ namespace nana
erase_n = str.size() - offset; erase_n = str.size() - offset;
//If there is not a parameter for %argNNN, the %argNNN will be erased. //If there is not a parameter for %argNNN, the %argNNN will be erased.
std::size_t arg = static_cast<std::size_t>(::nana::stoi(str.substr(offset + 4, arg_n))); std::size_t arg = static_cast<std::size_t>(std::stoi(str.substr(offset + 4, arg_n)));
if (arg_strs && arg < arg_strs->size()) if (arg_strs && arg < arg_strs->size())
str.replace(offset, erase_n, (*arg_strs)[arg]); str.replace(offset, erase_n, (*arg_strs)[arg]);

View File

@ -800,6 +800,11 @@ namespace paint
changed_ = false; changed_ = false;
} }
void graphics::set_changed()
{
changed_ = true;
}
void graphics::release() void graphics::release()
{ {
dwptr_.reset(); dwptr_.reset();