From f8991cbbd9d4a46c022c48190e2ab985db2d565e Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 17 Feb 2016 00:42:55 +0800 Subject: [PATCH 001/309] fix splitter bar weird behavior --- source/gui/place.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index d6adb5d0..df89bbeb 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -1323,8 +1323,6 @@ namespace nana public: div_splitter(place_parts::number_t init_weight) : division(kind::splitter, std::string()), - splitter_cursor_(cursor::arrow), - pause_move_collocate_(false), init_weight_(init_weight) { this->weight.assign(splitter_px); @@ -1373,11 +1371,18 @@ namespace nana left_pixels_ = area_left.*px_ptr; right_pixels_ = area_right.*px_ptr; + + grabbed_ = true; + }); + + splitter_.events().mouse_up([this](const arg_mouse&) + { + grabbed_ = false; }); splitter_.events().mouse_move.connect_unignorable([this](const arg_mouse& arg) { - if (false == arg.left_button) + if ((false == arg.left_button) || (false == grabbed_)) return; const bool vert = (::nana::cursor::size_we != splitter_cursor_); @@ -1526,13 +1531,14 @@ namespace nana return area; } private: - nana::cursor splitter_cursor_; + nana::cursor splitter_cursor_{nana::cursor::arrow}; place_parts::splitter splitter_; nana::point begin_point_; int left_pos_, right_pos_; unsigned left_pixels_, right_pixels_; dragger dragger_; - bool pause_move_collocate_; //A flag represents whether do move when collocating. + bool grabbed_{ false }; + bool pause_move_collocate_{ false }; //A flag represents whether do move when collocating. place_parts::number_t init_weight_; }; From 0ed51a7a21126bd8abd2afd568b73158ec52f8c2 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 17 Feb 2016 01:18:18 +0800 Subject: [PATCH 002/309] optimize template class to reduce generated binary size --- include/nana/gui/detail/general_events.hpp | 205 +++++++-------------- source/gui/detail/events_operation.cpp | 107 +++++++++++ 2 files changed, 178 insertions(+), 134 deletions(-) diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 8d75dc9e..446664fa 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -24,6 +24,9 @@ namespace nana { namespace detail { + void events_operation_register(event_handle); + void events_operation_cancel(event_handle); + class event_interface { public: @@ -38,8 +41,50 @@ namespace nana virtual event_interface* get_event() const = 0; }; - void events_operation_register(event_handle); - void events_operation_cancel(event_handle); + + struct docker_base + : public docker_interface + { + event_interface * event_ptr; + bool flag_deleted{ false }; + const bool unignorable; + + docker_base(event_interface*, bool unignorable_flag); + + detail::event_interface * get_event() const override; + }; + + class event_base + : public detail::event_interface + { + public: + ~event_base(); + + std::size_t length() const; + void clear() noexcept; + + void remove(event_handle evt) override; + protected: + //class emit_counter is a RAII helper for emitting count + //It is used for avoiding a try{}catch block which is required for some finial works when + //event handlers throw exceptions. + class emit_counter + { + public: + emit_counter(event_base*); + ~emit_counter(); + private: + event_base * const evt_; + }; + + //event_handle _m_emplace(::std::unique_ptr& docker_ptr, bool in_front); + event_handle _m_emplace(detail::docker_interface*, bool in_front); + protected: + unsigned emitting_count_{ 0 }; + bool deleted_flags_{ false }; + //std::unique_ptr>> dockers_; + std::vector * dockers_{ nullptr }; + }; }//end namespace detail /// base clase for all event argument types @@ -59,83 +104,32 @@ namespace nana /// the type of the members of general_events template - class basic_event : public detail::event_interface + class basic_event : public detail::event_base { public: using arg_reference = const typename std::remove_reference::type &; private: struct docker - : public detail::docker_interface + : public detail::docker_base { - basic_event * const event_ptr; std::function invoke; - bool flag_deleted{ false }; - bool unignorable{false}; - - docker(basic_event * s, std::function && ivk, bool unignorable_flag) - : event_ptr(s), invoke(std::move(ivk)), unignorable(unignorable_flag) + docker(basic_event * evt, std::function && ivk, bool unignorable_flag) + : docker_base(evt, unignorable_flag), invoke(std::move(ivk)) {} - docker(basic_event * s, const std::function & ivk, bool unignorable_flag) - : event_ptr(s), invoke(ivk), unignorable(unignorable_flag) + docker(basic_event * evt, const std::function & ivk, bool unignorable_flag) + : docker_base(evt, unignorable_flag), invoke(ivk) {} - - ~docker() - { - detail::events_operation_cancel(reinterpret_cast(this)); - } - - detail::event_interface * get_event() const override - { - return event_ptr; - } - }; - - //class emit_counter is a RAII helper for emitting count - //It is used for avoiding a try{}catch block which is required for some finial works when - //event handlers throw exceptions. - class emit_counter - { - public: - emit_counter(basic_event* evt) - : evt_{evt} - { - ++evt->emitting_count_; - } - - ~emit_counter() - { - if ((0 == --evt_->emitting_count_) && evt_->deleted_flags_) - { - evt_->deleted_flags_ = false; - for (auto i = evt_->dockers_->begin(); i != evt_->dockers_->end();) - { - if (static_cast(i->get())->flag_deleted) - i = evt_->dockers_->erase(i); - else - ++i; - } - } - } - private: - basic_event * const evt_; }; public: - /// It will get called firstly, because it is set at the beginning of the chain. + /// Creates an event handler at the beginning of event chain template event_handle connect_front(Function && fn) - { - internal_scope_guard lock; - if (nullptr == dockers_) - dockers_.reset(new std::vector>); - + { using prototype = typename std::remove_reference::type; - std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); - auto evt = reinterpret_cast(dck.get()); - dockers_->emplace(dockers_->begin(), std::move(dck)); - detail::events_operation_register(evt); - return evt; + + return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), false), true); } event_handle connect(void (*fn)(arg_reference)) @@ -149,16 +143,9 @@ namespace nana template event_handle connect(Function && fn) { - internal_scope_guard lock; - if (nullptr == dockers_) - dockers_.reset(new std::vector>); - using prototype = typename std::remove_reference::type; - std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); - auto evt = reinterpret_cast(dck.get()); - dockers_->emplace_back(std::move(dck)); - detail::events_operation_register(evt); - return evt; + + return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), false), false); } /// It will not get called if stop_propagation() was called. @@ -171,26 +158,10 @@ namespace nana /// It will get called because it is unignorable. template event_handle connect_unignorable(Function && fn, bool in_front = false) - { - internal_scope_guard lock; - if (nullptr == dockers_) - dockers_.reset(new std::vector>); - + { using prototype = typename std::remove_reference::type; - std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), true)); - auto evt = reinterpret_cast(dck.get()); - if (in_front) - dockers_->emplace(dockers_->begin(), std::move(dck)); - else - dockers_->emplace_back(std::move(dck)); - detail::events_operation_register(evt); - return evt; - } - std::size_t length() const - { - internal_scope_guard lock; - return (nullptr == dockers_ ? 0 : dockers_->size()); + return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), true), in_front); } void emit(arg_reference& arg) @@ -202,13 +173,13 @@ namespace nana emit_counter ec(this); auto& dockers = *dockers_; - const auto dockers_len = dockers.size(); + const auto dockers_len = dockers_->size(); //The dockers may resize when a new event handler is created by a calling handler. //Traverses with position can avaid crash error which caused by a iterator which becomes invalid. for (std::size_t pos = 0; pos < dockers_len; ++pos) { - auto docker_ptr = static_cast(dockers[pos].get()); + auto docker_ptr = static_cast(dockers[pos]); if (docker_ptr->flag_deleted) continue; @@ -217,7 +188,7 @@ namespace nana { for (++pos; pos < dockers_len; ++pos) { - auto docker_ptr = static_cast(dockers[pos].get()); + auto docker_ptr = static_cast(dockers[pos]); if (!docker_ptr->unignorable || docker_ptr->flag_deleted) continue; @@ -227,36 +198,6 @@ namespace nana } } } - - void clear() - { - internal_scope_guard lock; - if (dockers_) - dockers_.reset(); - } - - void remove(event_handle evt) override - { - internal_scope_guard lock; - if (dockers_) - { - for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i) - { - if (reinterpret_cast(evt) == i->get()) - { - //Checks whether this event is working now. - if (emitting_count_ > 1) - { - static_cast(i->get())->flag_deleted = true; - deleted_flags_ = true; - } - else - dockers_->erase(i); - break; - } - } - } - } private: template struct factory @@ -413,10 +354,6 @@ namespace nana }; } }; - private: - unsigned emitting_count_{ 0 }; - bool deleted_flags_{ false }; - std::unique_ptr>> dockers_; }; struct arg_mouse @@ -427,12 +364,12 @@ namespace nana ::nana::point pos; ///< cursor position in the event window ::nana::mouse button; ///< indicates a button which triggers the event - bool left_button; ///< mouse left button is pressed? - bool mid_button; ///< mouse middle button is pressed? - bool right_button; ///< mouse right button is pressed? - bool alt; ///< keyboard alt is pressed? - bool shift; ///< keyboard Shift is pressed? - bool ctrl; ///< keyboard Ctrl is pressed? + bool left_button; ///< true if mouse left button is pressed + bool mid_button; ///< true if mouse middle button is pressed + bool right_button; ///< true if mouse right button is pressed + bool alt; ///< true if keyboard alt is pressed + bool shift; ///< true if keyboard Shift is pressed + bool ctrl; ///< true if keyboard Ctrl is pressed /// Checks if left button is operated, bool is_left_button() const @@ -481,7 +418,7 @@ namespace nana event_code evt_code; ///< it is event_code::key_press in current event ::nana::window window_handle; ///< A handle to the event window mutable wchar_t key; ///< the key corresponding to the key pressed - mutable bool ignore; ///< this member is not used + mutable bool ignore; ///< this member is only available for key_char event, set 'true' to ignore the input. bool ctrl; ///< keyboard Ctrl is pressed? bool shift; ///< keyboard Shift is pressed }; diff --git a/source/gui/detail/events_operation.cpp b/source/gui/detail/events_operation.cpp index 8877ebd1..bff546ca 100644 --- a/source/gui/detail/events_operation.cpp +++ b/source/gui/detail/events_operation.cpp @@ -42,5 +42,112 @@ namespace nana } } //end namespace events_operation + + + //class docker_base + docker_base::docker_base(event_interface* evt, bool unignorable_flag) + : event_ptr(evt), unignorable(unignorable_flag) + {} + + detail::event_interface * docker_base::get_event() const + { + return event_ptr; + } + //end class docker_base + + //class event_base + event_base::~event_base() + { + clear(); + } + + std::size_t event_base::length() const + { + internal_scope_guard lock; + return (nullptr == dockers_ ? 0 : dockers_->size()); + } + + void event_base::clear() noexcept + { + internal_scope_guard lock; + if (dockers_) + { + for (auto p : *dockers_) + { + detail::events_operation_cancel(reinterpret_cast(p)); + delete p; + } + dockers_->clear(); + + delete dockers_; + dockers_ = nullptr; + } + } + + void event_base::remove(event_handle evt) + { + internal_scope_guard lock; + if (dockers_) + { + + for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i) + { + if (reinterpret_cast(evt) == *i) + { + //Checks whether this event is working now. + if (emitting_count_ > 1) + { + static_cast(*i)->flag_deleted = true; + deleted_flags_ = true; + } + else + dockers_->erase(i); + break; + } + } + } + } + + event_handle event_base::_m_emplace(detail::docker_interface* docker_ptr, bool in_front) + { + internal_scope_guard lock; + if (nullptr == dockers_) + dockers_ = new std::vector; + + auto evt = reinterpret_cast(docker_ptr); + + if (in_front) + dockers_->emplace(dockers_->begin(), docker_ptr); + else + dockers_->emplace_back(docker_ptr); + + detail::events_operation_register(evt); + return evt; + } + + //class emit_counter + event_base::emit_counter::emit_counter(event_base* evt) + : evt_{ evt } + { + ++evt->emitting_count_; + } + + event_base::emit_counter::~emit_counter() + { + if ((0 == --evt_->emitting_count_) && evt_->deleted_flags_) + { + evt_->deleted_flags_ = false; + for (auto i = evt_->dockers_->begin(); i != evt_->dockers_->end();) + { + if (static_cast(*i)->flag_deleted) + i = evt_->dockers_->erase(i); + else + ++i; + } + } + } + //end class emit_counter + //end class event_base + }//end namespace detail }//end namespace nana \ No newline at end of file From 999a1e7cbc85e5e4d7979bc05a8670f64aca4f6f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 16 Feb 2016 18:22:13 +0100 Subject: [PATCH 003/309] "automate" demos build with GLOB --- CMakeLists.txt | 91 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4b6ec4f..9d95f00a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ option(ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) option(CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF) + # The ISO C++ File System Technical Specification is optional. # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf # This is not a workaround, but an user option. @@ -195,22 +196,24 @@ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) # ?? -install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) +#install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file -if (BUILD_NANA_DEMOS) - set (CMAKE_INSTALL_PREFIX ${DEMO_BIN}) - set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin) - set(CMAKE_INSTALL_PREFIX ) - - add_executable(calculator ../nana-demo/calculator.cpp) - set_property( TARGET calculator PROPERTY CXX_STANDARD 14 ) - target_link_libraries(calculator ${PROJECT_NAME} ) - install(TARGETS calculator RUNTIME DESTINATION &{DEMO_BIN}) + + +if (BUILD_NANA_DEMOS_) + #set (CMAKE_INSTALL_PREFIX ${DEMO_BIN}) + #set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin) + #set(CMAKE_INSTALL_PREFIX ) + + #add_executable(calculator ../nana-demo/calculator.cpp) + #set_property( TARGET calculator PROPERTY CXX_STANDARD 14 ) + #target_link_libraries(calculator ${PROJECT_NAME} ) + #install(TARGETS calculator RUNTIME DESTINATION &{DEMO_BIN}) if (BUILD_FreeMe) add_executable(FreeMe ../nana-demo/FreeMe.cpp) @@ -348,7 +351,7 @@ if (BUILD_NANA_DEMOS) if (ENABLE_AUDIO) add_executable(audio_player ../nana-demo/Examples/audio_player.cpp) set_property( TARGET audio_player PROPERTY CXX_STANDARD 14 ) - target_link_libraries(audio_player ${PROJECT_NAME} ) + target_link_libraries(audio_player ${PROJECT_NAME} ) endif(ENABLE_AUDIO) # TODO: make it automatic to select each demo and example and build each. @@ -364,9 +367,72 @@ if (BUILD_NANA_DEMOS) # target_link_libraries(${demoname} ${PROJECT_NAME} )# X11 Xft ${NANA_JPEG_LIB} ${NANA_PNG_LIB}) #endforeach( demofile ${DEMO_SOURCES} ) -endif(BUILD_NANA_DEMOS) +endif(BUILD_NANA_DEMOS_) +if (BUILD_NANA_DEMOS_temp) + + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}) + set(DEMO_BIN ${CMAKE_INSTALL_PREFIX}../nana-demo/bin) + + set (demos + calculator notepad widget_show widget_show2 + ) + # file_explorer + # FreeMe + + foreach ( demo ${demos}) + add_executable(${demo} "../nana-demo/${demo}.cpp") + set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demo} ${PROJECT_NAME}) + install(TARGETS ${demo} RUNTIME DESTINATION &{DEMO_BIN}) + + message("... building ../nana-demo/${demo}.cpp" ) # dont works as I specte + endforeach( demo ${demos}) + +endif (BUILD_NANA_DEMOS) + +if(BUILD_NANA_DEMOS) + + # TODO: make it automatic to select each demo and example and build each. + set(NANA_DEMOS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../nana-demo/") + message ( "NANA_DEMOS_DIR = " ${NANA_DEMOS_DIR}) + # https://cmake.org/cmake/help/v3.3/command/file.html?highlight=glob#file + file( GLOB DEMO_SOURCES RELATIVE ${NANA_DEMOS_DIR} *.cpp ) + message ( "DEMO_SOURCES = " ${DEMO_SOURCES}) + + foreach( demofile ${DEMO_SOURCES} ) + string( REPLACE ".cpp" "" demoname ${demofile} ) + message ( "demofile = " ${demofile}) + message ( "demoname = " ${demoname}) + add_executable( ${demoname} ${demofile} ) + set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demoname} ${PROJECT_NAME} ) + endforeach( demofile ${DEMO_SOURCES} ) + + + set(NANA_EXAMPLES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../nana-demo/Examples/") + message ( "NANA_EXAMPLES_DIR = " ${NANA_EXAMPLES_DIR}) + file( GLOB EXAMPLES_SOURCES RELATIVE ${NANA_EXAMPLES_DIR} *.cpp ) + message ( "EXAMPLES_SOURCES = " ${EXAMPLES_SOURCES}) + + foreach( demofile ${EXAMPLES_SOURCES} ) + string( REPLACE ".cpp" "" demoname ${demofile} ) + message ( "demofile = " ${demofile}) + message ( "demoname = " ${demoname}) + add_executable( ${demoname} ${demofile} ) + set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demoname} ${PROJECT_NAME} ) + endforeach( demofile ${EXAMPLES_SOURCES} ) + + + add_executable(label_listener ../nana-demo/Examples/label_listener.cpp) + set_property( TARGET label_listener PROPERTY CXX_STANDARD 14 ) + target_link_libraries(label_listener ${PROJECT_NAME}) + + +endif(BUILD_NANA_DEMOS) + # set compile flags if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") @@ -395,3 +461,4 @@ message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "ENABLE_AUDIO = " ${ENABLE_AUDIO}) + From f4bc8af69595b2cbe90992455e3b2c359be2add0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 16 Feb 2016 18:59:24 +0100 Subject: [PATCH 004/309] all demos in cmake --- CMakeLists.txt | 232 +++++-------------------------------------------- 1 file changed, 20 insertions(+), 212 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d95f00a..c3f9f12b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,183 +203,14 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file - - -if (BUILD_NANA_DEMOS_) - #set (CMAKE_INSTALL_PREFIX ${DEMO_BIN}) - #set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin) - #set(CMAKE_INSTALL_PREFIX ) - - #add_executable(calculator ../nana-demo/calculator.cpp) - #set_property( TARGET calculator PROPERTY CXX_STANDARD 14 ) - #target_link_libraries(calculator ${PROJECT_NAME} ) - #install(TARGETS calculator RUNTIME DESTINATION &{DEMO_BIN}) - - if (BUILD_FreeMe) - add_executable(FreeMe ../nana-demo/FreeMe.cpp) - set_property( TARGET FreeMe PROPERTY CXX_STANDARD 14 ) - target_link_libraries(FreeMe ${PROJECT_NAME} ) - install(TARGETS FreeMe RUNTIME DESTINATION &{DEMO_BIN}) - endif (BUILD_FreeMe) - - add_executable(notepad ../nana-demo/notepad.cpp) - set_property( TARGET notepad PROPERTY CXX_STANDARD 14 ) - target_link_libraries(notepad ${PROJECT_NAME} ) - install(TARGETS notepad RUNTIME DESTINATION &{DEMO_BIN}) - - add_executable(widget_show ../nana-demo/widget_show.cpp) - set_property( TARGET widget_show PROPERTY CXX_STANDARD 14 ) - target_link_libraries(widget_show ${PROJECT_NAME}) - install(TARGETS widget_show RUNTIME DESTINATION &{DEMO_BIN}) - - add_executable(widget_show2 ../nana-demo/widget_show2.cpp) - set_property( TARGET widget_show2 PROPERTY CXX_STANDARD 14 ) - target_link_libraries(widget_show2 ${PROJECT_NAME}) - install(TARGETS widget_show2 RUNTIME DESTINATION &{DEMO_BIN}) - - if (OFF) # temporal: we need to adapt the use of filesystem to nana v1.03 (no file iterator) - - add_executable(file_explorer ../nana-demo/file_explorer.cpp) - set_property( TARGET file_explorer PROPERTY CXX_STANDARD 14 ) - target_link_libraries(file_explorer ${PROJECT_NAME} ) - install(TARGETS file_explorer RUNTIME DESTINATION &{DEMO_BIN}) - - - - endif(OFF) - - add_executable(a_group_impl ../nana-demo/Examples/a_group_impl.cpp) - set_property( TARGET a_group_impl PROPERTY CXX_STANDARD 14 ) - target_link_libraries(a_group_impl ${PROJECT_NAME}) - - add_executable(animate-bmp ../nana-demo/Examples/animate-bmp.cpp) - set_property( TARGET animate-bmp PROPERTY CXX_STANDARD 14 ) - target_link_libraries(animate-bmp ${PROJECT_NAME}) - - add_executable(background-effects ../nana-demo/Examples/background-effects.cpp) - set_property( TARGET background-effects PROPERTY CXX_STANDARD 14 ) - target_link_libraries(background-effects ${PROJECT_NAME}) - - add_executable(categ ../nana-demo/Examples/categ.cpp) - set_property( TARGET categ PROPERTY CXX_STANDARD 14 ) - target_link_libraries(categ ${PROJECT_NAME}) - - add_executable(clicked ../nana-demo/Examples/clicked.cpp) - set_property( TARGET clicked PROPERTY CXX_STANDARD 14 ) - target_link_libraries(clicked ${PROJECT_NAME}) - - add_executable(decore ../nana-demo/Examples/decore.cpp) - set_property( TARGET decore PROPERTY CXX_STANDARD 14 ) - target_link_libraries(decore ${PROJECT_NAME}) - - add_executable(dock ../nana-demo/Examples/dock.cpp) - set_property( TARGET dock PROPERTY CXX_STANDARD 14 ) - target_link_libraries(dock ${PROJECT_NAME}) - - add_executable(drag-button ../nana-demo/Examples/drag-button.cpp) - set_property( TARGET drag-button PROPERTY CXX_STANDARD 14 ) - target_link_libraries(drag-button ${PROJECT_NAME}) - - add_executable(draw ../nana-demo/Examples/draw.cpp) - set_property( TARGET draw PROPERTY CXX_STANDARD 14 ) - target_link_libraries(draw ${PROJECT_NAME}) - - add_executable(example_combox ../nana-demo/Examples/example_combox.cpp) - set_property( TARGET example_combox PROPERTY CXX_STANDARD 14 ) - target_link_libraries(example_combox ${PROJECT_NAME}) - - add_executable(example_listbox ../nana-demo/Examples/example_listbox.cpp) - set_property( TARGET example_listbox PROPERTY CXX_STANDARD 14 ) - target_link_libraries(example_listbox ${PROJECT_NAME}) - - add_executable(example_menu ../nana-demo/Examples/example_menu.cpp) - set_property( TARGET example_menu PROPERTY CXX_STANDARD 14 ) - target_link_libraries(example_menu ${PROJECT_NAME}) - - add_executable(filebox-txt ../nana-demo/Examples/filebox-txt.cpp) - set_property( TARGET filebox-txt PROPERTY CXX_STANDARD 14 ) - target_link_libraries(filebox-txt ${PROJECT_NAME}) - - add_executable(folder_tree ../nana-demo/Examples/folder_tree.cpp) - set_property( TARGET folder_tree PROPERTY CXX_STANDARD 14 ) - target_link_libraries(folder_tree ${PROJECT_NAME}) - - add_executable(folder_tree_nana ../nana-demo/Examples/folder_tree_nana.cpp) - set_property( TARGET folder_tree_nana PROPERTY CXX_STANDARD 14 ) - target_link_libraries(folder_tree_nana ${PROJECT_NAME}) - - add_executable(folder_tree_std ../nana-demo/Examples/folder_tree_std.cpp) - set_property( TARGET folder_tree_std PROPERTY CXX_STANDARD 14 ) - target_link_libraries(folder_tree_std ${PROJECT_NAME}) - - add_executable(listbox_Resolver ../nana-demo/Examples/listbox_Resolver.cpp) - set_property( TARGET listbox_Resolver PROPERTY CXX_STANDARD 14 ) - target_link_libraries(listbox_Resolver ${PROJECT_NAME}) - - add_executable(framework_design_2 ../nana-demo/Examples/framework_design_2.cpp) - set_property( TARGET framework_design_2 PROPERTY CXX_STANDARD 14 ) - target_link_libraries(framework_design_2 ${PROJECT_NAME}) - - add_executable(framework_design_3 ../nana-demo/Examples/framework_design_3.cpp) - set_property( TARGET framework_design_3 PROPERTY CXX_STANDARD 14 ) - target_link_libraries(framework_design_3 ${PROJECT_NAME}) - - add_executable(group ../nana-demo/Examples/group.cpp) - set_property( TARGET group PROPERTY CXX_STANDARD 14 ) - target_link_libraries(group ${PROJECT_NAME}) - - add_executable(HelloWord ../nana-demo/Examples/HelloWord.cpp) - set_property( TARGET HelloWord PROPERTY CXX_STANDARD 14 ) - target_link_libraries(HelloWord ${PROJECT_NAME}) - - add_executable(listbox_inline_widget ../nana-demo/Examples/listbox_inline_widget.cpp) - set_property( TARGET listbox_inline_widget PROPERTY CXX_STANDARD 14 ) - target_link_libraries(listbox_inline_widget ${PROJECT_NAME}) - - add_executable(inputbox ../nana-demo/Examples/inputbox.cpp) - set_property( TARGET inputbox PROPERTY CXX_STANDARD 14 ) - target_link_libraries(inputbox ${PROJECT_NAME}) - - add_executable(label_listener ../nana-demo/Examples/label_listener.cpp) - set_property( TARGET label_listener PROPERTY CXX_STANDARD 14 ) - target_link_libraries(label_listener ${PROJECT_NAME}) - - add_executable(lambda_event.Cpp11 ../nana-demo/Examples/lambda_event.Cpp11.cpp) - set_property( TARGET lambda_event.Cpp11 PROPERTY CXX_STANDARD 14 ) - target_link_libraries(lambda_event.Cpp11 ${PROJECT_NAME}) - - if (ENABLE_AUDIO) - add_executable(audio_player ../nana-demo/Examples/audio_player.cpp) - set_property( TARGET audio_player PROPERTY CXX_STANDARD 14 ) - target_link_libraries(audio_player ${PROJECT_NAME} ) - endif(ENABLE_AUDIO) - - # TODO: make it automatic to select each demo and example and build each. - #set(NANA_DEMOS_DIR ${CMAKE_SOURCE_DIR}/../nana-demo) - #set(NANA_EXAMPLES_DIR ${CMAKE_SOURCE_DIR}/../Examples/nana-demo/) - # https://cmake.org/cmake/help/v3.3/command/file.html?highlight=glob#file - #file( GLOB_RECURSE DEMO_SOURCES RELATIVE ../nana-demo *.cpp ) - - #foreach( demofile ${DEMO_SOURCES} ) - # string( REPLACE ".cpp" "" demoname ${demofile} ) - # add_executable( ${demoname} ${demofile} ) - # set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 ) - # target_link_libraries(${demoname} ${PROJECT_NAME} )# X11 Xft ${NANA_JPEG_LIB} ${NANA_PNG_LIB}) - #endforeach( demofile ${DEMO_SOURCES} ) - -endif(BUILD_NANA_DEMOS_) - - -if (BUILD_NANA_DEMOS_temp) +if (BUILD_NANA_DEMOS) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}) set(DEMO_BIN ${CMAKE_INSTALL_PREFIX}../nana-demo/bin) - set (demos - calculator notepad widget_show widget_show2 - ) # file_explorer # FreeMe + set (demos calculator notepad widget_show widget_show2 ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") @@ -387,51 +218,28 @@ if (BUILD_NANA_DEMOS_temp) target_link_libraries(${demo} ${PROJECT_NAME}) install(TARGETS ${demo} RUNTIME DESTINATION &{DEMO_BIN}) - message("... building ../nana-demo/${demo}.cpp" ) # dont works as I specte + message("... to build: ../nana-demo/${demo}.cpp" ) + endforeach( demo ${demos}) + + set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked + decore dock drag-button draw example.button example_combox example_listbox example_menu + filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 + group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 + mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image + threading thread-pool various_events window-dragger windows-subclassing + ) + + foreach ( demo ${demos}) + add_executable(${demo} "../nana-demo/Examples/${demo}.cpp") + set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demo} ${PROJECT_NAME}) + install(TARGETS ${demo} RUNTIME DESTINATION &{DEMO_BIN}) + + message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) endif (BUILD_NANA_DEMOS) -if(BUILD_NANA_DEMOS) - - # TODO: make it automatic to select each demo and example and build each. - set(NANA_DEMOS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../nana-demo/") - message ( "NANA_DEMOS_DIR = " ${NANA_DEMOS_DIR}) - # https://cmake.org/cmake/help/v3.3/command/file.html?highlight=glob#file - file( GLOB DEMO_SOURCES RELATIVE ${NANA_DEMOS_DIR} *.cpp ) - message ( "DEMO_SOURCES = " ${DEMO_SOURCES}) - - foreach( demofile ${DEMO_SOURCES} ) - string( REPLACE ".cpp" "" demoname ${demofile} ) - message ( "demofile = " ${demofile}) - message ( "demoname = " ${demoname}) - add_executable( ${demoname} ${demofile} ) - set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demoname} ${PROJECT_NAME} ) - endforeach( demofile ${DEMO_SOURCES} ) - - - set(NANA_EXAMPLES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../nana-demo/Examples/") - message ( "NANA_EXAMPLES_DIR = " ${NANA_EXAMPLES_DIR}) - file( GLOB EXAMPLES_SOURCES RELATIVE ${NANA_EXAMPLES_DIR} *.cpp ) - message ( "EXAMPLES_SOURCES = " ${EXAMPLES_SOURCES}) - - foreach( demofile ${EXAMPLES_SOURCES} ) - string( REPLACE ".cpp" "" demoname ${demofile} ) - message ( "demofile = " ${demofile}) - message ( "demoname = " ${demoname}) - add_executable( ${demoname} ${demofile} ) - set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demoname} ${PROJECT_NAME} ) - endforeach( demofile ${EXAMPLES_SOURCES} ) - - - add_executable(label_listener ../nana-demo/Examples/label_listener.cpp) - set_property( TARGET label_listener PROPERTY CXX_STANDARD 14 ) - target_link_libraries(label_listener ${PROJECT_NAME}) - - -endif(BUILD_NANA_DEMOS) # set compile flags if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") From c6a84467ea9ba64e512ce881af67ae5463162ff2 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 16 Feb 2016 21:11:25 +0100 Subject: [PATCH 005/309] pending demos --- CMakeLists.txt | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3f9f12b..2728f9b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ -# CMake configuration for Nana +# CMake configuration for Nana # Author: Andrew Kornilov(https://github.com/ierofant) -# Contributor: -# Robert Hauck - Enable support for PNG/Freetype +# Contributors: +# Jinhao +# Robert Hauck - Enable support for PNG/Freetype # Qiangqiang Wu - Add biicode support # Ariel Vina-Rodriguez (qPCR4vir) @@ -9,6 +10,7 @@ #https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption # use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir # if your changes don't execute + option(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF) option(ENABLE_PNG "Enable the use of PNG" OFF) option(LIBPNG_FROM_OS "Use libpng from operating system." ON) @@ -144,7 +146,6 @@ if(ENABLE_AUDIO) endif(UNIX) endif(ENABLE_AUDIO) -#Unicode if(CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(CMAKE_VERBOSE_PREPROCESSOR) @@ -187,53 +188,47 @@ add_library(${PROJECT_NAME} ${NANA_SOURCE} ${NANA_SYSTEM_SOURCE} ${NANA_THREADS_SOURCE}) - #Headers: use INCLUDE_DIRECTORIES - # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES + # Headers: use INCLUDE_DIRECTORIES + # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) -# ?? -#install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) - # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file if (BUILD_NANA_DEMOS) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}) - set(DEMO_BIN ${CMAKE_INSTALL_PREFIX}../nana-demo/bin) - - # file_explorer - # FreeMe set (demos calculator notepad widget_show widget_show2 ) + # Pending: file_explorer FreeMe foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) target_link_libraries(${demo} ${PROJECT_NAME}) - install(TARGETS ${demo} RUNTIME DESTINATION &{DEMO_BIN}) - + install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) + set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked decore dock drag-button draw example.button example_combox example_listbox example_menu filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 - mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image + mbox menu_debug menu_popuper modal_form MontiHall place_login screen stretch_image threading thread-pool various_events window-dragger windows-subclassing ) - + # Pending: png + foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/Examples/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) target_link_libraries(${demo} ${PROJECT_NAME}) - install(TARGETS ${demo} RUNTIME DESTINATION &{DEMO_BIN}) + install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/Examples/") message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) From da585868883b1e1f969935e878a195a440cb5f67 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 16 Feb 2016 21:39:48 +0100 Subject: [PATCH 006/309] try png demo --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2728f9b4..24b23784 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,10 +219,10 @@ if (BUILD_NANA_DEMOS) decore dock drag-button draw example.button example_combox example_listbox example_menu filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 - mbox menu_debug menu_popuper modal_form MontiHall place_login screen stretch_image + mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image threading thread-pool various_events window-dragger windows-subclassing ) - # Pending: png + # Pending: foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/Examples/${demo}.cpp") From 4a0ca4f2f634e7deae00995b10a028ac2938a726 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 17 Feb 2016 01:50:34 +0100 Subject: [PATCH 007/309] updated to filesystem_selector --- build/vc2015/nana.vcxproj | 3 + build/vc2015/nana.vcxproj.filters | 8 ++ .../nana/filesystem/filesystem_selector.hpp | 81 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 include/nana/filesystem/filesystem_selector.hpp diff --git a/build/vc2015/nana.vcxproj b/build/vc2015/nana.vcxproj index e9c0aa02..ce428ef7 100644 --- a/build/vc2015/nana.vcxproj +++ b/build/vc2015/nana.vcxproj @@ -249,6 +249,9 @@ + + + diff --git a/build/vc2015/nana.vcxproj.filters b/build/vc2015/nana.vcxproj.filters index 0f547b4e..aaac3c60 100644 --- a/build/vc2015/nana.vcxproj.filters +++ b/build/vc2015/nana.vcxproj.filters @@ -49,6 +49,9 @@ {53feb93f-2b86-4bf5-b2f3-f60ef1bbbf76} + + {6caffbf6-c023-4dbf-ba69-cdb49feddb5d} + @@ -280,4 +283,9 @@ Source Files\gui\detail + + + Header Files\filesystem + + \ No newline at end of file diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp new file mode 100644 index 00000000..6b26b5d5 --- /dev/null +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -0,0 +1,81 @@ +/** +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file nana\filesystem\filesystem_selector.hpp +* @autor by Ariel Vina-Rodriguez: +* @brief A "ISO C++" filesystem Implementation selector +* The ISO C++ File System Technical Specification is optional. +* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf +* This is not a workaround, but an user option. +* The library maybe available in the std library in use or from Boost (almost compatible) +* http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm +* or you can choose to use the (partial, but functional) implementation provided by nana. +* If you include the file +* The selected option will be set by nana into std::experimental::filesystem +* By default Nana will use the ISO TS if available, or nana if not. +* Boost will be use only if explicitily changed +* nana Now mimic std::experimental::filesystem::v1 (boost v3) +* +*/ + +#ifndef NANA_FILESYSTEM_SELECTOR +#define NANA_FILESYSTEM_SELECTOR + +#include + +#if defined(NANA_BOOST_FILESYSTEM_AVAILABLE) && ( defined(NANA_BOOST_FILESYSTEM_FORCE) || (defined(STD_FILESYSTEM_NOT_SUPPORTED) && defined(NANA_BOOST_FILESYSTEM_PREFERRED) ) ) + +# include + // add boost::filesystem into std::experimental::filesystem + namespace std { + namespace experimental { +# ifdef CXX_NO_INLINE_NAMESPACE + using namespace boost::experimental; +# else + using namespace boost::experimental::v3; +# endif + + } + +#elif defined(STD_FILESYSTEM_NOT_SUPPORTED) + +# include + namespace std { + namespace experimental { +# ifdef CXX_NO_INLINE_NAMESPACE + using namespace nana::experimental; +# else + using namespace nana::experimental::v1; +# endif + } +} + +#else +# include +#endif + +#ifndef __cpp_lib_experimental_filesystem +# define __cpp_lib_experimental_filesystem 1 +#endif + +#if defined(NANA_WINDOWS) +constexpr auto def_root = "C:"; +constexpr auto def_rootstr = "C:\\"; +constexpr auto def_rootname = "Local Drive(C:)"; +#elif defined(NANA_LINUX) +constexpr auto def_root = "/"; +constexpr auto def_rootstr = "/"; +constexpr auto def_rootname = "Root/"; +#endif + +#endif // NANA_FILESYSTEM_SELECTOR // "Force use of Boost filesystem if available (over ISO)? + + + + + From d3120cbf35f6babcdf1c5fe59e5928d1026d6632 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 18 Feb 2016 01:01:55 +0800 Subject: [PATCH 008/309] optimize generated binary size --- include/nana/deploy.hpp | 4 +- include/nana/gui/detail/bedrock.hpp | 6 +- include/nana/gui/detail/color_schemes.hpp | 15 +- include/nana/gui/detail/events_operation.hpp | 1 + include/nana/gui/detail/general_events.hpp | 28 +- include/nana/gui/element.hpp | 3 +- include/nana/gui/programming_interface.hpp | 2 +- include/nana/gui/widgets/widget.hpp | 96 ++----- source/deploy.cpp | 4 +- source/gui/detail/bedrock_pi.cpp | 6 +- source/gui/detail/color_schemes.cpp | 18 +- source/gui/place.cpp | 269 ++++++++++--------- source/gui/place_parts.hpp | 83 +++--- source/gui/programming_interface.cpp | 4 +- source/gui/widgets/widget.cpp | 20 +- 15 files changed, 274 insertions(+), 285 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 35659972..19163c82 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -95,9 +95,9 @@ namespace std namespace nana { /// Checks whether a specified text is utf8 encoding - bool is_utf8(const char* str, unsigned len); + bool is_utf8(const char* str, std::size_t len); void throw_not_utf8(const std::string& text); - void throw_not_utf8(const char*, unsigned len); + void throw_not_utf8(const char*, std::size_t len); void throw_not_utf8(const char*); const std::string& to_utf8(const std::string&); diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index e4872711..e29c1758 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -1,7 +1,7 @@ /* * A Bedrock Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -78,8 +78,8 @@ namespace detail void define_state_cursor(core_window_t*, nana::cursor, thread_context*); void undefine_state_cursor(core_window_t*, thread_context*); - widget_colors& get_scheme_template(scheme_factory_base&&); - widget_colors* make_scheme(scheme_factory_base&&); + widget_colors& get_scheme_template(scheme_factory_interface&&); + widget_colors* make_scheme(scheme_factory_interface&&); events_operation& evt_operation(); window_manager& wd_manager(); diff --git a/include/nana/gui/detail/color_schemes.hpp b/include/nana/gui/detail/color_schemes.hpp index 9482f084..2d177c17 100644 --- a/include/nana/gui/detail/color_schemes.hpp +++ b/include/nana/gui/detail/color_schemes.hpp @@ -1,7 +1,7 @@ /* * Color Schemes * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -19,20 +19,21 @@ namespace nana { namespace detail { - class scheme_factory_base + class scheme_factory_interface { public: struct factory_identifier{}; - virtual ~scheme_factory_base() = default; + virtual ~scheme_factory_interface() = default; virtual factory_identifier* get_id() const = 0; virtual widget_colors* create() = 0; virtual widget_colors* create(widget_colors&) = 0; }; + template class scheme_factory - : public scheme_factory_base + : public scheme_factory_interface { private: factory_identifier* get_id() const override @@ -54,7 +55,7 @@ namespace nana }; template - scheme_factory_base::factory_identifier scheme_factory::fid_; + scheme_factory_interface::factory_identifier scheme_factory::fid_; class color_schemes { @@ -69,8 +70,8 @@ namespace nana color_schemes(); ~color_schemes(); - scheme& scheme_template(scheme_factory_base&&); - scheme* create(scheme_factory_base&&); + scheme& scheme_template(scheme_factory_interface&&); + scheme* create(scheme_factory_interface&&); private: implement * impl_; }; diff --git a/include/nana/gui/detail/events_operation.hpp b/include/nana/gui/detail/events_operation.hpp index 78f5c432..025ef5b1 100644 --- a/include/nana/gui/detail/events_operation.hpp +++ b/include/nana/gui/detail/events_operation.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #if defined(STD_THREAD_NOT_SUPPORTED) #include diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 446664fa..e801dba5 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -17,7 +17,6 @@ #include "internal_scope_guard.hpp" #include #include -#include #include namespace nana @@ -67,7 +66,7 @@ namespace nana protected: //class emit_counter is a RAII helper for emitting count //It is used for avoiding a try{}catch block which is required for some finial works when - //event handlers throw exceptions. + //event handlers throw exceptions. Precondition event_base.dockers_ != nullptr. class emit_counter { public: @@ -77,12 +76,10 @@ namespace nana event_base * const evt_; }; - //event_handle _m_emplace(::std::unique_ptr& docker_ptr, bool in_front); event_handle _m_emplace(detail::docker_interface*, bool in_front); protected: unsigned emitting_count_{ 0 }; bool deleted_flags_{ false }; - //std::unique_ptr>> dockers_; std::vector * dockers_{ nullptr }; }; }//end namespace detail @@ -172,27 +169,26 @@ namespace nana emit_counter ec(this); - auto& dockers = *dockers_; - const auto dockers_len = dockers_->size(); - //The dockers may resize when a new event handler is created by a calling handler. //Traverses with position can avaid crash error which caused by a iterator which becomes invalid. - for (std::size_t pos = 0; pos < dockers_len; ++pos) + + auto i = dockers_->data(); + auto const end = i + dockers_->size(); + + for (; i != end; ++i) { - auto docker_ptr = static_cast(dockers[pos]); - if (docker_ptr->flag_deleted) + if (static_cast(*i)->flag_deleted) continue; - docker_ptr->invoke(arg); + static_cast(*i)->invoke(arg); if (arg.propagation_stopped()) { - for (++pos; pos < dockers_len; ++pos) + for (++i; i != end; ++i) { - auto docker_ptr = static_cast(dockers[pos]); - if (!docker_ptr->unignorable || docker_ptr->flag_deleted) + if (!static_cast(*i)->unignorable || static_cast(*i)->flag_deleted) continue; - docker_ptr->invoke(arg); + static_cast(*i)->invoke(arg); } break; } @@ -274,7 +270,7 @@ namespace nana }; } }; - + template struct factory < std::function, false> { diff --git a/include/nana/gui/element.hpp b/include/nana/gui/element.hpp index 599aa87a..7f0a891c 100644 --- a/include/nana/gui/element.hpp +++ b/include/nana/gui/element.hpp @@ -1,7 +1,7 @@ /* * Elements of GUI Gadgets * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -88,7 +88,6 @@ namespace nana struct factory_interface : public detail::factory_abstract { - virtual ~factory_interface(){} virtual ElementInterface* create() const = 0; }; diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 8adfd2eb..c50f8f2e 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -46,7 +46,7 @@ namespace API { namespace detail { - ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_base&&); + ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_interface&&); } void effects_edge_nimbus(window, effects::edge_nimbus); diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 1fdb48fa..cfc174f7 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -1,7 +1,7 @@ /** * The fundamental widget class implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -132,9 +132,25 @@ namespace nana virtual nana::color _m_bgcolor() const; }; + namespace detail + { + class widget_base + : public widget + { + public: + ~widget_base(); + + window handle() const override; + private: + void _m_notify_destroy() override final; + protected: + window handle_{ nullptr }; + }; + } + /// Base class of all the classes defined as a widget window. Defaultly a widget_tag template - class widget_object: public widget + class widget_object: public detail::widget_base { protected: typedef DrawerTrigger drawer_trigger_t; @@ -147,12 +163,6 @@ namespace nana scheme_{ API::dev::make_scheme() } {} - ~widget_object() - { - if(handle_) - API::close_window(handle_); - } - event_type& events() const { return *events_; @@ -179,11 +189,6 @@ namespace nana return (this->empty() == false); } - window handle() const override - { - return handle_; - } - widget_object& borderless(bool enable) { API::widget_borderless(handle_, enable); @@ -214,13 +219,7 @@ namespace nana { return *events_; } - - void _m_notify_destroy() override final - { - handle_ = nullptr; - } private: - window handle_{nullptr}; DrawerTrigger trigger_; std::shared_ptr events_; std::unique_ptr scheme_; @@ -228,7 +227,7 @@ namespace nana /// Base class of all the classes defined as a non-graphics-buffer widget window. The second template parameter DrawerTrigger is always ignored.\see nana::panel template - class widget_object: public widget + class widget_object: public detail::widget_base { protected: typedef DrawerTrigger drawer_trigger_t; @@ -240,12 +239,6 @@ namespace nana : events_{ std::make_shared() }, scheme_{ API::dev::make_scheme() } {} - ~widget_object() - { - if(handle_) - API::close_window(handle_); - } - event_type& events() const { return *events_; @@ -269,12 +262,7 @@ namespace nana } return (this->empty() == false); } - - window handle() const override - { - return handle_; - } - + scheme_type& scheme() const { return *scheme_; @@ -284,13 +272,7 @@ namespace nana { return *events_; } - - void _m_notify_destroy() override final - { - handle_ = nullptr; - } private: - window handle_{nullptr}; std::shared_ptr events_; std::unique_ptr scheme_; };//end class widget_object @@ -298,7 +280,7 @@ namespace nana /// Base class of all the classes defined as a root window. \see nana::form template - class widget_object: public widget + class widget_object: public detail::widget_base { protected: typedef DrawerTrigger drawer_trigger_t; @@ -324,12 +306,6 @@ namespace nana _m_bind_and_attach(); } - ~widget_object() - { - if(handle_) - API::close_window(handle_); - } - event_type& events() const { return *events_; @@ -340,11 +316,6 @@ namespace nana API::activate_window(handle_); } - window handle() const override - { - return handle_; - } - native_window_type native_handle() const { return API::root(handle_); @@ -435,13 +406,7 @@ namespace nana { return *events_; } - - void _m_notify_destroy() override final - { - handle_ = nullptr; - } private: - window handle_; DrawerTrigger trigger_; std::shared_ptr events_; std::unique_ptr scheme_; @@ -453,7 +418,7 @@ namespace nana /// Especialization. Base class of all the classes defined as a frame window. \see nana::frame template - class widget_object: public widget + class widget_object: public detail::widget_base { protected: typedef int drawer_trigger_t; @@ -465,12 +430,6 @@ namespace nana : events_{ std::make_shared() }, scheme_{ API::dev::make_scheme() } {} - ~widget_object() - { - if(handle_) - API::close_window(handle_); - } - event_type& events() const { return *events_; @@ -494,11 +453,6 @@ namespace nana return (this->empty() == false); } - window handle() const override - { - return handle_; - } - scheme_type& scheme() const { return *scheme_; @@ -513,13 +467,7 @@ namespace nana { return *events_; } - - void _m_notify_destroy() override final - { - handle_ = nullptr; - } private: - window handle_{nullptr}; std::shared_ptr events_; std::unique_ptr scheme_; };//end class widget_object diff --git a/source/deploy.cpp b/source/deploy.cpp index 3592a3bf..6971d563 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -438,7 +438,7 @@ namespace std namespace nana { - bool is_utf8(const char* str, unsigned len) + bool is_utf8(const char* str, std::size_t len) { auto ustr = reinterpret_cast(str); auto end = ustr + len; @@ -474,7 +474,7 @@ namespace nana throw std::invalid_argument("The text is not encoded in UTF8"); } - void throw_not_utf8(const char* text, unsigned len) + void throw_not_utf8(const char* text, std::size_t len) { if (!is_utf8(text, len)) throw std::invalid_argument("The text is not encoded in UTF8"); diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 830887ea..7c7472bb 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -1,7 +1,7 @@ /* * A Bedrock Platform-Independent Implementation * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -198,12 +198,12 @@ namespace nana } } - widget_colors& bedrock::get_scheme_template(scheme_factory_base&& factory) + widget_colors& bedrock::get_scheme_template(scheme_factory_interface&& factory) { return pi_data_->scheme.scheme_template(std::move(factory)); } - widget_colors* bedrock::make_scheme(scheme_factory_base&& factory) + widget_colors* bedrock::make_scheme(scheme_factory_interface&& factory) { return pi_data_->scheme.create(std::move(factory)); } diff --git a/source/gui/detail/color_schemes.cpp b/source/gui/detail/color_schemes.cpp index c7fcd530..6cfa41d4 100644 --- a/source/gui/detail/color_schemes.cpp +++ b/source/gui/detail/color_schemes.cpp @@ -1,3 +1,15 @@ +/* +* Color Schemes +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file: nana/gui/color_schemes.cpp +*/ + #include #include @@ -57,7 +69,7 @@ namespace nana //class color_schemes struct color_schemes::implement { - std::map> scheme_template; + std::map> scheme_template; }; color_schemes::color_schemes() @@ -70,7 +82,7 @@ namespace nana delete impl_; } - auto color_schemes::scheme_template(scheme_factory_base&& factory) -> scheme& + auto color_schemes::scheme_template(scheme_factory_interface&& factory) -> scheme& { auto & tmpl_scheme = impl_->scheme_template[factory.get_id()]; @@ -81,7 +93,7 @@ namespace nana return *tmpl_scheme.get(); } - widget_colors* color_schemes::create(scheme_factory_base&& factory) + widget_colors* color_schemes::create(scheme_factory_interface&& factory) { return factory.create(scheme_template(std::move(factory))); } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index d6adb5d0..b7fadf7f 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -1346,74 +1346,77 @@ namespace nana splitter_.cursor(splitter_cursor_); dragger_.trigger(splitter_); - splitter_.events().mouse_down.connect_unignorable([this](const arg_mouse& arg) + + auto grab_fn = [this](const arg_mouse& arg) { if (false == arg.left_button) return; - begin_point_ = splitter_.pos(); - - auto px_ptr = &nana::rectangle::width; - - //Use field_area of leaf, not margin_area. Otherwise splitter would be at wrong position - auto area_left = _m_leaf_left()->field_area; - auto area_right = _m_leaf_right()->field_area; - - if (nana::cursor::size_we != splitter_cursor_) + if (event_code::mouse_down == arg.evt_code) { - left_pos_ = area_left.y; - right_pos_ = area_right.bottom(); - px_ptr = &nana::rectangle::height; + begin_point_ = splitter_.pos(); + + auto px_ptr = &nana::rectangle::width; + + //Use field_area of leaf, not margin_area. Otherwise splitter would be at wrong position + auto area_left = _m_leaf_left()->field_area; + auto area_right = _m_leaf_right()->field_area; + + if (nana::cursor::size_we != splitter_cursor_) + { + left_pos_ = area_left.y; + right_pos_ = area_right.bottom(); + px_ptr = &nana::rectangle::height; + } + else + { + left_pos_ = area_left.x; + right_pos_ = area_right.right(); + } + + left_pixels_ = area_left.*px_ptr; + right_pixels_ = area_right.*px_ptr; } - else + else if (event_code::mouse_move == arg.evt_code) { - left_pos_ = area_left.x; - right_pos_ = area_right.right(); + const bool vert = (::nana::cursor::size_we != splitter_cursor_); + auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w(); + int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x); + + int total_pixels = static_cast(left_pixels_ + right_pixels_); + + auto left_px = static_cast(left_pixels_) + delta; + if (left_px > total_pixels) + left_px = total_pixels; + else if (left_px < 0) + left_px = 0; + + double imd_rate = 100.0 / area_px; + left_px = static_cast(limit_px(_m_leaf_left(), left_px, area_px)); + _m_leaf_left()->weight.assign_percent(imd_rate * left_px); + + auto right_px = static_cast(right_pixels_) - delta; + if (right_px > total_pixels) + right_px = total_pixels; + else if (right_px < 0) + right_px = 0; + + right_px = static_cast(limit_px(_m_leaf_right(), right_px, area_px)); + _m_leaf_right()->weight.assign_percent(imd_rate * right_px); + + pause_move_collocate_ = true; + div_owner->collocate(splitter_.parent()); + + //After the collocating, the splitter keeps the calculated weight of left division, + //and clear the weight of right division. + _m_leaf_right()->weight.reset(); + + pause_move_collocate_ = false; } + }; - left_pixels_ = area_left.*px_ptr; - right_pixels_ = area_right.*px_ptr; - }); - - splitter_.events().mouse_move.connect_unignorable([this](const arg_mouse& arg) - { - if (false == arg.left_button) - return; - - const bool vert = (::nana::cursor::size_we != splitter_cursor_); - auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w(); - int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x); - - int total_pixels = static_cast(left_pixels_ + right_pixels_); - - auto left_px = static_cast(left_pixels_)+delta; - if (left_px > total_pixels) - left_px = total_pixels; - else if (left_px < 0) - left_px = 0; - - double imd_rate = 100.0 / area_px; - left_px = static_cast(limit_px(_m_leaf_left(), left_px, area_px)); - _m_leaf_left()->weight.assign_percent(imd_rate * left_px); - - auto right_px = static_cast(right_pixels_)-delta; - if (right_px > total_pixels) - right_px = total_pixels; - else if (right_px < 0) - right_px = 0; - - right_px = static_cast(limit_px(_m_leaf_right(), right_px, area_px)); - _m_leaf_right()->weight.assign_percent(imd_rate * right_px); - - pause_move_collocate_ = true; - div_owner->collocate(splitter_.parent()); - - //After the collocating, the splitter keeps the calculated weight of left division, - //and clear the weight of right division. - _m_leaf_right()->weight.reset(); - - pause_move_collocate_ = false; - }); + splitter_.events().mouse_down.connect_unignorable(grab_fn); + splitter_.events().mouse_move.connect_unignorable(grab_fn); } auto limited_range = _m_update_splitter_range(); @@ -1621,7 +1624,7 @@ namespace nana indicator_.docker->z_order(nullptr, ::nana::z_order_action::topmost); indicator_.docker->show(); - indicator_.docker->events().destroy([this] + indicator_.docker->events().destroy([this](const arg_destroy&) { if (indicator_.dock_area) { @@ -1764,81 +1767,86 @@ namespace nana this->bgcolor(colors::alice_blue); this->cursor(_m_is_vert(dir_) ? ::nana::cursor::size_ns : ::nana::cursor::size_we); - this->events().mouse_down([this](const arg_mouse& arg) + + auto grab_fn = [this, wd](const arg_mouse& arg) { - if (arg.button != ::nana::mouse::left_button) - return; - - bool is_vert = _m_is_vert(dir_); - - API::capture_window(this->handle(), true); - auto basepos = API::cursor_position(); - base_pos_.x = (is_vert ? basepos.y : basepos.x); - - basepos = this->pos(); - base_pos_.y = (is_vert ? basepos.y : basepos.x); - - base_px_ = (is_vert ? pane_dv_->field_area.height : pane_dv_->field_area.width); - }); - - this->events().mouse_up([this] - { - API::capture_window(this->handle(), false); - }); - - this->events().mouse_move([this, wd](const arg_mouse& arg) - { - if (!arg.is_left_button()) - return; - - auto now_pos = API::cursor_position(); - int delta = (_m_is_vert(dir_) ? now_pos.y : now_pos.x) - base_pos_.x; - int new_pos = base_pos_.y + delta; - if (new_pos < range_.x) + if (event_code::mouse_down == arg.evt_code) //press mouse button { - new_pos = range_.x; - delta = new_pos - base_pos_.y; - } - else if (new_pos >= range_.y) - { - new_pos = range_.y - 1; - delta = new_pos - base_pos_.y; - } + if (arg.button != ::nana::mouse::left_button) + return; - now_pos = this->pos(); - if (_m_is_vert(dir_)) - now_pos.y = new_pos; + bool is_vert = _m_is_vert(dir_); + + API::capture_window(this->handle(), true); + auto basepos = API::cursor_position(); + base_pos_.x = (is_vert ? basepos.y : basepos.x); + + basepos = this->pos(); + base_pos_.y = (is_vert ? basepos.y : basepos.x); + + base_px_ = (is_vert ? pane_dv_->field_area.height : pane_dv_->field_area.width); + } + else if (event_code::mouse_move == arg.evt_code) //hover + { + if (!arg.is_left_button()) + return; + + auto now_pos = API::cursor_position(); + int delta = (_m_is_vert(dir_) ? now_pos.y : now_pos.x) - base_pos_.x; + int new_pos = base_pos_.y + delta; + if (new_pos < range_.x) + { + new_pos = range_.x; + delta = new_pos - base_pos_.y; + } + else if (new_pos >= range_.y) + { + new_pos = range_.y - 1; + delta = new_pos - base_pos_.y; + } + + now_pos = this->pos(); + if (_m_is_vert(dir_)) + now_pos.y = new_pos; + else + now_pos.x = new_pos; + this->move(now_pos); + + auto px = base_px_; + switch (dir_) + { + case ::nana::direction::west: + case ::nana::direction::north: + if (delta < 0) + px -= static_cast(-delta); + else + px += static_cast(delta); + break; + case ::nana::direction::east: + case ::nana::direction::south: + if (delta < 0) + px += static_cast(-delta); + else + px -= static_cast(delta); + break; + default: + break; + } + + auto dock_px = (_m_is_vert(dir_) ? dock_dv_->field_area.height : dock_dv_->field_area.width); + + pane_dv_->weight.assign_percent(double(px) / double(dock_px) * 100); + + dock_dv_->collocate(wd); + } else - now_pos.x = new_pos; - this->move(now_pos); + API::capture_window(this->handle(), false); //release mouse button + }; - auto px = base_px_; - switch (dir_) - { - case ::nana::direction::west: - case ::nana::direction::north: - if (delta < 0) - px -= static_cast(-delta); - else - px += static_cast(delta); - break; - case ::nana::direction::east: - case ::nana::direction::south: - if (delta < 0) - px += static_cast(-delta); - else - px -= static_cast(delta); - break; - default: - break; - } - - auto dock_px = (_m_is_vert(dir_) ? dock_dv_->field_area.height : dock_dv_->field_area.width); - - pane_dv_->weight.assign_percent(double(px) / double(dock_px) * 100); - - dock_dv_->collocate(wd); - }); + auto & evt = this->events(); + evt.mouse_down(grab_fn); + evt.mouse_up(grab_fn); + evt.mouse_move(grab_fn); } void range(int begin, int end) @@ -1867,6 +1875,7 @@ namespace nana if (i->get()->display) return i->get(); } + return nullptr; } diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 25708b93..1832d74a 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -1,7 +1,7 @@ /* * Parts of Class Place * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -233,45 +233,50 @@ namespace nana } }); - caption_.events().mouse_down([this](const arg_mouse& arg) + auto grab_fn = [this](const arg_mouse& arg) { - if (::nana::mouse::left_button == arg.button) + if (event_code::mouse_down == arg.evt_code) { - moves_.started = true; - moves_.start_pos = API::cursor_position(); - moves_.start_container_pos = (floating() ? container_->pos() : this->pos()); - API::capture_window(caption_, true); - } - }); - - caption_.events().mouse_move([this](const arg_mouse& arg) - { - if (arg.left_button && moves_.started) - { - auto move_pos = API::cursor_position() - moves_.start_pos; - if (!floating()) + if (::nana::mouse::left_button == arg.button) { - if (std::abs(move_pos.x) > 4 || std::abs(move_pos.y) > 4) - float_away(move_pos); - } - else - { - move_pos += moves_.start_container_pos; - API::move_window(container_->handle(), move_pos); - notifier_->notify_move(); + moves_.started = true; + moves_.start_pos = API::cursor_position(); + moves_.start_container_pos = (floating() ? container_->pos() : this->pos()); + API::capture_window(caption_, true); } } - }); - - caption_.events().mouse_up([this](const arg_mouse& arg) - { - if ((::nana::mouse::left_button == arg.button) && moves_.started) + else if (event_code::mouse_move == arg.evt_code) { - moves_.started = false; - API::capture_window(caption_, false); - notifier_->notify_move_stopped(); + if (arg.left_button && moves_.started) + { + auto move_pos = API::cursor_position() - moves_.start_pos; + if (!floating()) + { + if (std::abs(move_pos.x) > 4 || std::abs(move_pos.y) > 4) + float_away(move_pos); + } + else + { + move_pos += moves_.start_container_pos; + API::move_window(container_->handle(), move_pos); + notifier_->notify_move(); + } + } } - }); + else if (event_code::mouse_up == arg.evt_code) + { + if ((::nana::mouse::left_button == arg.button) && moves_.started) + { + moves_.started = false; + API::capture_window(caption_, false); + notifier_->notify_move_stopped(); + } + } + }; + + caption_.events().mouse_down(grab_fn); + caption_.events().mouse_move(grab_fn); + caption_.events().mouse_up(grab_fn); } @@ -293,13 +298,13 @@ namespace nana tabbar_.reset(new tabbar_lite(*this)); tabbar_->events().selected.clear(); - tabbar_->events().selected([this] + tabbar_->events().selected([this](const event_arg&) { auto handle = tabbar_->attach(tabbar_->selected()); - if (handle) - caption_.caption(API::window_caption(handle)); - else - caption_.caption(::std::string()); + + //Set caption through a caption of window specified by handle + //Empty if handle is null + caption_.caption(API::window_caption(handle)); }); tabbar_->move({ 0, r.bottom() - 20, r.width, 20 }); @@ -320,7 +325,7 @@ namespace nana if (tabbar_) { - tabbar_->push_back(::nana::charset(wdg->caption())); + tabbar_->push_back(wdg->caption()); tabbar_->attach(panels_.size(), wdg->handle()); } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index a5f96e98..f653069c 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -55,9 +55,9 @@ namespace API namespace detail { - ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_base&& factory) + ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_interface&& factory) { - return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_base&&>(factory)); + return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_interface&&>(factory)); } bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg) diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index 5982ea71..1169e59e 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -1,6 +1,6 @@ /* * The fundamental widget class implementation - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -370,6 +370,24 @@ namespace nana { return std::unique_ptr(new widget::inner_widget_notifier(*wdg)); } + + //class widget_base + widget_base::~widget_base() + { + if (handle_) + API::close_window(handle_); + } + + window widget_base::handle() const + { + return handle_; + } + + void widget_base::_m_notify_destroy() + { + handle_ = nullptr; + } + //end class widget_base } }//end namespace nana From 2806908f63ad91ce1052dab238bfd6602ad5a98c Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 18 Feb 2016 08:21:50 +0100 Subject: [PATCH 009/309] filesystem ext --- include/nana/filesystem/filesystem_ext.hpp | 30 +++++++++++++++++++ .../nana/filesystem/filesystem_selector.hpp | 11 +------ 2 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 include/nana/filesystem/filesystem_ext.hpp diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp new file mode 100644 index 00000000..1f5d4317 --- /dev/null +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -0,0 +1,30 @@ +/** +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file nana\filesystem\filesystem_ext.hpp +* @autor by Ariel Vina-Rodriguez: +* @brief Some convenient extensions to the filesystem library. +* +*/ + +#ifndef NANA_FILESYSTEM_EXT_HPP +#define NANA_FILESYSTEM_EXT_HPP + +#if defined(NANA_WINDOWS) + constexpr auto def_root = "C:"; + constexpr auto def_rootstr = "C:\\"; + constexpr auto def_rootname = "Local Drive(C:)"; +#elif defined(NANA_LINUX) + constexpr auto def_root = "/"; + constexpr auto def_rootstr = "/"; + constexpr auto def_rootname = "Root/"; +#endif + +// nana::experimental::filesystem::path_user()); // REPLACE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! to filesystem_ext.hhp + +#endif //NANA_FILESYSTEM_EXT_HPP diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index 6b26b5d5..a91e903d 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -63,17 +63,8 @@ # define __cpp_lib_experimental_filesystem 1 #endif -#if defined(NANA_WINDOWS) -constexpr auto def_root = "C:"; -constexpr auto def_rootstr = "C:\\"; -constexpr auto def_rootname = "Local Drive(C:)"; -#elif defined(NANA_LINUX) -constexpr auto def_root = "/"; -constexpr auto def_rootstr = "/"; -constexpr auto def_rootname = "Root/"; -#endif -#endif // NANA_FILESYSTEM_SELECTOR // "Force use of Boost filesystem if available (over ISO)? +#endif // NANA_FILESYSTEM_SELECTOR From 9e686eb5d62cf41177697a9f9369b24b207adbc3 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 18 Feb 2016 10:54:14 +0100 Subject: [PATCH 010/309] cleanup use of namespace filesystem --- include/nana/filesystem/filesystem.hpp | 14 +++----- include/nana/filesystem/filesystem_ext.hpp | 14 ++++++++ .../nana/filesystem/filesystem_selector.hpp | 33 ++++++++++++------- source/filesystem/filesystem.cpp | 10 +++--- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index a3a3e373..61ce8223 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -40,18 +40,14 @@ #include - // namespace std { namespace experimental { namespace filesystem { inline namespace v1 { - -namespace nana { namespace experimental { - -#ifndef CXX_NO_INLINE_NAMESPACE -inline namespace v1 +namespace nana { namespace experimental { namespace filesystem { +#ifndef CXX_NO_INLINE_NAMESPACE + inline namespace v1 + { #endif -namespace filesystem -{ - enum class file_type + enum class file_type { none = 0, ///< has not been determined or an error occurred while trying to determine not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 1f5d4317..0e75b249 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -15,6 +15,7 @@ #ifndef NANA_FILESYSTEM_EXT_HPP #define NANA_FILESYSTEM_EXT_HPP +namespace nana {namespace experimental {namespace filesystem {namespace ext { #if defined(NANA_WINDOWS) constexpr auto def_root = "C:"; constexpr auto def_rootstr = "C:\\"; @@ -27,4 +28,17 @@ // nana::experimental::filesystem::path_user()); // REPLACE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! to filesystem_ext.hhp +template // DI = directory_iterator from std, boost, or nana +class directory_only_iterator : public DI +{ + // if (!this->is_directory()) continue; +}; + +template // DI = directory_iterator from std, boost, or nana +class regular_file_only_iterator : public DI +{ + // if (this->is_directory()) continue; +}; + + }}}} #endif //NANA_FILESYSTEM_EXT_HPP diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index a91e903d..b168ce30 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -31,29 +31,40 @@ #if defined(NANA_BOOST_FILESYSTEM_AVAILABLE) && ( defined(NANA_BOOST_FILESYSTEM_FORCE) || (defined(STD_FILESYSTEM_NOT_SUPPORTED) && defined(NANA_BOOST_FILESYSTEM_PREFERRED) ) ) # include + // add boost::filesystem into std::experimental::filesystem - namespace std { - namespace experimental { +namespace std { + namespace experimental { + namespace filesystem { + # ifdef CXX_NO_INLINE_NAMESPACE - using namespace boost::experimental; + using namespace boost::experimental::filesystem; # else - using namespace boost::experimental::v3; + using namespace boost::experimental::filesystem::v3; # endif - } + } // filesystem + } // experimental +} // std + #elif defined(STD_FILESYSTEM_NOT_SUPPORTED) # include - namespace std { - namespace experimental { + +namespace std { + namespace experimental { + namespace filesystem { + # ifdef CXX_NO_INLINE_NAMESPACE - using namespace nana::experimental; + using namespace nana::experimental::filesystem; # else - using namespace nana::experimental::v1; + using namespace nana::experimental::filesystem::v1; # endif - } -} + + } // filesystem + } // experimental +} // std #else # include diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index aca26162..3f432fbd 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -37,12 +37,12 @@ #endif -namespace nana { namespace experimental { -#ifndef CXX_NO_INLINE_NAMESPACE - inline namespace v1 { -#endif - namespace filesystem +namespace nana { namespace experimental { namespace filesystem { +#ifndef CXX_NO_INLINE_NAMESPACE + inline namespace v1 { +#endif + //class filesystem_error filesystem_error::filesystem_error(const std::string& msg, std::error_code err) : std::system_error(err, msg) From 0e0f1cfb7fc21da61bc779b99f7dee2237f58f49 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 18 Feb 2016 11:45:10 +0100 Subject: [PATCH 011/309] update readme [skip ci] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b985907..cd9a692d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Nana C++ Library -[Linux (gcc 5, including demos) ![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) +[Linux (gcc 5.2.1 and 4.9.2)![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) including [(nana-demos)](https://github.com/qPCR4vir/nana-demo) -[Windows (VC2015) ![AppVeyor uild status](https://ci.appveyor.com/api/projects/status/5j79p9fi887usv7h?svg=true)](https://ci.appveyor.com/project/qPCR4vir/nana) +[Windows (Microsoft (R) Build Engine version 14.0.24720.0) ![AppVeyor uild status](https://ci.appveyor.com/api/projects/status/5j79p9fi887usv7h?svg=true)](https://ci.appveyor.com/project/qPCR4vir/nana) [![Licence](https://img.shields.io/badge/license-BSL-blue.svg?style=flat)](LICENSE_1_0.txt) From a839cf8deb5db177e15e4043fe80f61770bc924d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 19 Feb 2016 00:49:32 +0800 Subject: [PATCH 012/309] optimize generated binary size --- include/nana/gui/detail/general_events.hpp | 32 +++++++++++++---- .../widgets/skeletons/text_token_stream.hpp | 19 ++-------- source/gui/detail/bedrock_windows.cpp | 6 ++-- source/gui/msgbox.cpp | 29 ++++++++------- source/gui/place.cpp | 4 +-- source/gui/place_parts.hpp | 8 +---- source/gui/widgets/button.cpp | 2 +- source/gui/widgets/categorize.cpp | 2 +- source/gui/widgets/combox.cpp | 36 +++++++++---------- source/gui/widgets/listbox.cpp | 2 -- source/gui/widgets/textbox.cpp | 13 ++----- 11 files changed, 68 insertions(+), 85 deletions(-) diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index e801dba5..0ff84083 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -231,11 +231,6 @@ namespace nana }; } - static std::function build_second(fn_type&& fn, void(fn_type::*)(arg_reference)) - { - return std::move(fn); - } - template static std::function build_second(Tfn&& fn, Ret(fn_type::*)()const) { @@ -245,11 +240,36 @@ namespace nana }; } + static std::function build_second(fn_type&& fn, void(fn_type::*)(arg_reference)) + { + return std::move(fn); + } + static std::function build_second(fn_type&& fn, void(fn_type::*)(arg_reference) const) { return std::move(fn); } + static std::function build_second(fn_type& fn, void(fn_type::*)(arg_reference)) + { + return fn; + } + + static std::function build_second(fn_type& fn, void(fn_type::*)(arg_reference) const) + { + return fn; + } + + static std::function build_second(const fn_type& fn, void(fn_type::*)(arg_reference)) + { + return fn; + } + + static std::function build_second(const fn_type& fn, void(fn_type::*)(arg_reference) const) + { + return fn; + } + template static std::function build_second(Tfn&& fn, Ret(fn_type::*)(Arg2)) { @@ -259,7 +279,7 @@ namespace nana fn(arg); }; } - + template static std::function build_second(Tfn&& fn, Ret(fn_type::*)(Arg2)const) { diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index 7fbd3801..f529299b 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -15,7 +15,6 @@ #include -#include #include #include #include @@ -86,26 +85,12 @@ namespace nana{ namespace widgets{ namespace skeletons std::pair binary_number() const { - std::stringstream ss; - ss<(nana::charset(binary_.first))<<' '<(nana::charset(binary_.second)); - - std::pair r; - ss>>r.first>>r.second; - return r; + return{ std::stoul(binary_.first), std::stoul(binary_.second) }; } int number() const { - std::stringstream ss; - ss<(nana::charset(idstr_)); - - //It's a hex number. - if(idstr_.size() > 2 && idstr_[0] == '0' && (idstr_[1] == 'x' || idstr_[1] == 'X')) - ss>>std::hex; - - int n; - ss>>n; - return n; + return std::stoi(idstr_, nullptr, 0); } private: static bool _m_unicode_word_breakable(wchar_t ch) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 2915ec1c..1f557bca 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -252,9 +251,8 @@ namespace detail { if(wd_manager().number_of_core_window()) { - std::stringstream ss; - ss<<"Nana.GUI detects a memory leaks in window_manager, "<(wd_manager().number_of_core_window())<<" window(s) are not uninstalled."; - ::MessageBoxA(0, ss.str().c_str(), ("Nana C++ Library"), MB_OK); + std::string msg = "Nana.GUI detects a memory leaks in window_manager, " + std::to_string(wd_manager().number_of_core_window()) + " window(s) are not uninstalled."; + ::MessageBoxA(0, msg.c_str(), ("Nana C++ Library"), MB_OK); } delete impl_; diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index dd20cf6e..4b5cb5f3 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -708,7 +708,7 @@ namespace nana impl->spinbox.size({ value_px, 24 }); }); - impl->spinbox.events().destroy.connect_unignorable([impl] + impl->spinbox.events().destroy.connect_unignorable([impl](const arg_destroy&) { impl->value = impl->spinbox.to_int(); }); @@ -786,7 +786,7 @@ namespace nana impl->spinbox.size(::nana::size{ value_px, 24 }); }); - impl->spinbox.events().destroy.connect_unignorable([impl] + impl->spinbox.events().destroy.connect_unignorable([impl](const arg_destroy&) { impl->value = impl->spinbox.to_double(); }); @@ -913,7 +913,7 @@ namespace nana }); auto & wdg = (value_px ? static_cast(impl->combox) : static_cast(impl->textbox)); - wdg.events().destroy.connect_unignorable([&wdg, impl] + wdg.events().destroy.connect_unignorable([&wdg, impl](const arg_destroy&) { impl->value = wdg.caption(); }); @@ -1028,16 +1028,19 @@ namespace nana impl->wdg_year.size(sz); }); - impl->wdg_day.events().destroy.connect_unignorable([impl] + auto destroy_fn = [impl](const arg_destroy& arg) { - impl->day = impl->wdg_day.to_int(); - impl->month = static_cast(impl->wdg_month.option()) + 1; - }); + if (arg.window_handle == impl->wdg_day.handle()) + { + impl->day = impl->wdg_day.to_int(); + impl->month = static_cast(impl->wdg_month.option()) + 1; + } + else if(arg.window_handle == impl->wdg_year.handle()) + impl->year = impl->wdg_year.to_int(); + }; - impl->wdg_year.events().destroy.connect_unignorable([impl] - { - impl->year = impl->wdg_year.to_int(); - }); + impl->wdg_day.events().destroy.connect_unignorable(destroy_fn); + impl->wdg_year.events().destroy.connect_unignorable(destroy_fn); auto make_days = [impl] { @@ -1123,7 +1126,7 @@ namespace nana impl->browse.create(impl->dock); impl->browse.i18n(i18n_eval("Browse")); - impl->browse.events().click([wd, impl] + impl->browse.events().click([wd, impl](const arg_click&) { impl->fbox.owner(wd); if (impl->fbox.show()) @@ -1140,7 +1143,7 @@ namespace nana impl->browse.move({static_cast(arg.width - 60), 0, 60, arg.height}); }); - impl->path_edit.events().destroy.connect_unignorable([impl] + impl->path_edit.events().destroy.connect_unignorable([impl](const arg_destroy&) { impl->value = impl->path_edit.caption(); }); diff --git a/source/gui/place.cpp b/source/gui/place.cpp index b7fadf7f..d0796c90 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -304,9 +304,7 @@ namespace nana void _m_throw_error(const std::string& err) { - std::stringstream ss; - ss << "place: " << err << " at " << static_cast(sp_ - divstr_); - throw std::runtime_error(ss.str()); + throw std::runtime_error("nana::place: " + err + " at " + std::to_string(static_cast(sp_ - divstr_))); } void _m_attr_number_value() diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 1832d74a..1d21d600 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -203,7 +203,6 @@ namespace nana destroy_dockarea = (0 == tabbar_->length()); } - if (destroy_dockarea) notifier_->request_close(); }); @@ -224,7 +223,6 @@ namespace nana else r.height = arg.height - 20; } - for (auto & pn : panels_) { @@ -313,7 +311,7 @@ namespace nana std::size_t pos = 0; for (auto & pn : panels_) { - tabbar_->push_back(::nana::charset(pn.widget_ptr->caption())); + tabbar_->push_back(pn.widget_ptr->caption()); tabbar_->attach(pos++, *pn.widget_ptr); } } @@ -330,9 +328,7 @@ namespace nana } if (panels_.empty()) - { caption_.caption(wdg->caption()); - } panels_.emplace_back(); panels_.back().widget_ptr.swap(wdg); @@ -359,8 +355,6 @@ namespace nana graph.rectangle(false, colors::coral); }); - - API::set_parent_window(handle(), container_->handle()); this->move({ 1, 1 }); diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index 301c07c7..1b7aa835 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -479,7 +479,7 @@ namespace nana{ namespace drawerbase void button::_m_complete_creation() { - events().shortkey.connect_unignorable([this] + events().shortkey.connect_unignorable([this](const arg_keyboard&) { get_drawer_trigger().emit_click(); }); diff --git a/source/gui/widgets/categorize.cpp b/source/gui/widgets/categorize.cpp index 3c10b41f..230369c8 100644 --- a/source/gui/widgets/categorize.cpp +++ b/source/gui/widgets/categorize.cpp @@ -571,7 +571,7 @@ namespace nana style_.listbox = &(form_loader()(window_, r, true)); style_.listbox->set_module(style_.module, 16); - style_.listbox->events().destroy.connect_unignorable([this] + style_.listbox->events().destroy.connect_unignorable([this](const arg_destroy&) { //Close list when listbox is destoryed style_.mode = mode::normal; diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index c5df35f8..6d803e18 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -1,7 +1,7 @@ /* * A Combox Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -253,12 +253,25 @@ namespace nana state_.lister->renderer(item_renderer_); state_.lister->set_module(module_, image_pixels_); state_.item_index_before_selection = module_.index; + //The lister window closes by itself. I just take care about the destroy event. //The event should be destroy rather than unload. Because the unload event is invoked while //the lister is not closed, if popuping a message box, the lister will cover the message box. - state_.lister->events().destroy.connect_unignorable([this] + state_.lister->events().destroy.connect_unignorable([this](const arg_destroy&) { - _m_lister_close_sig(); + state_.lister = nullptr; //The lister closes by itself. + if ((module_.index != nana::npos) && (module_.index != state_.item_index_before_selection)) + { + option(module_.index, true); + API::update_window(*widget_); + } + else + { + //Redraw the widget even though the index has not been changed, + //because the push button should be updated due to the state + //changed from pressed to normal/hovered. + API::refresh_window(*widget_); + } }); } } @@ -432,23 +445,6 @@ namespace nana return true; } private: - void _m_lister_close_sig() - { - state_.lister = nullptr; //The lister closes by itself. - if ((module_.index != nana::npos) && (module_.index != state_.item_index_before_selection)) - { - option(module_.index, true); - API::update_window(*widget_); - } - else - { - //Redraw the widget even though the index has not been changed, - //because the push button should be updated due to the state - //changed from pressed to normal/hovered. - API::refresh_window(*widget_); - } - } - void _m_draw_push_button(bool enabled) { ::nana::rectangle r{graph_->size()}; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 5dc59321..96b423e3 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3770,8 +3770,6 @@ namespace nana else if (ess_->lister.last_selected_abs == pos_) ess_->lister.last_selected_abs.set_both(npos); - ess_->update(); - ess_->update(); return *this; } diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index a4d4d499..fe140e41 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -13,7 +13,6 @@ #include #include #include -#include namespace nana { @@ -495,11 +494,7 @@ namespace drawerbase { auto s = _m_caption(); if (s.empty()) return 0; - std::stringstream ss; - int value; - ss << to_utf8(s); - ss >> value; - return value; + return std::stoi(s, nullptr, 0); } double textbox::to_double() const @@ -507,11 +502,7 @@ namespace drawerbase { auto s = _m_caption(); if (s.empty()) return 0; - std::stringstream ss; - double value; - ss << to_utf8(s); - ss >> value; - return value; + return std::stod(s); } textbox& textbox::from(int n) From 6d84be2051ad471323a34041b2d153b1e2733419 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 18 Feb 2016 15:38:33 +0100 Subject: [PATCH 013/309] working on directory_only_iterator --- include/nana/filesystem/filesystem.hpp | 13 +++--- include/nana/filesystem/filesystem_ext.hpp | 48 +++++++++++++++++++--- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 61ce8223..88b9dbd0 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -297,15 +297,12 @@ namespace nana { namespace experimental { namespace filesystem std::uintmax_t file_size(const path& p); //uintmax_t file_size(const path& p, error_code& ec) noexcept; - inline bool is_directory(file_status s) { return s.type() == file_type::directory ;} - bool is_directory(const path& p); - inline bool is_directory(const directory_entry& d) - { - return is_directory(d.status()); - } - //bool is_directory(const path& p, error_code& ec) noexcept; + inline bool is_directory(file_status s) noexcept + { return s.type() == file_type::directory ;} - //bool is_regular_file(file_status s) noexcept; + bool is_directory(const path& p); + + //bool is_directory(const path& p, error_code& ec) noexcept; inline bool is_empty(const path& p) { diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 0e75b249..35aeec7c 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -26,18 +26,56 @@ namespace nana {namespace experimental {namespace filesystem {namespace ext { constexpr auto def_rootname = "Root/"; #endif -// nana::experimental::filesystem::path_user()); // REPLACE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! to filesystem_ext.hhp +// nana::experimental::filesystem::path_user()); // REPLACE !!!!!!!!!! to filesystem_ext.hhp -template // DI = directory_iterator from std, boost, or nana +inline bool is_directory(const directory_entry& d) noexcept +{ + return is_directory(d.status()); +} + + +template // DI = directory_iterator from std, boost, or nana : return directory_entry class directory_only_iterator : public DI { - // if (!this->is_directory()) continue; + DI& find_first() + { + while(( (*this) != DI{}) || !is_directory((*this)) ) + this->DI::operator++(); + return (*this); + } +public: + template + directory_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) + { + find_first(); + } + directory_only_iterator& operator++() + { + this->DI::operator++(); + return find_first(); + } }; -template // DI = directory_iterator from std, boost, or nana +template // DI = directory_iterator from std, boost, or nana : value_type directory_entry class regular_file_only_iterator : public DI { - // if (this->is_directory()) continue; + DI& find_first() + { + while(( (*this) != DI{}) || !is_regular_file(*this) ) + this->DI::operator++(); + return (*this); + } +public: + template + regular_file_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) + { + find_first(); + } + regular_file_only_iterator& operator++() + { + this->DI::operator++(); + return find_first(); + } }; }}}} From d8a06989f34d48afb990654e499b47e67e687846 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 18 Feb 2016 16:00:17 +0100 Subject: [PATCH 014/309] working on directory_only_iterator --- include/nana/filesystem/filesystem_ext.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 35aeec7c..90b9978d 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -39,7 +39,7 @@ class directory_only_iterator : public DI { DI& find_first() { - while(( (*this) != DI{}) || !is_directory((*this)) ) + while(( (*this) != DI{}) || !is_directory((*this)->status()) ) this->DI::operator++(); return (*this); } @@ -61,7 +61,7 @@ class regular_file_only_iterator : public DI { DI& find_first() { - while(( (*this) != DI{}) || !is_regular_file(*this) ) + while(( (*this) != DI{}) || !is_regular_file((*this)->status()) ) this->DI::operator++(); return (*this); } From 9f430f7220a6f2b3870fb7652549dfcd52df4183 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 19 Feb 2016 13:52:15 +0100 Subject: [PATCH 015/309] more standard features for filesystem --- include/nana/filesystem/filesystem.hpp | 70 +++++++++++++++----------- source/filesystem/filesystem.cpp | 8 +-- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 88b9dbd0..c44345c6 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -1,4 +1,4 @@ -/* +/** * A ISO C++ filesystem Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,17 +7,17 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/filesystem/filesystem.hpp - * Modiffied by Ariel Vina-Rodriguez: - * Now mimic std::experimental::filesystem::v1 (boost v3) - * and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013 + * @file nana/filesystem/filesystem.hpp + * @author Jinhao, conributed: Ariel Vina-Rodriguez + * @brief Mimic std::experimental::filesystem::v1 (boost v3) + * and need VC2015 or a C++11 compiler. With a few correction can be compiler by VC2013 */ +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 2014-07-04 // http://en.cppreference.com/w/cpp/experimental/fs // http://cpprocks.com/introduction-to-tr2-filesystem-library-in-vs2012/ --- TR2 filesystem in VS2012 // https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.140%29.aspx --- C++ 14, the header VS2015 // https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- header VS2013 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 2014-07-04 // http://cplusplus.github.io/filesystem-ts/working-draft.html --- in html format // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html --- in html format // http://article.gmane.org/gmane.comp.lib.boost.devel/256220 --- The filesystem TS unanimously approved by ISO. @@ -47,7 +47,7 @@ namespace nana { namespace experimental { namespace filesystem { #endif - enum class file_type + enum class file_type { none = 0, ///< has not been determined or an error occurred while trying to determine not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error @@ -78,7 +78,7 @@ namespace nana { namespace experimental { namespace filesystem uintmax_t available; }; - using file_time_type = std::chrono::time_point;// trivial-clock> ; + using file_time_type = std::chrono::time_point; ///< trivial-clock> ; class file_status { @@ -112,7 +112,7 @@ namespace nana { namespace experimental { namespace filesystem public: #if defined(NANA_WINDOWS) using value_type = wchar_t; - const static value_type preferred_separator = '\\'; + const static value_type preferred_separator = '\\'; //? L'\\' ? #else using value_type = char; const static value_type preferred_separator = '/'; @@ -199,8 +199,9 @@ namespace nana { namespace experimental { namespace filesystem filesystem_error(const std::string& msg, const path& path1, std::error_code err); filesystem_error(const std::string& msg, const path& path1, const path& path2, std::error_code err); - const path& path1() const; //noexcept - const path& path2() const; //noexcept + const path& path1() const noexcept; + const path& path2() const noexcept; + // const char* what() const noexcept; private: path path1_; path path2_; @@ -225,33 +226,23 @@ namespace nana { namespace experimental { namespace filesystem filesystem::path path_; }; - /// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator - //template + /// InputIterator that iterate over the sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator class directory_iterator :public std::iterator { using find_handle = void*; public: - using value_type = directory_entry ; - typedef ptrdiff_t difference_type; - typedef const directory_entry* pointer; - typedef const directory_entry& reference; - typedef std::input_iterator_tag iterator_category; - directory_iterator(); - directory_iterator(const path& file_path); + directory_iterator() noexcept; + explicit directory_iterator(const path& dir); const value_type& operator*() const; const value_type* operator->() const; directory_iterator& operator++(); - directory_iterator operator++(int); + directory_iterator operator++(int); ///< extention - bool equal(const directory_iterator& x) const; + bool equal(const directory_iterator& x) const; - // enable directory_iterator range-based for statements - directory_iterator begin(); - directory_iterator end(); - private: template static bool _m_ignore(const Char * p) @@ -271,6 +262,16 @@ namespace nana { namespace experimental { namespace filesystem find_handle handle_{nullptr}; value_type value_; }; + /// enable directory_iterator range-based for statements + inline directory_iterator begin( directory_iterator iter) noexcept + { + return iter; + } + + inline directory_iterator end( const directory_iterator&) noexcept + { + return {}; + } //class recursive_directory_iterator; @@ -304,6 +305,17 @@ namespace nana { namespace experimental { namespace filesystem //bool is_directory(const path& p, error_code& ec) noexcept; + inline bool is_regular_file(file_status s) noexcept + { + return s.type() == file_type::regular; + } + inline bool is_regular_file(const path& p) + { + return is_regular_file(status(p)); + } + // bool is_regular_file(const path& p, error_code& ec) noexcept; + // Returns: is_regular_file(status(p, ec)).Returns false if an error occurs. + inline bool is_empty(const path& p) { auto fs = status(p); @@ -313,7 +325,7 @@ namespace nana { namespace experimental { namespace filesystem return (file_size(p) == 0); } - //bool is_empty(const path& p, error_code& ec) noexcept; + // bool is_empty(const path& p, error_code& ec) noexcept; bool create_directories(const path& p); @@ -325,11 +337,11 @@ namespace nana { namespace experimental { namespace filesystem bool modified_file_time(const path& p, struct tm&); - path path_user(); + path path_user(); ///< extention ? path current_path(); //path current_path(error_code& ec); - void current_path(const path& p); + void current_path(const path& p); ///< chdir //void current_path(const path& p, error_code& ec) noexcept; diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index 3f432fbd..fc68a885 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -384,7 +384,7 @@ namespace nana { namespace experimental { namespace filesystem } }; - directory_iterator::directory_iterator() + directory_iterator::directory_iterator() noexcept : end_(true), handle_(nullptr) {} @@ -414,14 +414,10 @@ namespace nana { namespace experimental { namespace filesystem bool directory_iterator::equal(const directory_iterator& x) const { if (end_ && (end_ == x.end_)) return true; - return (value_.path().filename() == x.value_.path().filename()); + return (value_.path().filename() == x.value_.path().filename()); } - // enable directory_iterator range-based for statements - directory_iterator directory_iterator::begin() { return *this; } - directory_iterator directory_iterator::end() { return{}; } - void directory_iterator::_m_prepare(const path& file_path) { path_ = file_path.native(); From 17782a60e1e93e2238fa2c7ee6336d30a9827366 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 19 Feb 2016 13:58:14 +0100 Subject: [PATCH 016/309] directory_only_iterator is OK now --- include/nana/filesystem/filesystem_ext.hpp | 61 ++++++++++++++++------ 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 90b9978d..7e33ae9e 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -26,22 +26,28 @@ namespace nana {namespace experimental {namespace filesystem {namespace ext { constexpr auto def_rootname = "Root/"; #endif -// nana::experimental::filesystem::path_user()); // REPLACE !!!!!!!!!! to filesystem_ext.hhp +// nana::experimental::filesystem::path_user()); -inline bool is_directory(const directory_entry& d) noexcept +inline bool is_directory(const std::experimental::filesystem::directory_entry& dir) noexcept { - return is_directory(d.status()); + return is_directory(dir.status()); } -template // DI = directory_iterator from std, boost, or nana : return directory_entry -class directory_only_iterator : public DI -{ - DI& find_first() +//template // DI = directory_iterator from std, boost, or nana : return directory_entry +class directory_only_iterator : public std::experimental::filesystem::directory_iterator +{ + using DI = std::experimental::filesystem::directory_iterator; + directory_only_iterator& find_first() { - while(( (*this) != DI{}) || !is_directory((*this)->status()) ) - this->DI::operator++(); - return (*this); + auto end = directory_only_iterator{}; + while (*this != end) + { + if (is_directory((**this).status())) + return *this; + this->DI::operator++(); + } + return end; } public: template @@ -49,19 +55,31 @@ public: { find_first(); } + directory_only_iterator( ) {} directory_only_iterator& operator++() { this->DI::operator++(); return find_first(); } }; - -template // DI = directory_iterator from std, boost, or nana : value_type directory_entry -class regular_file_only_iterator : public DI +inline directory_only_iterator begin(directory_only_iterator iter) noexcept { - DI& find_first() + return iter; +} + +inline directory_only_iterator end(const directory_only_iterator&) noexcept +{ + return{}; +} + + +//template // DI = directory_iterator from std, boost, or nana : value_type directory_entry +class regular_file_only_iterator : public std::experimental::filesystem::directory_iterator +{ + using DI = std::experimental::filesystem::directory_iterator; + regular_file_only_iterator& find_first() { - while(( (*this) != DI{}) || !is_regular_file((*this)->status()) ) + while(( (*this) != DI{}) && !is_regular_file((**this).status())) this->DI::operator++(); return (*this); } @@ -71,6 +89,7 @@ public: { find_first(); } + regular_file_only_iterator() : DI() {} regular_file_only_iterator& operator++() { this->DI::operator++(); @@ -78,5 +97,15 @@ public: } }; - }}}} +inline regular_file_only_iterator begin(regular_file_only_iterator iter) noexcept +{ + return iter; +} + +inline regular_file_only_iterator end(const regular_file_only_iterator&) noexcept +{ + return{}; +} + +}}}} #endif //NANA_FILESYSTEM_EXT_HPP From 11f216434f28d15fa933ebf14d1d7f8575376a57 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 19 Feb 2016 13:59:51 +0100 Subject: [PATCH 017/309] better integration of the nana filesystem extensions and possible force to use it --- include/nana/filesystem/filesystem_ext.hpp | 2 ++ include/nana/filesystem/filesystem_selector.hpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 7e33ae9e..289bab0a 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -15,6 +15,8 @@ #ifndef NANA_FILESYSTEM_EXT_HPP #define NANA_FILESYSTEM_EXT_HPP +#include + namespace nana {namespace experimental {namespace filesystem {namespace ext { #if defined(NANA_WINDOWS) constexpr auto def_root = "C:"; diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index b168ce30..af4cf298 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -28,7 +28,7 @@ #include -#if defined(NANA_BOOST_FILESYSTEM_AVAILABLE) && ( defined(NANA_BOOST_FILESYSTEM_FORCE) || (defined(STD_FILESYSTEM_NOT_SUPPORTED) && defined(NANA_BOOST_FILESYSTEM_PREFERRED) ) ) +#if (!defined(NANA_FILESYSTEM_FORCE) && defined(NANA_BOOST_FILESYSTEM_AVAILABLE) && ( defined(NANA_BOOST_FILESYSTEM_FORCE) || (defined(STD_FILESYSTEM_NOT_SUPPORTED) && defined(NANA_BOOST_FILESYSTEM_PREFERRED) ) )) # include @@ -48,7 +48,7 @@ namespace std { } // std -#elif defined(STD_FILESYSTEM_NOT_SUPPORTED) +#elif (defined(NANA_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_NOT_SUPPORTED)) # include From 83bb669ff106b70fcd2c297a4f66cdfd624be1dd Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 19 Feb 2016 14:03:28 +0100 Subject: [PATCH 018/309] test travis with dev_dir_it, check in master ! before pushing back into master check what branch in nana-demo correspond --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 02ceda02..6e840779 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=50 --branch=master https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=50 --branch=dev_dir_it https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From 2e8b9264bfde0838f5c9b32153656b80c9f855ff Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 19 Feb 2016 14:16:34 +0100 Subject: [PATCH 019/309] fix compiler error noexeption --- source/filesystem/filesystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index fc68a885..63795147 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -59,12 +59,12 @@ namespace nana { namespace experimental { namespace filesystem path2_(path2) {} - const path& filesystem_error::path1() const + const path& filesystem_error::path1() const noexcept { return path1_; } - const path&filesystem_error::path2() const + const path& filesystem_error::path2() const noexcept { return path2_; } From 6d383d288d516a55bf81074167f1e6bdf036da3e Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 19 Feb 2016 14:26:30 +0100 Subject: [PATCH 020/309] fix return local end --- include/nana/filesystem/filesystem_ext.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 289bab0a..3c911b2b 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -49,7 +49,7 @@ class directory_only_iterator : public std::experimental::filesystem::directory_ return *this; this->DI::operator++(); } - return end; + return *this; } public: template From bd7b6e691c8d6f3a2c14381228b5925ca4242234 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 24 Feb 2016 23:21:16 +0100 Subject: [PATCH 021/309] travi test nana branch hotfix-1.3 with demo-nana branch dev_nana_in_examples --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6e840779..d411b4b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=50 --branch=dev_dir_it https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=50 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From e649a06b6fafde9ede4a606f4638f9b4ee112fe7 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 25 Feb 2016 00:07:39 +0100 Subject: [PATCH 022/309] include protoversion of the file_explore demo --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24b23784..4d099d6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,8 +203,8 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if (BUILD_NANA_DEMOS) - set (demos calculator notepad widget_show widget_show2 ) - # Pending: file_explorer FreeMe + set (demos calculator file_explorer notepad widget_show widget_show2 ) + # Pending: FreeMe foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") From 0978ed7e1815d93b06660150eea9bcd4184e7a93 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 25 Feb 2016 08:40:57 +0100 Subject: [PATCH 023/309] NANA_BOOST_FILESYSTEM_PREFERRED On by default. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d099d6b..cdbbe357 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF # By default Nana will use the ISO TS if available, or nana if not. # Boost will be use only if you change one of the following: option(CMAKE_BOOST_FILESYSTEM_AVAILABLE "Is Boost filesystem available?" OFF) -option(NANA_BOOST_FILESYSTEM_PREFERRED "Is Boost filesystem preferred over nana?" OFF) +option(NANA_BOOST_FILESYSTEM_PREFERRED "Is Boost filesystem preferred over nana?" ON) option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over ISO)?" OFF) option(CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") option(CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") From 1dd42c8841e68e9a7039528a94a5b4891db3edca Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 25 Feb 2016 09:26:06 +0100 Subject: [PATCH 024/309] log Boost related configuration --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cdbbe357..261fe97d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,4 +264,12 @@ message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "ENABLE_AUDIO = " ${ENABLE_AUDIO}) +message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) +message ( "DESTDIR = " ${DESTDIR}) +message ( "CMAKE_BOOST_FILESYSTEM_AVAILABLE = " ${CMAKE_BOOST_FILESYSTEM_AVAILABLE}) +message ( "NANA_BOOST_FILESYSTEM_PREFERRED = " ${NANA_BOOST_FILESYSTEM_PREFERRED}) +message ( "CMAKE_BOOST_FILESYSTEM_FORCE = " ${CMAKE_BOOST_FILESYSTEM_FORCE}) +message ( "CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}) +message ( "CMAKE_BOOST_FILESYSTEM_LIB = " ${CMAKE_BOOST_FILESYSTEM_LIB}) + From aad9e7780462803bde037845ed56b83c169950cc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 25 Feb 2016 19:18:40 +0100 Subject: [PATCH 025/309] a few more std features in filesystem --- include/nana/filesystem/filesystem.hpp | 53 ++++++++++++++++++-------- source/filesystem/filesystem.cpp | 9 ++++- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index c44345c6..1bbe3aa9 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -127,23 +127,41 @@ namespace nana { namespace experimental { namespace filesystem _m_assign(source); } + // modifiers + //void clear() noexcept; + path& make_preferred(); + path& remove_filename(); + //path& replace_filename(const path& replacement); + //path& replace_extension(const path& replacement = path()); + //void swap(path& rhs) noexcept; + + // decomposition + //path root_name() const; + //path root_directory() const; + //path root_path() const; + //path relative_path() const; + path parent_path() const; + path filename() const; + //path stem() const; + path extension() const; + + // query + bool empty() const noexcept; + //bool has_root_name() const; + //bool has_root_directory() const; + //bool has_root_path() const; + //bool has_relative_path() const; + bool has_parent_path() const { return !parent_path().empty(); }; // temp;; + bool has_filename() const { return !filename().empty(); }; // temp; + //bool has_stem() const; + bool has_extension() const { return !extension().empty(); }; // temp + //bool is_absolute() const; + //bool is_relative() const; int compare(const path& other) const; - bool empty() const; - path extension() const; - - path parent_path() const; file_type what() const; - //decomposition - path filename() const; - - //modifiers - path& remove_filename(); - - - const value_type*c_str() const; const string_type& native() const; operator string_type() const; @@ -335,16 +353,21 @@ namespace nana { namespace experimental { namespace filesystem bool create_directory(const path& p, const path& attributes); //bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept; - bool modified_file_time(const path& p, struct tm&); + bool modified_file_time(const path& p, struct tm&); ///< extention ? + + /// The time of last data modification of p, determined as if by the value of the POSIX + /// stat structure member st_mtime obtained as if by POSIX stat(). + file_time_type last_write_time(const path& p); + /// returns file_time_type::min() if an error occurs + //file_time_type last_write_time(const path& p, error_code& ec) noexcept; path path_user(); ///< extention ? - + path current_path(); //path current_path(error_code& ec); void current_path(const path& p); ///< chdir //void current_path(const path& p, error_code& ec) noexcept; - bool remove(const path& p); bool remove(const path& p, std::error_code& ec); // noexcept; diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index 63795147..1f523f3a 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -110,7 +110,7 @@ namespace nana { namespace experimental { namespace filesystem return pathstr_.compare(p.pathstr_); } - bool path::empty() const + bool path::empty() const noexcept { #if defined(NANA_WINDOWS) return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES); @@ -781,6 +781,13 @@ namespace nana { namespace experimental { namespace filesystem return false; } + file_time_type last_write_time(const path& p) + { + struct tm t; + modified_file_time(p, t); + std::chrono::system_clock::time_point dateTime =std::chrono::system_clock::from_time_t( mktime(&t) ); + return dateTime; + } bool create_directory(const path& p) { From c499c351dce565c87b0fdeb23373699fdea22f01 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 25 Feb 2016 19:21:29 +0100 Subject: [PATCH 026/309] cleanup selection of std, boost or nana filesystem and install it in travis, with detection in cmake todo: check namespaces and compatibility of boost filesystem --- .travis.yml | 4 +- CMakeLists.txt | 71 +++++++++++++------ include/nana/config.hpp | 38 ++++++---- .../nana/filesystem/filesystem_selector.hpp | 60 ++++++++-------- 4 files changed, 107 insertions(+), 66 deletions(-) diff --git a/.travis.yml b/.travis.yml index d411b4b0..a688d416 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,10 +65,12 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : + - sudo apt-get update -qq + - sudo apt-get install libboost-filesystem-dev - mkdir bld - cd bld script: - - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF + - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON - make diff --git a/CMakeLists.txt b/CMakeLists.txt index 261fe97d..1a4b6852 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ # use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir # if your changes don't execute +set(NANA_LINKS) + option(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF) option(ENABLE_PNG "Enable the use of PNG" OFF) option(LIBPNG_FROM_OS "Use libpng from operating system." ON) @@ -20,8 +22,9 @@ option(ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) option(CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF) +option(INCLUDE_EXPERIMENTAL_DEMOS "" OFF) -# The ISO C++ File System Technical Specification is optional. +# The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf # This is not a workaround, but an user option. # The library maybe available in the std library in use or from Boost (almost compatible) @@ -29,28 +32,51 @@ option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF # or you can choose to use the (partial, but functional) implementation provided by nana. # If you include the file # The selected option will be set by nana into std::experimental::filesystem -# By default Nana will use the ISO TS if available, or nana if not. -# Boost will be use only if you change one of the following: -option(CMAKE_BOOST_FILESYSTEM_AVAILABLE "Is Boost filesystem available?" OFF) -option(NANA_BOOST_FILESYSTEM_PREFERRED "Is Boost filesystem preferred over nana?" ON) -option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over ISO)?" OFF) -option(CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") -option(CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") +# By default Nana will try to use the STD. If not available will try +# to use boost if available. Nana own implementation will be use only none of them are available. +# You can change that default if you change one of the following +# (please don't define more than one of the _XX_FORCE options): +option(CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" ON) +option(CMAKE_NANA_FILESYSTEM_FORCE "Force nana filesystem over ISO and boost?" OFF) +option(CMAKE_STD_FILESYSTEM_FORCE "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF) +option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over STD)?" OFF) +# cmake will find the package self, if don't works set the following (please find the correct values): +#option(CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") +#option(CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") +#include_directories("${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") +#list(APPEND NANA_LINKS "${CMAKE_BOOST_FILESYSTEM_LIB}") -set(NANA_LINKS) -if (CMAKE_BOOST_FILESYSTEM_AVAILABLE) - if (CMAKE_BOOST_FILESYSTEM_PREFERED OR CMAKE_BOOST_FILESYSTEM_FORCE) + +if (CMAKE_NANA_FILESYSTEM_FORCE) + add_definitions(-DNANA_FILESYSTEM_FORCE) + +elseif (CMAKE_STD_FILESYSTEM_FORCE) + add_definitions(-DSTD_FILESYSTEM_FORCE) + +elseif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) + + if (CMAKE_BOOST_FILESYSTEM_FORCE) + add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) + endif(CMAKE_BOOST_FILESYSTEM_FORCE) + + # https://cmake.org/cmake/help/git-master/module/FindBoost.html + # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, + # even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries. + # If using Boost::thread, then Thread::Thread will also be added automatically. + find_package(Boost COMPONENTS filesystem) + if (Boost_FOUND) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) - if (CMAKE_BOOST_FILESYSTEM_FORCE) - add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) - else() - add_definitions(-DNANA_BOOST_FILESYSTEM_PREFERED) - endif() - include_directories("${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") - list(APPEND NANA_LINKS "${CMAKE_BOOST_FILESYSTEM_LIB}") - endif (CMAKE_BOOST_FILESYSTEM_PREFERED OR CMAKE_BOOST_FILESYSTEM_FORCE) -endif (CMAKE_BOOST_FILESYSTEM_AVAILABLE) + include_directories(SYSTEM "${Boost_INCLUDE_DIR}") + list(APPEND NANA_LINKS "${Boost_LIBRARIES}") + endif (Boost_FOUND) + + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_STATIC_RUNTIME ON) # ?? + #set(Boost_USE_MULTITHREADED ON) + +endif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) + project(nana) cmake_minimum_required(VERSION 2.8) @@ -203,7 +229,10 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if (BUILD_NANA_DEMOS) - set (demos calculator file_explorer notepad widget_show widget_show2 ) + set (demos calculator notepad widget_show widget_show2 ) + if (INCLUDE_EXPERIMENTAL_DEMOS) + list(APPEND demos file_explorer) + endif (INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe foreach ( demo ${demos}) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 6335f2e2..2c1d3c83 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -39,20 +39,30 @@ // https://github.com/meganz/mingw-std-threads //#define NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ -//////////////////////////// -// The ISO C++ File System Technical Specification is optional. -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf -// This is not a workaround, but an user option. -// The library maybe available in the std library in use or from Boost (almost compatible) -// http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm -// or you can choose to use the (partial, but functional) implementation provided by nana. -// If you include the file -// The selected option will be set by nana into std::experimental::filesystem -// By default Nana will use the ISO TS if available, or nana if not. -// Boost will be use only if you change one of the following (set the includes and link correspondly): -//#define NANA_BOOST_FILESYSTEM_AVAILABLE // "Is Boost filesystem available?" -//#define NANA_BOOST_FILESYSTEM_PREFERRED // "Is Boost filesystem preferred over nana?" -//#define NANA_BOOST_FILESYSTEM_FORCE // "Force use of Boost filesystem if available (over ISO)? +//# The ISO C++ File System Technical Specification(ISO - TS, or STD) is optional. +//# http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf +//# This is not a workaround, but an user option. +//# The library maybe available in the std library in use or from Boost(almost compatible) +//# http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm +//# or you can choose to use the(partial, but functional) implementation provided by nana. +//# If you include the file +//# the selected option will be set by nana into std::experimental::filesystem +//# By default Nana will try to use the STD.If not available will try +//# to use boost if available.Nana own implementation will be use only none of them are available. +//# You can change that default if you change one of the following +//# (please don't define more than one of the _XX_FORCE options): +// +//#define BOOST_FILESYSTEM_AVAILABLE // "Is Boost filesystem available?" +//#define BOOST_FILESYSTEM_FORCE // "Force use of Boost filesystem if available (over ISO and nana) +//#define STD_FILESYSTEM_FORCE // "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF) +//#define NANA_FILESYSTEM_FORCE // "Force nana filesystem over ISO and boost?" OFF) +// +// Make sure you (cmake?) provide the following where correspond (please find the correct values): +// set CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") +// set CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") +// include_directories CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT +// APPEND flag LINKS CMAKE_BOOST_FILESYSTEM_LIB + /////////////////// // Support of PCM playback diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index af4cf298..5b00e0c7 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -9,16 +9,17 @@ * @file nana\filesystem\filesystem_selector.hpp * @autor by Ariel Vina-Rodriguez: * @brief A "ISO C++" filesystem Implementation selector -* The ISO C++ File System Technical Specification is optional. -* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf -* This is not a workaround, but an user option. -* The library maybe available in the std library in use or from Boost (almost compatible) -* http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm -* or you can choose to use the (partial, but functional) implementation provided by nana. -* If you include the file -* The selected option will be set by nana into std::experimental::filesystem -* By default Nana will use the ISO TS if available, or nana if not. -* Boost will be use only if explicitily changed +* +* The ISO C++ File System Technical Specification(ISO - TS, or STD) is optional. +* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf +* This is not a workaround, but an user option. +* The library maybe available in the std library in use or from Boost(almost compatible) +* http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm +* or you can choose to use the(partial, but functional) implementation provided by nana. +* If you include the file +* the selected option will be set by nana into std::experimental::filesystem +* By default Nana will try to use the STD. If not available will try +* to use boost if available. Nana own implementation will be use only if none of them are available. * nana Now mimic std::experimental::filesystem::v1 (boost v3) * */ @@ -28,7 +29,25 @@ #include -#if (!defined(NANA_FILESYSTEM_FORCE) && defined(NANA_BOOST_FILESYSTEM_AVAILABLE) && ( defined(NANA_BOOST_FILESYSTEM_FORCE) || (defined(STD_FILESYSTEM_NOT_SUPPORTED) && defined(NANA_BOOST_FILESYSTEM_PREFERRED) ) )) +#if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) ) + +# include + +namespace std { + namespace experimental { + namespace filesystem { + +# ifdef CXX_NO_INLINE_NAMESPACE + using namespace nana::experimental::filesystem; +# else + using namespace nana::experimental::filesystem::v1; +# endif + + } // filesystem + } // experimental +} // std + +#elif (defined(BOOST_FILESYSTEM_AVAILABLE) && ( defined(BOOST_FILESYSTEM_FORCE) || ( defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(STD_FILESYSTEM_FORCE) ) )) # include @@ -47,25 +66,6 @@ namespace std { } // experimental } // std - -#elif (defined(NANA_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_NOT_SUPPORTED)) - -# include - -namespace std { - namespace experimental { - namespace filesystem { - -# ifdef CXX_NO_INLINE_NAMESPACE - using namespace nana::experimental::filesystem; -# else - using namespace nana::experimental::filesystem::v1; -# endif - - } // filesystem - } // experimental -} // std - #else # include #endif From ad926c3d0317f2c14b7974bbe3b7700e0b445ef4 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Thu, 25 Feb 2016 19:27:33 +0100 Subject: [PATCH 027/309] eliminate problematic line in travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a688d416..a8f6c634 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,7 +65,6 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : - - sudo apt-get update -qq - sudo apt-get install libboost-filesystem-dev - mkdir bld - cd bld From 890b60d9c73cb3ec3f305ba5fc522b6ddc820ba0 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Thu, 25 Feb 2016 19:30:50 +0100 Subject: [PATCH 028/309] elimine - sudo apt-get install libboost-filesystem-dev --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a8f6c634..96209c96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ matrix: - alsa-oss - libx11-dev - libxft-dev + - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test - env: CXX=g++-4.9 CC=gcc-4.9 @@ -65,7 +66,6 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : - - sudo apt-get install libboost-filesystem-dev - mkdir bld - cd bld From 1c42e93d917cb8bdf0ad65aefef881baf9f71919 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Thu, 25 Feb 2016 19:41:41 +0100 Subject: [PATCH 029/309] try nana, no boost filesystem --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96209c96..15e6c5d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,6 +70,6 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON + - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=OFF -DINCLUDE_EXPERIMENTAL_DEMOS=ON - make From 2504a915b30a3c90d0ed91163ca31907045c0b60 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 14:03:01 +0100 Subject: [PATCH 030/309] FIX: project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES --- CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a4b6852..2a6706ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,11 @@ # use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir # if your changes don't execute +# It seems that project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES. +# https://bbs.archlinux.org/viewtopic.php?id=84967 +project(nana) +cmake_minimum_required(VERSION 2.8) + set(NANA_LINKS) option(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF) @@ -22,7 +27,7 @@ option(ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) option(CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF) -option(INCLUDE_EXPERIMENTAL_DEMOS "" OFF) +option(INCLUDE_EXPERIMENTAL_DEMOS "" ON) # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf @@ -47,7 +52,6 @@ option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available #list(APPEND NANA_LINKS "${CMAKE_BOOST_FILESYSTEM_LIB}") - if (CMAKE_NANA_FILESYSTEM_FORCE) add_definitions(-DNANA_FILESYSTEM_FORCE) @@ -78,8 +82,6 @@ elseif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) endif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) -project(nana) -cmake_minimum_required(VERSION 2.8) # Compatibility with CMake 3.1 if(POLICY CMP0054) @@ -230,9 +232,9 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if (BUILD_NANA_DEMOS) set (demos calculator notepad widget_show widget_show2 ) - if (INCLUDE_EXPERIMENTAL_DEMOS) + #if (INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer) - endif (INCLUDE_EXPERIMENTAL_DEMOS) + #endif (INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe foreach ( demo ${demos}) From ff279652bce90fe47f2cf5853561e7ccb2150fdc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 15:24:51 +0100 Subject: [PATCH 031/309] two pretty print functions in filesystem_ext --- include/nana/filesystem/filesystem_ext.hpp | 50 +++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 3c911b2b..abcdc5d3 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -108,6 +108,54 @@ inline regular_file_only_iterator end(const regular_file_only_iterator&) noexcep { return{}; } - + +inline std::string pretty_file_size(const std::experimental::filesystem::path& path) // todo: move to .cpp +{ + try { + std::size_t bytes = std::experimental::filesystem::file_size ( path ); + const char * ustr[] = { " KB", " MB", " GB", " TB" }; + std::stringstream ss; + if (bytes < 1024) + ss << bytes << " Bytes"; + else + { + double cap = bytes / 1024.0; + std::size_t uid = 0; + while ((cap >= 1024.0) && (uid < sizeof(ustr) / sizeof(char *))) + { + cap /= 1024.0; + ++uid; + } + ss << cap; + auto s = ss.str(); + auto pos = s.find('.'); + if (pos != s.npos) + { + if (pos + 2 < s.size()) + s.erase(pos + 2); + } + return s + ustr[uid]; + } + + return ss.str(); + } + catch (...) {} + return {}; +} + +inline std::string pretty_file_date(const std::experimental::filesystem::path& path) // todo: move to .cpp +{ + try { + auto ftime = std::experimental::filesystem::last_write_time(path); + std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); + std::stringstream tm; + tm << std::put_time(std::localtime(&cftime), "%Y-%m-%d, %H:%M:%S"); + return tm.str(); + } + catch (...) { + return {}; + } +} + }}}} #endif //NANA_FILESYSTEM_EXT_HPP From d335f34a6c1709faebce8992ca236fe0538dd176 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 16:47:53 +0100 Subject: [PATCH 032/309] truly empty? in filesystem_ext --- include/nana/filesystem/filesystem.hpp | 8 ++++---- source/filesystem/filesystem.cpp | 18 +++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 1bbe3aa9..b7cb9cdc 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -112,7 +112,7 @@ namespace nana { namespace experimental { namespace filesystem public: #if defined(NANA_WINDOWS) using value_type = wchar_t; - const static value_type preferred_separator = '\\'; //? L'\\' ? + const static value_type preferred_separator = L'\\'; //? L'\\' ? #else using value_type = char; const static value_type preferred_separator = '/'; @@ -151,10 +151,10 @@ namespace nana { namespace experimental { namespace filesystem //bool has_root_directory() const; //bool has_root_path() const; //bool has_relative_path() const; - bool has_parent_path() const { return !parent_path().empty(); }; // temp;; - bool has_filename() const { return !filename().empty(); }; // temp; + bool has_parent_path() const { return !parent_path().string().empty(); }; // temp;; + bool has_filename() const { return !filename().string().empty(); }; // temp; //bool has_stem() const; - bool has_extension() const { return !extension().empty(); }; // temp + bool has_extension() const { return !extension().string().empty(); }; // temp //bool is_absolute() const; //bool is_relative() const; diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index 1f523f3a..ead15a1a 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -110,6 +110,7 @@ namespace nana { namespace experimental { namespace filesystem return pathstr_.compare(p.pathstr_); } + /// true if the path is empty, false otherwise. ?? bool path::empty() const noexcept { #if defined(NANA_WINDOWS) @@ -122,17 +123,20 @@ namespace nana { namespace experimental { namespace filesystem path path::extension() const { + // todo: make more globlal #if defined(NANA_WINDOWS) - auto pos = pathstr_.find_last_of(L"\\/."); + auto SLorP=L"\\/."; + auto P=L'.'; #else - auto pos = pathstr_.find_last_of("\\/."); + auto SLorP="\\/."; + auto P='.'; #endif - if ((pos == pathstr_.npos) || (pathstr_[pos] != '.')) - return path(); + auto pos = pathstr_.find_last_of(SLorP); - - if (pos + 1 == pathstr_.size()) - return path(); + if ( ( pos == pathstr_.npos) + || ( pathstr_[pos] != P ) + || ( pos + 1 == pathstr_.size() )) + return path(); return path(pathstr_.substr(pos)); } From d7a3f12136b9e26c1be19f84d716fb53e17dd1d2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 16:52:26 +0100 Subject: [PATCH 033/309] include demo --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a6706ed..594c5f4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,9 +232,9 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if (BUILD_NANA_DEMOS) set (demos calculator notepad widget_show widget_show2 ) - #if (INCLUDE_EXPERIMENTAL_DEMOS) + if (INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer) - #endif (INCLUDE_EXPERIMENTAL_DEMOS) + endif (INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe foreach ( demo ${demos}) From 569eb49a5ca01b5de58348c4f055b27f9e927149 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 27 Feb 2016 02:02:29 +0800 Subject: [PATCH 034/309] fix and improve the internal handle of focus change enhanced textbox behavior of focus change --- include/nana/gui/basis.hpp | 1 + include/nana/gui/detail/general_events.hpp | 15 ++- .../nana/gui/detail/inner_fwd_implement.hpp | 3 +- include/nana/gui/detail/window_manager.hpp | 2 +- include/nana/gui/programming_interface.hpp | 6 + .../gui/widgets/skeletons/text_editor.hpp | 12 +- .../widgets/skeletons/text_editor_part.hpp | 9 ++ include/nana/gui/widgets/textbox.hpp | 10 ++ source/gui/detail/bedrock_posix.cpp | 103 ++++++++------- source/gui/detail/bedrock_windows.cpp | 102 ++++++++------- source/gui/detail/window_manager.cpp | 4 +- source/gui/programming_interface.cpp | 4 +- source/gui/widgets/skeletons/text_editor.cpp | 122 +++++++++++++++--- source/gui/widgets/textbox.cpp | 27 ++-- 14 files changed, 290 insertions(+), 130 deletions(-) diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index 26ca8885..723d3140 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -95,6 +95,7 @@ namespace nana undo = substitute, //System Code for OS + os_tab = 0x09, os_shift = 0x10, os_ctrl = 0x11, os_pageup = 0x21, os_pagedown, diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 0ff84083..c49cab98 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -424,9 +424,18 @@ namespace nana struct arg_focus : public event_arg { - ::nana::window window_handle; ///< A handle to the event window - ::nana::native_window_type receiver; ///< it is a native window handle, and specified which window receives focus - bool getting; ///< the window received focus? + /// A constant to indicate how keyboard focus emitted. + enum class reason + { + general, ///< the focus is received by OS native window manager. + tabstop, ///< the focus is received by pressing tab. + mouse_press ///< the focus is received by pressing a mouse button. + }; + + ::nana::window window_handle; ///< A handle to the event window + ::nana::native_window_type receiver; ///< it is a native window handle, and specified which window receives focus + bool getting; ///< the window received focus? + reason focus_reason; ///< determines how the widget receives keyboard focus, it is ignored when 'getting' is equal to false }; struct arg_keyboard : public event_arg diff --git a/include/nana/gui/detail/inner_fwd_implement.hpp b/include/nana/gui/detail/inner_fwd_implement.hpp index 90589d3c..e24853b0 100644 --- a/include/nana/gui/detail/inner_fwd_implement.hpp +++ b/include/nana/gui/detail/inner_fwd_implement.hpp @@ -117,8 +117,9 @@ namespace nana{ nana::paint::graphics root_graph; shortkey_container shortkeys; - struct condition_tag + struct condition_rep { + bool ignore_tab{ false }; //ignore tab when the focus is changed by pressing tab. core_window_t* pressed{nullptr}; //The handle to a window which has been pressed by pressing left button of mouse. core_window_t* pressed_by_space{ nullptr }; //The handle to a window which has been pressed by pressing spacebar. core_window_t* hovered{nullptr}; //the latest window that mouse moved diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index b04c32dc..965be995 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -136,7 +136,7 @@ namespace detail std::vector get_children(core_window_t*) const; bool set_parent(core_window_t* wd, core_window_t* new_parent); - core_window_t* set_focus(core_window_t*, bool root_has_been_focused); + core_window_t* set_focus(core_window_t*, bool root_has_been_focused, arg_focus::reason); core_window_t* capture_redirect(core_window_t*); void capture_ignore_children(bool ignore); diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index c50f8f2e..03138a04 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -283,8 +283,14 @@ namespace API cursor window_cursor(window); void activate_window(window); + + /// Determines whether the specified window will get the keyboard focus when its root window gets native system focus. bool is_focus_ready(window); + + /// Returns the current keyboard focus window. window focus_window(); + + /// Sets the keyboard focus for a specified window. void focus_window(window); window capture_window(); diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 3189cd18..986bc438 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -229,6 +229,9 @@ namespace nana{ namespace widgets /// Returns text position of each line that currently displays on screen const std::vector& text_position() const; + + void focus_behavior(text_focus_behavior); + void select_behavior(bool move_to_end); public: void draw_corner(); void render(bool focused); @@ -249,6 +252,8 @@ namespace nana{ namespace widgets const upoint& caret() const; point caret_screen_pos() const; bool scroll(bool upwards, bool vertical); + + bool focus_changed(const arg_focus&); bool mouse_enter(bool); bool mouse_move(bool left_button, const point& screen_pos); bool mouse_pressed(const arg_mouse& arg); @@ -353,10 +358,13 @@ namespace nana{ namespace widgets struct selection { - enum mode_selection_t{mode_no_selected, mode_mouse_selected, mode_method_selected}; + enum class mode{ no_selected, mouse_selected, method_selected }; - mode_selection_t mode_selection; + text_focus_behavior behavior; + bool move_to_end; + mode mode_selection; bool dragged; + bool ignore_press; nana::upoint a, b; }select_; diff --git a/include/nana/gui/widgets/skeletons/text_editor_part.hpp b/include/nana/gui/widgets/skeletons/text_editor_part.hpp index be4ec920..8cf1c389 100644 --- a/include/nana/gui/widgets/skeletons/text_editor_part.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor_part.hpp @@ -11,6 +11,15 @@ namespace nana { namespace skeletons { + enum class text_focus_behavior + { + none, + select, + select_if_tabstop, + select_if_click, + select_if_tabstop_or_click + }; + //forward declaration class text_editor; diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 69fda830..bc3b9ab1 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -98,6 +98,8 @@ namespace nana :public widget_object { public: + using text_focus_behavior = widgets::skeletons::text_focus_behavior; + using text_positions = std::vector; /// The default constructor without creating the widget. textbox(); @@ -207,6 +209,14 @@ namespace nana /// Returns the height of line in pixels unsigned line_pixels() const; + + /// Sets the behavior when textbox gets focus. + void focus_behavior(text_focus_behavior); + + /// Sets the caret move behavior when the content of textbox is selected. + /// E.g. Whether caret moves to left of selected content or moves to left of last position when left arrow key is pressed. + /// @param move_to_end determines whether to move caret to left of selected_content or to left of last position. + void select_behavior(bool move_to_end); protected: //Overrides widget's virtual functions native_string_type _m_caption() const throw() override; diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index a8f78c37..d5b9a282 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -255,7 +255,7 @@ namespace detail if ((!wd) && pre) { internal_scope_guard lock; - wd_manager().set_focus(pre, false); + wd_manager().set_focus(pre, false, arg_focus::reason::general); wd_manager().update(pre, true, false); } } @@ -479,6 +479,7 @@ namespace detail arg.window_handle = reinterpret_cast(wd); arg.receiver = recv; arg.getting = getting; + arg.focus_reason = arg_focus::reason::general; } void assign_arg(arg_wheel& arg, basic_window* wd, const XEvent& evt) @@ -701,7 +702,7 @@ namespace detail arg.receiver = native_window; arg.getting = true; if(!brock.emit(event_code::focus, focus, arg, true, &context)) - brock.wd_manager().set_focus(msgwnd, true); + brock.wd_manager().set_focus(msgwnd, true, arg_focus::reason::general); } break; case FocusOut: @@ -765,7 +766,7 @@ namespace detail if (new_focus && !new_focus->flags.ignore_mouse_focus) { context.event_window = new_focus; - auto kill_focus = brock.wd_manager().set_focus(new_focus, false); + auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press); if (kill_focus != new_focus) brock.wd_manager().do_lazy_refresh(kill_focus, false); } @@ -1048,7 +1049,8 @@ namespace detail auto tstop_wd = wd_manager.tabstop(msgwnd, !argkey.shift); if (tstop_wd) { - wd_manager.set_focus(tstop_wd, false); + root_runtime->condition.ignore_tab = true; + wd_manager.set_focus(tstop_wd, false, arg_focus::reason::tabstop); wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(tstop_wd, true); } @@ -1144,8 +1146,8 @@ namespace detail arg.ignore = false; arg.key = charbuf[i]; - // When tab is pressed, only tab-eating mode is allowed - if ((keyboard::tab == arg.key) && !(msgwnd->flags.tab & tab_type::eating)) + //Only accept tab when it is not ignored. + if ((keyboard::tab == arg.key) && root_runtime->condition.ignore_tab) continue; if(context.is_alt_pressed) @@ -1185,52 +1187,61 @@ namespace detail nana::detail::platform_spec::instance().write_keystate(xevent.xkey); { auto os_code = os_code_from_keysym(::XLookupKeysym(&xevent.xkey, 0)); - if(keyboard::alt != os_code) + if(keyboard::alt != os_code) //MUST NOT BE AN ALT { if(0x11 == os_code) context.is_ctrl_pressed = false; - msgwnd = brock.focus(); - if(msgwnd) - { - if(msgwnd == pressed_wd_space) - { - msgwnd->flags.action = mouse_action::normal; + if (('\t' == os_code) && root_runtime->condition.ignore_tab) + { + root_runtime->condition.ignore_tab = false; + } + else + { + + msgwnd = brock.focus(); + if(msgwnd) + { + if(msgwnd == pressed_wd_space) + { + msgwnd->flags.action = mouse_action::normal; - arg_click click_arg; - click_arg.mouse_args = nullptr; - click_arg.window_handle = reinterpret_cast(msgwnd); + arg_click click_arg; + click_arg.mouse_args = nullptr; + click_arg.window_handle = reinterpret_cast(msgwnd); - auto retain = msgwnd->together.events_ptr; - if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) - { - arg_mouse arg; - arg.alt = false; - arg.button = ::nana::mouse::left_button; - arg.ctrl = false; - arg.evt_code = event_code::mouse_up; - arg.left_button = true; - arg.mid_button = false; - arg.pos.x = 0; - arg.pos.y = 0; - arg.window_handle = reinterpret_cast(msgwnd); + auto retain = msgwnd->together.events_ptr; + if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) + { + arg_mouse arg; + arg.alt = false; + arg.button = ::nana::mouse::left_button; + arg.ctrl = false; + arg.evt_code = event_code::mouse_up; + arg.left_button = true; + arg.mid_button = false; + arg.pos.x = 0; + arg.pos.y = 0; + arg.window_handle = reinterpret_cast(msgwnd); - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); - } - pressed_wd_space = nullptr; - } - else - { - arg_keyboard arg; - arg.evt_code = event_code::key_release; - arg.window_handle = reinterpret_cast(msgwnd); - arg.ignore = false; - arg.key = os_code; - brock.get_key_state(arg); - brock.emit(event_code::key_release, msgwnd, arg, true, &context); - } - } + emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + brock.wd_manager().do_lazy_refresh(msgwnd, false); + } + pressed_wd_space = nullptr; + } + else + { + arg_keyboard arg; + + arg.evt_code = event_code::key_release; + arg.window_handle = reinterpret_cast(msgwnd); + arg.ignore = false; + arg.key = os_code; + brock.get_key_state(arg); + brock.emit(event_code::key_release, msgwnd, arg, true, &context); + } + } + } if(os_code < keyboard::os_arrow_left || keyboard::os_arrow_down < os_code) brock.delay_restore(2); //Restores while key release @@ -1245,7 +1256,7 @@ namespace detail { bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); if (set_focus) - brock.wd_manager().set_focus(msgwnd, false); + brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::general); arg_keyboard arg; arg.evt_code = event_code::key_release; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 1f557bca..8b3cb978 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -549,6 +549,7 @@ namespace detail arg.window_handle = reinterpret_cast(wd); arg.receiver = recv; arg.getting = getting; + arg.focus_reason = arg_focus::reason::general; } void assign_arg(arg_wheel& arg, basic_window* wd, const parameter_decoder& pmdec) @@ -882,7 +883,7 @@ namespace detail arg_focus arg; assign_arg(arg, focus, native_window, true); if (!brock.emit(event_code::focus, focus, arg, true, &context)) - brock.wd_manager().set_focus(msgwnd, true); + brock.wd_manager().set_focus(msgwnd, true, arg_focus::reason::general); } def_window_proc = true; break; @@ -922,7 +923,7 @@ namespace detail { if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus) { - auto killed = brock.wd_manager().set_focus(msgwnd, false); + auto killed = brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::mouse_press); if (killed != msgwnd) brock.wd_manager().do_lazy_refresh(killed, false); } @@ -964,7 +965,7 @@ namespace detail auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); if (new_focus && (!new_focus->flags.ignore_mouse_focus)) { - auto kill_focus = brock.wd_manager().set_focus(new_focus, false); + auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press); if (kill_focus != new_focus) brock.wd_manager().do_lazy_refresh(kill_focus, false); } @@ -1383,7 +1384,7 @@ namespace detail bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); if (set_focus) - brock.wd_manager().set_focus(msgwnd, false); + brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::general); arg_keyboard arg; arg.evt_code = event_code::key_release; @@ -1414,14 +1415,16 @@ namespace detail if(msgwnd) { auto & wd_manager = brock.wd_manager(); - if((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab + + if ((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab { bool is_forward = (::GetKeyState(VK_SHIFT) >= 0); auto tstop_wd = wd_manager.tabstop(msgwnd, is_forward); if (tstop_wd) { - wd_manager.set_focus(tstop_wd, false); + root_runtime->condition.ignore_tab = true; + wd_manager.set_focus(tstop_wd, false, arg_focus::reason::tabstop); wd_manager.do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(tstop_wd, true); } @@ -1479,8 +1482,10 @@ namespace detail msgwnd = brock.focus(); if (msgwnd && msgwnd->flags.enabled) { - // When tab is pressed, only tab-eating mode is allowed - if ((9 != wParam) || (msgwnd->flags.tab & tab_type::eating)) + auto & wd_manager = brock.wd_manager(); + + //Only accept tab when it is not ignored. + if (VK_TAB != wParam || !root_runtime->condition.ignore_tab) { arg_keyboard arg; arg.evt_code = event_code::key_char; @@ -1490,55 +1495,62 @@ namespace detail arg.ignore = false; msgwnd->together.events_ptr->key_char.emit(arg); - if ((false == arg.ignore) && brock.wd_manager().available(msgwnd)) + if ((false == arg.ignore) && wd_manager.available(msgwnd)) brock.emit_drawer(event_code::key_char, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } } return 0; case WM_KEYUP: if(wParam != VK_MENU) //MUST NOT BE AN ALT { - msgwnd = brock.focus(); - if(msgwnd) + if (VK_TAB == wParam && root_runtime->condition.ignore_tab) { - if (msgwnd == pressed_wd_space) + root_runtime->condition.ignore_tab = false; + } + else + { + msgwnd = brock.focus(); + if (msgwnd) { - msgwnd->flags.action = mouse_action::normal; - - arg_click click_arg; - click_arg.mouse_args = nullptr; - click_arg.window_handle = reinterpret_cast(msgwnd); - - auto retain = msgwnd->together.events_ptr; - if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) + if (msgwnd == pressed_wd_space) { - arg_mouse arg; - arg.alt = false; - arg.button = ::nana::mouse::left_button; - arg.ctrl = false; - arg.evt_code = event_code::mouse_up; - arg.left_button = true; - arg.mid_button = false; - arg.pos.x = 0; - arg.pos.y = 0; - arg.window_handle = reinterpret_cast(msgwnd); + msgwnd->flags.action = mouse_action::normal; - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + arg_click click_arg; + click_arg.mouse_args = nullptr; + click_arg.window_handle = reinterpret_cast(msgwnd); + + auto retain = msgwnd->together.events_ptr; + if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) + { + arg_mouse arg; + arg.alt = false; + arg.button = ::nana::mouse::left_button; + arg.ctrl = false; + arg.evt_code = event_code::mouse_up; + arg.left_button = true; + arg.mid_button = false; + arg.pos.x = 0; + arg.pos.y = 0; + arg.window_handle = reinterpret_cast(msgwnd); + + emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + brock.wd_manager().do_lazy_refresh(msgwnd, false); + } + pressed_wd_space = nullptr; + } + else + { + arg_keyboard arg; + arg.evt_code = event_code::key_release; + arg.window_handle = reinterpret_cast(msgwnd); + arg.key = static_cast(wParam); + brock.get_key_state(arg); + arg.ignore = false; + brock.emit(event_code::key_release, msgwnd, arg, true, &context); } - pressed_wd_space = nullptr; - } - else - { - arg_keyboard arg; - arg.evt_code = event_code::key_release; - arg.window_handle = reinterpret_cast(msgwnd); - arg.key = static_cast(wParam); - brock.get_key_state(arg); - arg.ignore = false; - brock.emit(event_code::key_release, msgwnd, arg, true, &context); } } } @@ -1625,7 +1637,7 @@ namespace detail if ((!wd) && pre && (pre->root != get_menu())) { internal_scope_guard lock; - wd_manager().set_focus(pre, false); + wd_manager().set_focus(pre, false, arg_focus::reason::general); wd_manager().update(pre, true, false); } } diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 4aa19757..fcb7fe6e 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -925,7 +925,7 @@ namespace detail //set_focus //@brief: set a keyboard focus to a window. this may fire a focus event. - window_manager::core_window_t* window_manager::set_focus(core_window_t* wd, bool root_has_been_focused) + window_manager::core_window_t* window_manager::set_focus(core_window_t* wd, bool root_has_been_focused, arg_focus::reason reason) { //Thread-Safe Required! std::lock_guard lock(mutex_); @@ -951,6 +951,7 @@ namespace detail arg.getting = false; arg.window_handle = reinterpret_cast(prev_focus); arg.receiver = wd->root; + arg.focus_reason = arg_focus::reason::general; brock.emit(event_code::focus, prev_focus, arg, true, brock.get_thread_context()); } @@ -968,6 +969,7 @@ namespace detail arg.window_handle = reinterpret_cast(wd); arg.getting = true; arg.receiver = wd->root; + arg.focus_reason = reason; brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context()); if (!root_has_been_focused) diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index f653069c..c645de9a 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -929,7 +929,7 @@ namespace API void focus_window(window wd) { - restrict::wd_manager().set_focus(reinterpret_cast(wd), false); + restrict::wd_manager().set_focus(reinterpret_cast(wd), false, arg_focus::reason::general); restrict::wd_manager().update(reinterpret_cast(wd), false, false); } @@ -1171,7 +1171,7 @@ namespace API window move_tabstop(window wd, bool next) { basic_window* ts_wd = restrict::wd_manager().tabstop(reinterpret_cast(wd), next); - restrict::wd_manager().set_focus(ts_wd, false); + restrict::wd_manager().set_focus(ts_wd, false, arg_focus::reason::general); restrict::wd_manager().update(ts_wd, false, false); return reinterpret_cast(ts_wd); } diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index fc6086cc..3c372903 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1289,7 +1289,11 @@ namespace nana{ namespace widgets text_area_.tab_space = 4; text_area_.scroll_pixels = 16; text_area_.hscroll = text_area_.vscroll = 0; - select_.mode_selection = selection::mode_no_selected; + + select_.behavior = text_focus_behavior::select_if_tabstop_or_click; + select_.move_to_end = false; + select_.mode_selection = selection::mode::no_selected; + select_.ignore_press = false; select_.dragged = false; API::create_caret(wd, 1, line_height()); @@ -1348,11 +1352,13 @@ namespace nana{ namespace widgets void text_editor::erase_keyword(const ::std::wstring& kw) { for (auto i = keywords_->kwbase.begin(); i != keywords_->kwbase.end(); ++i) + { if (i->text == kw) { keywords_->kwbase.erase(i); return; } + } } void text_editor::set_accept(std::function pred) @@ -1624,6 +1630,47 @@ namespace nana{ namespace widgets return 0; } + bool text_editor::focus_changed(const arg_focus& arg) + { + bool renderred = false; + + if (arg.getting && (select_.a == select_.b)) //Do not change the selected text + { + bool select_all = false; + switch (select_.behavior) + { + case text_focus_behavior::select: + select_all = true; + break; + case text_focus_behavior::select_if_click: + select_all = (arg_focus::reason::mouse_press == arg.focus_reason); + break; + case text_focus_behavior::select_if_tabstop: + select_all = (arg_focus::reason::tabstop == arg.focus_reason); + break; + case text_focus_behavior::select_if_tabstop_or_click: + select_all = (arg_focus::reason::tabstop == arg.focus_reason || arg_focus::reason::mouse_press == arg.focus_reason); + default: + break; + } + + if (select_all) + { + select(true); + move_caret_end(); + renderred = true; + + //If the text widget is focused by clicking mouse button, the selected text will be cancelled + //by the subsequent mouse down event. In this situation, the subsequent mouse down event should + //be ignored. + select_.ignore_press = (arg_focus::reason::mouse_press == arg.focus_reason); + } + } + show_caret(arg.getting); + reset_caret(); + return renderred; + } + bool text_editor::mouse_enter(bool enter) { if((false == enter) && (false == text_area_.captured)) @@ -1649,7 +1696,7 @@ namespace nana{ namespace widgets auto caret_pos_before = caret(); mouse_caret(scrpos); - if(select_.mode_selection != selection::mode_no_selected) + if(select_.mode_selection != selection::mode::no_selected) set_end_caret(); else if ((!select_.dragged) && (caret_pos_before != caret())) select_.dragged = true; @@ -1664,8 +1711,11 @@ namespace nana{ namespace widgets { if (event_code::mouse_down == arg.evt_code) { - if (!hit_text_area(arg.pos)) + if (select_.ignore_press || (!hit_text_area(arg.pos))) + { + select_.ignore_press = false; return false; + } if (::nana::mouse::left_button == arg.button) { @@ -1691,7 +1741,7 @@ namespace nana{ namespace widgets } points_.shift_begin_caret = points_.caret; } - select_.mode_selection = selection::mode_mouse_selected; + select_.mode_selection = selection::mode::mouse_selected; } text_area_.border_renderer(graph_, _m_bgcolor()); @@ -1699,11 +1749,12 @@ namespace nana{ namespace widgets } else if (event_code::mouse_up == arg.evt_code) { - auto is_prev_no_selected = (select_.mode_selection == selection::mode_no_selected); + select_.ignore_press = false; + auto is_prev_no_selected = (select_.mode_selection == selection::mode::no_selected); - if (select_.mode_selection == selection::mode_mouse_selected) + if (select_.mode_selection == selection::mode::mouse_selected) { - select_.mode_selection = selection::mode_no_selected; + select_.mode_selection = selection::mode::no_selected; set_end_caret(); } else if (is_prev_no_selected) @@ -1842,12 +1893,12 @@ namespace nana{ namespace widgets select_.b.y = static_cast(textbase_.lines()); if(select_.b.y) --select_.b.y; select_.b.x = static_cast(textbase_.getline(select_.b.y).size()); - select_.mode_selection = selection::mode_method_selected; + select_.mode_selection = selection::mode::method_selected; render(true); return true; } - select_.mode_selection = selection::mode_no_selected; + select_.mode_selection = selection::mode::no_selected; if (_m_cancel_select(0)) { render(true); @@ -1924,6 +1975,16 @@ namespace nana{ namespace widgets return text_position_; } + void text_editor::focus_behavior(text_focus_behavior behavior) + { + select_.behavior = behavior; + } + + void text_editor::select_behavior(bool move_to_end) + { + select_.move_to_end = move_to_end; + } + void text_editor::draw_corner() { if(text_area_.vscroll && text_area_.hscroll) @@ -2339,27 +2400,45 @@ namespace nana{ namespace widgets size_t lnsz = textbase_.getline(caret.y).size(); switch (key) { case keyboard::os_arrow_left: - if (caret.x != 0) { - --caret.x; + if (select_.move_to_end && (select_.a != select_.b) && (!arg.shift)) + { + caret = select_.a; changed = true; - }else { - if (caret.y != 0) { - --caret.y; - caret.x = static_cast(textbase_.getline(caret.y).size()); + } + else + { + if (caret.x != 0) { + --caret.x; changed = true; } + else { + if (caret.y != 0) { + --caret.y; + caret.x = static_cast(textbase_.getline(caret.y).size()); + changed = true; + } + } } break; case keyboard::os_arrow_right: - if (caret.x < lnsz) { - ++caret.x; + if (select_.move_to_end && (select_.a != select_.b) && (!arg.shift)) + { + caret = select_.b; changed = true; - }else { - if (caret.y != nlines - 1) { - ++caret.y; - caret.x = 0; + } + else + { + if (caret.x < lnsz) { + ++caret.x; changed = true; } + else { + if (caret.y != nlines - 1) { + ++caret.y; + caret.x = 0; + changed = true; + } + } } break; case keyboard::os_arrow_up: @@ -2411,6 +2490,7 @@ namespace nana{ namespace widgets if (select_.a != caret || select_.b != caret) { changed = true; } + if (changed) { if (arg.shift) { switch (key) { diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index fe140e41..b6d678af 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -94,14 +94,9 @@ namespace drawerbase { void drawer::focus(graph_reference graph, const arg_focus& arg) { - refresh(graph); - if (!editor_->attr().multi_lines && arg.getting) - { - editor_->select(true); - editor_->move_caret_end(); - } - editor_->show_caret(arg.getting); - editor_->reset_caret(); + if (!editor_->focus_changed(arg)) + refresh(graph); + API::lazy_refresh(); } @@ -590,6 +585,22 @@ namespace drawerbase { return (editor ? editor->line_height() : 0); } + void textbox::focus_behavior(text_focus_behavior behavior) + { + internal_scope_guard lock; + auto editor = get_drawer_trigger().editor(); + if (editor) + editor->focus_behavior(behavior); + } + + void textbox::select_behavior(bool move_to_end) + { + internal_scope_guard lock; + auto editor = get_drawer_trigger().editor(); + if (editor) + editor->select_behavior(move_to_end); + } + //Override _m_caption for caption() auto textbox::_m_caption() const throw() -> native_string_type { From 81aacd4f3c4fbc96560e6c18f90a9df5a26c9c43 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 20:04:36 +0100 Subject: [PATCH 035/309] fix #include --- include/nana/filesystem/filesystem_ext.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index abcdc5d3..ef561665 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -15,6 +15,7 @@ #ifndef NANA_FILESYSTEM_EXT_HPP #define NANA_FILESYSTEM_EXT_HPP +#include #include namespace nana {namespace experimental {namespace filesystem {namespace ext { From e06f124ea19559129e8077f3a3d67951e7a6b2f1 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 20:59:50 +0100 Subject: [PATCH 036/309] allow failures g++-4.9 http://stackoverflow.com/questions/14136833/stdput-time-implementation-status-in-gcc --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 15e6c5d6..23642786 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,8 @@ matrix: - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test + + allow_failures: - env: CXX=g++-4.9 CC=gcc-4.9 addons: apt: From 859631732db9d222a61c4c2e3205ebe5b373b521 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 21:00:58 +0100 Subject: [PATCH 037/309] first test boost --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 23642786..01bccf3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,6 +72,6 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=OFF -DINCLUDE_EXPERIMENTAL_DEMOS=ON + - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON - make From 7a4d18789b742fd4b2af3268bc0c92fc9311762d Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 21:04:58 +0100 Subject: [PATCH 038/309] fix? no 4.9 --- .travis.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index 01bccf3b..5d41b28e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,22 +24,6 @@ matrix: sources: - ubuntu-toolchain-r-test - allow_failures: - - env: CXX=g++-4.9 CC=gcc-4.9 - addons: - apt: - packages: - - g++-4.9 - - libjpeg8-dev - - libpng-dev - - libasound2-dev - - alsa-utils - - alsa-oss - - libx11-dev - - libxft-dev - sources: - - ubuntu-toolchain-r-test - allow_failures: - env: CXX=clang++-3.8 CC=clang-3.8 addons: @@ -73,5 +57,4 @@ before_script : script: - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON - - make From 61145300f1e6449a60986fcfef8dd93e91ff50ac Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 21:21:14 +0100 Subject: [PATCH 039/309] -DCMAKE_FIND_BOOST_FILESYSTEM=OFF --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5d41b28e..44391d09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,5 +56,5 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON + - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=OFF -DINCLUDE_EXPERIMENTAL_DEMOS=ON - make From f8fb4a464d5624a014edeed0d51de6dda117b2da Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 26 Feb 2016 21:24:04 +0100 Subject: [PATCH 040/309] restore travis --- .travis.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 44391d09..c3b00bb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,21 @@ matrix: - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test - + - env: CXX=g++-4.9 CC=gcc-4.9 + addons: + apt: + packages: + - g++-4.9 + - libjpeg8-dev + - libpng-dev + - libasound2-dev + - alsa-utils + - alsa-oss + - libx11-dev + - libxft-dev + sources: + - ubuntu-toolchain-r-test + allow_failures: - env: CXX=clang++-3.8 CC=clang-3.8 addons: @@ -57,4 +71,5 @@ before_script : script: - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=OFF -DINCLUDE_EXPERIMENTAL_DEMOS=ON - - make + + - make \ No newline at end of file From 7f10f8d28de464735bec52f51824d6931f429379 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 27 Feb 2016 00:13:37 +0100 Subject: [PATCH 041/309] add STD_put_time_NOT_SUPPORTED --- include/nana/c++defines.hpp | 8 ++++++- include/nana/deploy.hpp | 18 ++++++++++++++++ source/deploy.cpp | 43 +++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index d23e0a48..f7ac48e5 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -31,6 +31,7 @@ * - _SCL_SECURE_NO_WARNNGS, _CRT_SECURE_NO_DEPRECATE (VC) * - STD_CODECVT_NOT_SUPPORTED (VC RC, is a known issue on libstdc++, it works on libc++) * - STD_THREAD_NOT_SUPPORTED (GCC < 4.8.1) + * - STD_put_time_NOT_SUPPORTED (GCC < 5) * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) * - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8) @@ -133,8 +134,13 @@ #endif #endif + + #if ((__GNUC__ > 5) ) + # defie STD_put_time_NOT_SUPPORTED + #endif + #if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) - #undef STD_FILESYSTEM_NOT_SUPPORTED + # undef STD_FILESYSTEM_NOT_SUPPORTED #endif #if (__GNUC__ == 4) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 35659972..afb955da 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -92,6 +92,24 @@ namespace std } #endif +#ifdef STD_put_time_NOT_SUPPORTED +namespace std +{ + //Workaround for no implemenation of std::put_time in gcc < 5. + /* std unspecified return type */ + //template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t + //RTSTR put_time(const std::tm* tmb, const CharT* fmt); + + //template< > + std::string put_time/**/(const std::tm* tmb, const char* fmt); + + //Defined in header + // std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time); + //template<> + //std::wstring put_time(const std::tm* tmb, const wchar_t* fmt); +} +#endif // STD_put_time_NOT_SUPPORTED + namespace nana { /// Checks whether a specified text is utf8 encoding diff --git a/source/deploy.cpp b/source/deploy.cpp index 3592a3bf..91c4300d 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -436,6 +436,49 @@ namespace std } #endif +//#ifdef STD_put_time_NOT_SUPPORTED +#include +#include +namespace std +{ + //Workaround for no implemenation of std::put_time in gcc < 5. + /* std unspecified return type */ + //template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t + //RTSTR put_time(const std::tm* tmb, const CharT* fmt); + + //template< > + std::string put_time/**/(const std::tm* tmb, const char* fmt) + { + unsigned sz = 200; + std::string str(sz, '\0'); + sz = std::strftime(&str[0], str.size() - 1, fmt, tmb); + str.resize(sz); + return str; + } + //Defined in header + // std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time); + //template<> + //std::wstring put_time(const std::tm* tmb, const wchar_t* fmt) + //{ + // unsigned sz = 200; + // std::wstring str(sz, L'\0'); + // sz = std::wcsftime(&str[0], str.size() - 1, fmt, tmb); + // str.resize(sz); + // return str; + //} + // http://en.cppreference.com/w/cpp/chrono/c/wcsftime + // Defined in header + // std::size_t wcsftime(wchar_t* str, std::size_t count, const wchar_t* format, const std::tm* time); + // Converts the date and time information from a given calendar time time to a null - terminated + // wide character string str according to format string format.Up to count bytes are written. + // Parameters + // str - pointer to the first element of the wchar_t array for output + // count - maximum number of wide characters to write + // format - pointer to a null - terminated wide character string specifying the format of conversion. + + } +//#endif // STD_put_time_NOT_SUPPORTED + namespace nana { bool is_utf8(const char* str, unsigned len) From 1f2a48e63e3a42584956b5ff191905548c0b54b8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 27 Feb 2016 00:14:10 +0100 Subject: [PATCH 042/309] test boost fs --- .travis.yml | 2 +- include/nana/filesystem/filesystem_selector.hpp | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index c3b00bb2..216196c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,6 +70,6 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=OFF -DINCLUDE_EXPERIMENTAL_DEMOS=ON + - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON - make \ No newline at end of file diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index 5b00e0c7..b2a02293 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -55,13 +55,7 @@ namespace std { namespace std { namespace experimental { namespace filesystem { - -# ifdef CXX_NO_INLINE_NAMESPACE - using namespace boost::experimental::filesystem; -# else - using namespace boost::experimental::filesystem::v3; -# endif - + using namespace boost::filesystem; } // filesystem } // experimental } // std From 13123710337b5e0e8b2486dd027903907cb4d6a8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 27 Feb 2016 00:40:16 +0100 Subject: [PATCH 043/309] fix STD_put_time_NOT_SUPPORTED --- include/nana/c++defines.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index f7ac48e5..02970f53 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -135,7 +135,7 @@ #endif - #if ((__GNUC__ > 5) ) + #if ((__GNUC__ < 5) ) # defie STD_put_time_NOT_SUPPORTED #endif From fd1904ccc7f10f70663de6073cee8f2d1d49d64d Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 27 Feb 2016 00:44:40 +0100 Subject: [PATCH 044/309] fix define --- include/nana/c++defines.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 02970f53..6d5df62b 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -136,7 +136,7 @@ #if ((__GNUC__ < 5) ) - # defie STD_put_time_NOT_SUPPORTED + # define STD_put_time_NOT_SUPPORTED #endif #if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) From 0660530cd211339ec29c68ce44d250c8569918e2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 27 Feb 2016 00:51:00 +0100 Subject: [PATCH 045/309] =?UTF-8?q?fix=20=E2=80=98tm=E2=80=99=20in=20names?= =?UTF-8?q?pace=20=E2=80=98std=E2=80=99=20does=20not=20name=20a=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/nana/deploy.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index afb955da..069545cb 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -93,6 +93,7 @@ namespace std #endif #ifdef STD_put_time_NOT_SUPPORTED +#include namespace std { //Workaround for no implemenation of std::put_time in gcc < 5. From 9e176eb13bef7f4ed344c414f4903550fa34c6d4 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 27 Feb 2016 01:20:24 +0100 Subject: [PATCH 046/309] use old tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 02ceda02..4dd0deb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=50 --branch=master https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=50 --branch=stable https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From f236ca91cf6c2e2f515668d2ea3e164df9dc5f05 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 27 Feb 2016 16:47:27 -0800 Subject: [PATCH 047/309] Copy include files to installation directory. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 594c5f4c..ad065543 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,6 +225,10 @@ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) +# Install include directories too. +install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/nana + DESTINATION include) + set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file From 4eef6c679a4bfb47704cc1b2edb72472c1f36056 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 27 Feb 2016 17:55:39 -0800 Subject: [PATCH 048/309] Fixed path to experimental filesystem header for GNU environments. --- include/nana/filesystem/filesystem_selector.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index b2a02293..7d18115f 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -60,6 +60,8 @@ namespace std { } // experimental } // std +#elif (__GNUC__) +# include #else # include #endif From be2b67d9707524a7d1b6ef9266a2165056310e4a Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 29 Feb 2016 00:23:04 +0100 Subject: [PATCH 049/309] by default but optionally install includes, make easy to find variables in large lists --- CMakeLists.txt | 108 +++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ad065543..636b6176 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,16 +18,17 @@ cmake_minimum_required(VERSION 2.8) set(NANA_LINKS) -option(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF) -option(ENABLE_PNG "Enable the use of PNG" OFF) -option(LIBPNG_FROM_OS "Use libpng from operating system." ON) -option(ENABLE_JPEG "Enable the use of JPEG" OFF) -option(LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) -option(ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) -option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) -option(CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) -option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF) -option(INCLUDE_EXPERIMENTAL_DEMOS "" ON) +option(NANA_CMAKE_INSTALL_INCLUDES "Install nana includes when compile the library" ON) +option(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF) +option(NANA_CMAKE_ENABLE_PNG "Enable the use of PNG" OFF) +option(NANA_CMAKE_LIBPNG_FROM_OS "Use libpng from operating system." ON) +option(NANA_CMAKE_ENABLE_JPEG "Enable the use of JPEG" OFF) +option(NANA_CMAKE_LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) +option(NANA_CMAKE_ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) +option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) +option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) +option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." OFF) +option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf @@ -41,28 +42,28 @@ option(INCLUDE_EXPERIMENTAL_DEMOS "" ON) # to use boost if available. Nana own implementation will be use only none of them are available. # You can change that default if you change one of the following # (please don't define more than one of the _XX_FORCE options): -option(CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" ON) -option(CMAKE_NANA_FILESYSTEM_FORCE "Force nana filesystem over ISO and boost?" OFF) -option(CMAKE_STD_FILESYSTEM_FORCE "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF) -option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over STD)?" OFF) +option(NANA_CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" ON) +option(NANA_CMAKE_NANA_FILESYSTEM_FORCE "Force nana filesystem over ISO and boost?" OFF) +option(NANA_CMAKE_STD_FILESYSTEM_FORCE "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF) +option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over STD)?" OFF) # cmake will find the package self, if don't works set the following (please find the correct values): -#option(CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") -#option(CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") -#include_directories("${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") -#list(APPEND NANA_LINKS "${CMAKE_BOOST_FILESYSTEM_LIB}") +#option(NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") +#option(NANA_CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") +#include_directories("${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") +#list(APPEND NANA_LINKS "${NANA_CMAKE_BOOST_FILESYSTEM_LIB}") -if (CMAKE_NANA_FILESYSTEM_FORCE) +if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) add_definitions(-DNANA_FILESYSTEM_FORCE) -elseif (CMAKE_STD_FILESYSTEM_FORCE) +elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE) add_definitions(-DSTD_FILESYSTEM_FORCE) -elseif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) +elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) - if (CMAKE_BOOST_FILESYSTEM_FORCE) + if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) - endif(CMAKE_BOOST_FILESYSTEM_FORCE) + endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) # https://cmake.org/cmake/help/git-master/module/FindBoost.html # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, @@ -79,7 +80,7 @@ elseif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) set(Boost_USE_STATIC_RUNTIME ON) # ?? #set(Boost_USE_MULTITHREADED ON) -endif (CMAKE_FIND_BOOST_FILESYSTEM OR CMAKE_BOOST_FILESYSTEM_FORCE) +endif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) @@ -104,9 +105,9 @@ if(WIN32) endif(MSVC) if(MINGW) - if(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + if(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) - endif(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + endif(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(MINGW) elseif(WIN32) set(BUILD_FreeMe OFF) @@ -134,34 +135,34 @@ if(UNIX) endif(UNIX) #Find PNG -if(ENABLE_PNG) +if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) #set(NANA_PNG_LIB "png") list(APPEND NANA_LINKS -lpng ) - if(LIBPNG_FROM_OS) + if(NANA_CMAKE_LIBPNG_FROM_OS) find_package(PNG) if (PNG_FOUND) include_directories( ${PNG_INCLUDE_DIRS}) add_definitions(-DUSE_LIBPNG_FROM_OS) endif(PNG_FOUND) - endif(LIBPNG_FROM_OS) -endif(ENABLE_PNG) + endif(NANA_CMAKE_LIBPNG_FROM_OS) +endif(NANA_CMAKE_ENABLE_PNG) #Find JPEG -if(ENABLE_JPEG) +if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) #set(NANA_JPEG_LIB "jpeg") list(APPEND NANA_LINKS -ljpeg ) - if(LIBJPEG_FROM_OS) + if(NANA_CMAKE_LIBJPEG_FROM_OS) find_package(JPEG) if (JPEG_FOUND) include_directories( ${JPEG_INCLUDE_DIRS}) add_definitions(-DUSE_LIBJPEG_FROM_OS) endif(JPEG_FOUND) - endif(LIBJPEG_FROM_OS) -endif(ENABLE_JPEG) + endif(NANA_CMAKE_LIBJPEG_FROM_OS) +endif(NANA_CMAKE_ENABLE_JPEG) -if(ENABLE_AUDIO) +if(NANA_CMAKE_ENABLE_AUDIO) add_definitions(-DNANA_ENABLE_AUDIO) if(UNIX) find_package(ASOUND) @@ -172,11 +173,11 @@ if(ENABLE_AUDIO) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) endif(UNIX) -endif(ENABLE_AUDIO) +endif(NANA_CMAKE_ENABLE_AUDIO) -if(CMAKE_VERBOSE_PREPROCESSOR) +if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) -endif(CMAKE_VERBOSE_PREPROCESSOR) +endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) @@ -194,7 +195,7 @@ 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) -if(ENABLE_AUDIO) +if(NANA_CMAKE_ENABLE_AUDIO) aux_source_directory(${NANA_SOURCE_DIR}/audio NANA_AUDIO_SOURCE) aux_source_directory(${NANA_SOURCE_DIR}/audio/detail NANA_AUDIO_DETAIL_SOURCE) endif() @@ -226,19 +227,21 @@ install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib) # Install include directories too. -install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/nana - DESTINATION include) +if(NANA_CMAKE_INSTALL_INCLUDES) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/nana + DESTINATION include) +endif(NANA_CMAKE_INSTALL_INCLUDES) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file -if (BUILD_NANA_DEMOS) +if (NANA_CMAKE_BUILD_DEMOS) set (demos calculator notepad widget_show widget_show2 ) - if (INCLUDE_EXPERIMENTAL_DEMOS) + if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer) - endif (INCLUDE_EXPERIMENTAL_DEMOS) + endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe foreach ( demo ${demos}) @@ -268,7 +271,7 @@ if (BUILD_NANA_DEMOS) message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) -endif (BUILD_NANA_DEMOS) +endif (NANA_CMAKE_BUILD_DEMOS) # set compile flags @@ -297,14 +300,13 @@ message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) -message ( "NANA_LINKS = " ${NANA_LINKS}) -message ( "ENABLE_AUDIO = " ${ENABLE_AUDIO}) -message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) message ( "DESTDIR = " ${DESTDIR}) -message ( "CMAKE_BOOST_FILESYSTEM_AVAILABLE = " ${CMAKE_BOOST_FILESYSTEM_AVAILABLE}) -message ( "NANA_BOOST_FILESYSTEM_PREFERRED = " ${NANA_BOOST_FILESYSTEM_PREFERRED}) -message ( "CMAKE_BOOST_FILESYSTEM_FORCE = " ${CMAKE_BOOST_FILESYSTEM_FORCE}) -message ( "CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}) -message ( "CMAKE_BOOST_FILESYSTEM_LIB = " ${CMAKE_BOOST_FILESYSTEM_LIB}) +message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) +message ( "NANA_LINKS = " ${NANA_LINKS}) +message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO}) +message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) +message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) +message ( "NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}) +message ( "NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB}) From bd0e27deb88f8060a5afa90f6a2931be76dbdf37 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 29 Feb 2016 00:23:55 +0100 Subject: [PATCH 050/309] Microsoft also support --- include/nana/filesystem/filesystem_selector.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index 7d18115f..b0d3ae3a 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -60,10 +60,8 @@ namespace std { } // experimental } // std -#elif (__GNUC__) -# include #else -# include +# include #endif #ifndef __cpp_lib_experimental_filesystem From 282508d54faa285d72b61a2b677b5a63c04a19d8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 29 Feb 2016 00:32:32 +0100 Subject: [PATCH 051/309] update travis too --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 216196c3..5ab94854 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,6 +70,6 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF -DCMAKE_FIND_BOOST_FILESYSTEM=ON -DINCLUDE_EXPERIMENTAL_DEMOS=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON - make \ No newline at end of file From 54ecf4d7140faee6acaae6b40d6c94774d608c92 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 29 Feb 2016 14:30:49 +0100 Subject: [PATCH 052/309] a simple but not trivial HelloWorld --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 636b6176..e223c53c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) set(Boost_USE_STATIC_RUNTIME ON) # ?? #set(Boost_USE_MULTITHREADED ON) -endif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) +endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) @@ -238,7 +238,7 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if (NANA_CMAKE_BUILD_DEMOS) - set (demos calculator notepad widget_show widget_show2 ) + set (demos calculator helloworld_demo notepad widget_show widget_show2 ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer) endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) From 8be4603ef5331942347d585c419acdddc7659055 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 1 Mar 2016 14:12:48 +0100 Subject: [PATCH 053/309] doxygen comments --- build/makefile/readme.md | 6 ++--- include/nana/gui/basis.hpp | 48 +++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/build/makefile/readme.md b/build/makefile/readme.md index 1b8d9b1b..38ce2141 100644 --- a/build/makefile/readme.md +++ b/build/makefile/readme.md @@ -1,8 +1,8 @@ -Building Nana C++ Library -requires: +# Building Nana C++ Library directly with make +If you are using make directly, it require: X11, pthread, Xpm, rt, dl, freetype2, Xft, fontconfig, ALSA -Writing a makefile for creating applications with Nana C++ Library +Example of writing a makefile for creating applications with Nana C++ Library ------------------- ``` GCC = g++ diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index 26ca8885..55518554 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -1,15 +1,15 @@ -/* +/** + * \file basis.hpp + * \brief This file provides basis class and data structures required by the GUI + * * Basis Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/basis.hpp - * - * This file provides basis class and data structrue that required by gui */ #ifndef NANA_GUI_BASIS_HPP @@ -151,7 +151,25 @@ namespace nana appearance(); appearance(bool has_decoration, bool taskbar, bool floating, bool no_activate, bool min, bool max, bool sizable); }; - /// Provided to generate an appearance object with better readability and understandability + + +/** @brief Provided to generate an appearance object with better readability and understandability + +A window has an appearance. This appearance can be specified when a window is being created. +To determine the appearance of a window there is a structure named nana::appearance with +a bool member for each feature with can be included or excluded in the "apereance" of the windows form. +But in practical development is hard to describe the style of the appearance using the struct nana::appearance. +If a form would to be defined without min/max button and sizable border, then + +\code{.CPP} + nana::form form(x, y, width, height, nana::appearance(false, false, false, true, false)); +\endcode + +This piece of code may be confusing because of the 5 parameters of the constructor of `nana::form`. So the library provides a helper class for making it easy. +For better readability and understandability Nana provides three templates classes to generate an appearance object: +nana::appear::decorate, nana::appear::bald and nana::appear::optional. Each provide an operator +that return a corresponding nana::appearance with predefined values. +*/ struct appear { struct minimize{}; @@ -160,7 +178,20 @@ namespace nana struct taskbar{}; struct floating{}; struct no_activate{}; - /// Create an appearance of a window with "decoration" + + /** @brief Create an appearance of a window with "decoration" in non-client area, such as title bar + * + * We can create a form without min/max button and sizable border like this: + * \code{.CPP} + * using nana::appear; + * nana::form form(x, y, width, height, appear::decorate()); + * \endcode + * The appearance created by appear::decorate<>() has a titlebar and borders that are draw by the + * platform- window manager. If a window needs a minimize button, it should be: + * \code{.CPP} + * appear::decorate() + * \endcode + */ template< typename Minimize = null_type, typename Maximize = null_type, typename Sizable = null_type, @@ -181,7 +212,8 @@ namespace nana ); } }; - /// Create an appearance of a window without "decoration" + + /// Create an appearance of a window without "decoration" with no titlebar and no 3D-look borders. template < typename Taskbar = null_type, typename Floating = null_type, typename NoActive = null_type, From ddbbdf21ff1580009ee29a92a72b77cbf98b4989 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 1 Mar 2016 17:00:43 +0100 Subject: [PATCH 054/309] doxy comments --- include/nana/gui/detail/general_events.hpp | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 8d75dc9e..87a7b2b2 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -42,7 +42,7 @@ namespace nana void events_operation_cancel(event_handle); }//end namespace detail - /// base clase for all event argument types + /// base class for all event argument types class event_arg { public: @@ -57,7 +57,12 @@ namespace nana struct general_events; - /// the type of the members of general_events + /// \brief the type of the members of general_events. + /// It connect the functions to be called as response to the event and manages that chain of responses + /// It is a functor, that get called to connect a "normal" response function, with normal "priority". + /// If a response function need another priority (unignorable or called first) it will need to be connected with + /// the specific connect function not with the operator() + /// It also permit to "emit" that event, calling all the active responders. template class basic_event : public detail::event_interface { @@ -68,6 +73,8 @@ namespace nana : public detail::docker_interface { basic_event * const event_ptr; + + /// the callback/response function taking the typed argument std::function invoke; bool flag_deleted{ false }; @@ -92,9 +99,9 @@ namespace nana } }; - //class emit_counter is a RAII helper for emitting count - //It is used for avoiding a try{}catch block which is required for some finial works when - //event handlers throw exceptions. + /// \breif RAII helper for emitting count. + /// It is used to avoid a try{}catch block which is required for some finial works when + /// event handlers throw exceptions. class emit_counter { public: @@ -133,11 +140,12 @@ namespace nana using prototype = typename std::remove_reference::type; std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); auto evt = reinterpret_cast(dck.get()); - dockers_->emplace(dockers_->begin(), std::move(dck)); + dockers_->emplace(dockers_->begin(), std::move(dck)); // <---- the difference detail::events_operation_register(evt); return evt; } + /// It will not get called if stop_propagation() was called. event_handle connect(void (*fn)(arg_reference)) { return connect([fn](arg_reference arg){ @@ -145,7 +153,7 @@ namespace nana }); } - /// It will not get called if stop_propagation() was called. + /// It will not get called if stop_propagation() was called, because it is set at the end of the chain.. template event_handle connect(Function && fn) { @@ -156,7 +164,7 @@ namespace nana using prototype = typename std::remove_reference::type; std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); auto evt = reinterpret_cast(dck.get()); - dockers_->emplace_back(std::move(dck)); + dockers_->emplace_back(std::move(dck)); // <---- the difference detail::events_operation_register(evt); return evt; } @@ -187,12 +195,14 @@ namespace nana return evt; } + /// how many responses are registered? std::size_t length() const { internal_scope_guard lock; return (nullptr == dockers_ ? 0 : dockers_->size()); } + /// by emitting the event it call each active response with the given arg. void emit(arg_reference& arg) { internal_scope_guard lock; @@ -205,7 +215,7 @@ namespace nana const auto dockers_len = dockers.size(); //The dockers may resize when a new event handler is created by a calling handler. - //Traverses with position can avaid crash error which caused by a iterator which becomes invalid. + //Traverses with position can avoid crash error caused by an iterator which becomes invalid. for (std::size_t pos = 0; pos < dockers_len; ++pos) { auto docker_ptr = static_cast(dockers[pos].get()); @@ -221,7 +231,7 @@ namespace nana if (!docker_ptr->unignorable || docker_ptr->flag_deleted) continue; - docker_ptr->invoke(arg); + docker_ptr->invoke(arg); // <--- finally call the response } break; } @@ -418,11 +428,11 @@ namespace nana bool deleted_flags_{ false }; std::unique_ptr>> dockers_; }; - + struct arg_mouse : public event_arg { - event_code evt_code; ///< + event_code evt_code; ///< what kind of mouse event? ::nana::window window_handle; ///< A handle to the event window ::nana::point pos; ///< cursor position in the event window ::nana::mouse button; ///< indicates a button which triggers the event @@ -473,7 +483,7 @@ namespace nana { ::nana::window window_handle; ///< A handle to the event window ::nana::native_window_type receiver; ///< it is a native window handle, and specified which window receives focus - bool getting; ///< the window received focus? + bool getting; ///< the window received focus? (as oppose to losing focus) }; struct arg_keyboard : public event_arg @@ -518,7 +528,7 @@ namespace nana { ::nana::window window_handle; ///< A handle to the event window }; - + /// a higher level event argument than just mouse down struct arg_click : public event_arg { ::nana::window window_handle; ///< A handle to the event window From d09c1bd733d3fd06f4f546a6d390c00be924f900 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 1 Mar 2016 18:54:31 +0100 Subject: [PATCH 055/309] brief --- include/nana/gui/detail/general_events.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 87a7b2b2..8c17ff28 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -58,6 +58,7 @@ namespace nana struct general_events; /// \brief the type of the members of general_events. + /// It connect the functions to be called as response to the event and manages that chain of responses /// It is a functor, that get called to connect a "normal" response function, with normal "priority". /// If a response function need another priority (unignorable or called first) it will need to be connected with @@ -99,7 +100,8 @@ namespace nana } }; - /// \breif RAII helper for emitting count. + /// \brief RAII helper for emitting count. + /// It is used to avoid a try{}catch block which is required for some finial works when /// event handlers throw exceptions. class emit_counter @@ -451,7 +453,8 @@ namespace nana } }; - /// in arg_wheel event_code is event_code::mouse_wheel + /// \brief in arg_wheel event_code is event_code::mouse_wheel + /// The type arg_wheel is derived from arg_mouse, a handler /// with prototype void(const arg_mouse&) can be set for mouse_wheel. struct arg_wheel : public arg_mouse From cbe639900805e2281121b59dbd4dff8f491fe59b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 1 Mar 2016 18:57:03 +0100 Subject: [PATCH 056/309] doxy --- include/nana/gui/detail/general_events.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 8c17ff28..29dae364 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -57,13 +57,14 @@ namespace nana struct general_events; - /// \brief the type of the members of general_events. - - /// It connect the functions to be called as response to the event and manages that chain of responses - /// It is a functor, that get called to connect a "normal" response function, with normal "priority". - /// If a response function need another priority (unignorable or called first) it will need to be connected with - /// the specific connect function not with the operator() - /// It also permit to "emit" that event, calling all the active responders. + /** @brief the type of the members of general_events. + * + * It connect the functions to be called as response to the event and manages that chain of responses + * It is a functor, that get called to connect a "normal" response function, with normal "priority". + * If a response function need another priority (unignorable or called first) it will need to be connected with + * the specific connect function not with the operator() + * It also permit to "emit" that event, calling all the active responders. + */ template class basic_event : public detail::event_interface { From 976b5ec275e155e1f3b147c6989e2a01637f6acb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 1 Mar 2016 18:59:57 +0100 Subject: [PATCH 057/309] explore automatic GUI testing in VS2015, cmake and travis local works vary good in windows with VS2015 --- .travis.yml | 7 ++++--- CMakeLists.txt | 14 +++++++++++++ include/nana/gui/wvl.hpp | 5 ++++- source/gui/wvl.cpp | 43 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ab94854..be36e3c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=50 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=50 --branch=testing https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true @@ -70,6 +70,7 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=OFF - - make \ No newline at end of file + - make + - clicked \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e223c53c..94fa3494 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,9 @@ option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during comp option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." OFF) option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) +option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) +option(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING "Add defoult automatic GUI test?" OFF) + # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf @@ -238,6 +241,17 @@ set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if (NANA_CMAKE_BUILD_DEMOS) + if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + + if(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) + endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) + + NANA_ADD_DEF_AUTOMATIC_GUI_TESTING + + set (demos calculator helloworld_demo notepad widget_show widget_show2 ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer) diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index 1f104bbd..a55ec00b 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -15,6 +15,8 @@ #ifndef NANA_GUI_WVL_HPP #define NANA_GUI_WVL_HPP + + #include "programming_interface.hpp" #include "screen.hpp" #include "widgets/form.hpp" @@ -58,6 +60,7 @@ namespace nana template using form_loader = detail::form_loader; - void exec(); + void exec(unsigned wait = 0, std::function = {}); + }//end namespace nana #endif diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index cedca916..912bc3ef 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -13,6 +13,22 @@ #include #include +#include + +#include + + +//#define NANA_AUTOMATIC_GUI_TESTING + +inline unsigned Wait(unsigned wait = 0) +{ +#ifdef NANA_AUTOMATIC_GUI_TESTING + return wait; +#else + return 0; +#endif +} + namespace nana { namespace detail @@ -23,8 +39,33 @@ namespace nana } } - void exec() + void exec(unsigned wait, std::function f ) { + #ifdef NANA_ADD_DEF_AUTOMATIC_GUI_TESTING + if (!wait) + wait = 10; + if (!f) + f = []() {API::exit(); }; + #endif + + wait = Wait(wait); + + std::cout << "Will wait " << wait << " sec...\n"; + std::thread t([wait, &f]() + { if (wait) + { + std::cout << "Waiting " << wait << " sec...\n"; + std::this_thread::sleep_for(std::chrono::seconds{ wait } ); + std::cout << "Waited !! running... \n" ; + f(); + //API::exit(); + std::cout << "Runed... \n"; + } + }); + detail::bedrock::instance().pump_event(nullptr, false); + + if (t.joinable()) + t.join(); } }//end namespace nana From 18a919f11e0cd89e5a7fdaa4bbdc6649d3b381d0 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 1 Mar 2016 19:06:33 +0100 Subject: [PATCH 058/309] fix --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94fa3494..b2ce1517 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,9 +249,6 @@ if (NANA_CMAKE_BUILD_DEMOS) add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - NANA_ADD_DEF_AUTOMATIC_GUI_TESTING - - set (demos calculator helloworld_demo notepad widget_show widget_show2 ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer) From 37ed48d38ad2149534e9ca08526a8e33f874e357 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 1 Mar 2016 19:23:35 +0100 Subject: [PATCH 059/309] add_custom_command( TARGET clicked POST_BUILD COMMAND clicked ) --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2ce1517..334a5741 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,6 +282,13 @@ if (NANA_CMAKE_BUILD_DEMOS) message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) + if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_custom_command( TARGET clicked POST_BUILD COMMAND clicked ) + endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + +add_custom_command(OUTPUT generated.cpp generated.hpp + COMMAND marks-code-generator + endif (NANA_CMAKE_BUILD_DEMOS) From 6160801bdf23c698d915f90d80908c0f11a8b883 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 1 Mar 2016 19:26:38 +0100 Subject: [PATCH 060/309] fix --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 334a5741..34bf68e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,9 +286,6 @@ if (NANA_CMAKE_BUILD_DEMOS) add_custom_command( TARGET clicked POST_BUILD COMMAND clicked ) endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) -add_custom_command(OUTPUT generated.cpp generated.hpp - COMMAND marks-code-generator - endif (NANA_CMAKE_BUILD_DEMOS) From 669a7385a6e2dc36996bd20c81da88eae1a90e6e Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 1 Mar 2016 19:33:50 +0100 Subject: [PATCH 061/309] # --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34bf68e6..e66ae762 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,7 +283,7 @@ if (NANA_CMAKE_BUILD_DEMOS) endforeach( demo ${demos}) if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_custom_command( TARGET clicked POST_BUILD COMMAND clicked ) + #add_custom_command( TARGET clicked POST_BUILD COMMAND clicked ) endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) endif (NANA_CMAKE_BUILD_DEMOS) From b8eb7dbffd61323bbc99106c74fa584a2ed88e42 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 1 Mar 2016 19:34:50 +0100 Subject: [PATCH 062/309] ls --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index be36e3c6..81a75b7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,4 +73,5 @@ script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=OFF - make - - clicked \ No newline at end of file + - ls + - clicked From 59d94b9c7a1887de58c343cbb93dc7dfb0ff9f49 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 11:42:19 +0100 Subject: [PATCH 063/309] FreeMe need more work - let out of the way temporally --- CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e66ae762..af383c4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) option(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING "Add defoult automatic GUI test?" OFF) +option(NANA_CMAKE_BUILD_FreeMe "Build FreeMe (currently broken)?" OFF) # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. @@ -178,6 +179,10 @@ if(NANA_CMAKE_ENABLE_AUDIO) endif(UNIX) endif(NANA_CMAKE_ENABLE_AUDIO) +if (NANA_CMAKE_BUILD_FreeMe) + add_definitions(-DBUILD_FreeMe) +endif (NANA_CMAKE_BUILD_FreeMe) + if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) @@ -250,10 +255,11 @@ if (NANA_CMAKE_BUILD_DEMOS) endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) set (demos calculator helloworld_demo notepad widget_show widget_show2 ) + if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - list(APPEND demos file_explorer) + list(APPEND demos file_explorer FreeMe) endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - # Pending: FreeMe + # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") From 8cb8655147a45a583bb5340fc215f1bb72a7e82b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 11:43:05 +0100 Subject: [PATCH 064/309] -DNANA_AUTOMATIC_GUI_TESTING --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af383c4d..99bd332e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,8 +113,6 @@ if(WIN32) add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(MINGW) -elseif(WIN32) - set(BUILD_FreeMe OFF) endif(WIN32) if(APPLE) @@ -183,6 +181,10 @@ if (NANA_CMAKE_BUILD_FreeMe) add_definitions(-DBUILD_FreeMe) endif (NANA_CMAKE_BUILD_FreeMe) +if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) +endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) From a2fd7f32c85fb56df340f08866c6bc6d723912c6 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 14:05:48 +0100 Subject: [PATCH 065/309] NANA_ADD_DEF_AUTOMATIC_GUI_TESTING Support for NANA_AUTOMATIC_GUI_TESTING Will cause the program to self-test the GUI. If NANA_ADD_DEF_AUTOMATIC_GUI_TESTING is also defined a default automatic GUI test will be added to all programs which don't have yet one defined. This default test will simple wait 10 sec. (time to construct, show and execute the GUI) and then exit normally. --- CMakeLists.txt | 9 +++++++++ include/nana/config.hpp | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99bd332e..cf01bf48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,8 +183,15 @@ endif (NANA_CMAKE_BUILD_FreeMe) if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + + if(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) + endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) + endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + + if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) @@ -331,5 +338,7 @@ message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB}) +message ( "NANA_CMAKE_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_AUTOMATIC_GUI_TESTING}) +message ( "NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING}) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 2c1d3c83..99d73d31 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -93,6 +93,21 @@ #endif #endif + +/////////////////// +// Support for NANA_AUTOMATIC_GUI_TESTING +// Will cause the program to self-test the GUI. +// If NANA_ADD_DEF_AUTOMATIC_GUI_TESTING is also defined a default automatic GUI test +// will be added to all programs which don't have yet one defined. This default test will simple +// wait 10 sec. (time to construct, show and execute the GUI) and then exit normally. +// +//#define NANA_AUTOMATIC_GUI_TESTING +//#if defined(NANA_AUTOMATIC_GUI_TESTING) + //#define NANA_ADD_DEF_AUTOMATIC_GUI_TESTING +//#endif + + + #if !defined(VERBOSE_PREPROCESSOR) //#define VERBOSE_PREPROCESSOR #endif From 3184022bf1ada9e5db5bb1e50ceb8adaba699d89 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 14:08:14 +0100 Subject: [PATCH 066/309] wait and close --- include/nana/gui/wvl.hpp | 2 +- source/gui/wvl.cpp | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index a55ec00b..aac2319e 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -60,7 +60,7 @@ namespace nana template using form_loader = detail::form_loader; - void exec(unsigned wait = 0, std::function = {}); + void exec(unsigned wait = 0, std::function = {}, unsigned wait_end=0, form *fm= nullptr); }//end namespace nana #endif diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 912bc3ef..621e9c4c 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -18,8 +18,6 @@ #include -//#define NANA_AUTOMATIC_GUI_TESTING - inline unsigned Wait(unsigned wait = 0) { #ifdef NANA_AUTOMATIC_GUI_TESTING @@ -39,7 +37,7 @@ namespace nana } } - void exec(unsigned wait, std::function f ) + void exec(unsigned wait, std::function f, unsigned wait_end, form *fm ) { #ifdef NANA_ADD_DEF_AUTOMATIC_GUI_TESTING if (!wait) @@ -51,16 +49,21 @@ namespace nana wait = Wait(wait); std::cout << "Will wait " << wait << " sec...\n"; - std::thread t([wait, &f]() + std::thread t([wait, &f, wait_end, fm]() { if (wait) { std::cout << "Waiting " << wait << " sec...\n"; std::this_thread::sleep_for(std::chrono::seconds{ wait } ); - std::cout << "Waited !! running... \n" ; + std::cout << "running... \n" ; f(); - //API::exit(); - std::cout << "Runed... \n"; - } + std::cout << "Done... \n"; + std::cout << "Now waiting anothers " << wait << " sec...\n"; + std::this_thread::sleep_for(std::chrono::seconds{ wait_end } ); + std::cout << "Done... \n"; + if (fm) + fm->close(); + API::exit(); // why not works? + } }); detail::bedrock::instance().pump_event(nullptr, false); From 9c148a86a205d2e295213f94fa0c8a0af2bc3506 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 15:29:38 +0100 Subject: [PATCH 067/309] Wait_or_not --- source/gui/wvl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 621e9c4c..0e7e4adc 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -18,7 +18,7 @@ #include -inline unsigned Wait(unsigned wait = 0) +inline unsigned Wait_or_not(unsigned wait = 0) { #ifdef NANA_AUTOMATIC_GUI_TESTING return wait; @@ -46,7 +46,7 @@ namespace nana f = []() {API::exit(); }; #endif - wait = Wait(wait); + wait = Wait_or_not(wait); std::cout << "Will wait " << wait << " sec...\n"; std::thread t([wait, &f, wait_end, fm]() @@ -57,7 +57,7 @@ namespace nana std::cout << "running... \n" ; f(); std::cout << "Done... \n"; - std::cout << "Now waiting anothers " << wait << " sec...\n"; + std::cout << "Now waiting anothers " << wait_end << " sec...\n"; std::this_thread::sleep_for(std::chrono::seconds{ wait_end } ); std::cout << "Done... \n"; if (fm) From b000928b30ab849b0f562afa86049a75aad328ce Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 16:17:50 +0100 Subject: [PATCH 068/309] run what locally run --- CMakeLists.txt | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf01bf48..5eab2744 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,6 +181,7 @@ if (NANA_CMAKE_BUILD_FreeMe) add_definitions(-DBUILD_FreeMe) endif (NANA_CMAKE_BUILD_FreeMe) + if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) @@ -263,11 +264,24 @@ if (NANA_CMAKE_BUILD_DEMOS) add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - set (demos calculator helloworld_demo notepad widget_show widget_show2 ) + set (demos calculator helloworld_demo notepad ) - if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - list(APPEND demos file_explorer FreeMe) - endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + foreach ( demo ${demos}) + add_executable(${demo} "../nana-demo/${demo}.cpp") + set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demo} ${PROJECT_NAME}) + if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) + endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") + message("... to build: ../nana-demo/${demo}.cpp" ) + endforeach( demo ${demos}) + + set (demos widget_show widget_show2 ) + + if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + list(APPEND demos file_explorer FreeMe) + endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) foreach ( demo ${demos}) @@ -293,14 +307,10 @@ if (NANA_CMAKE_BUILD_DEMOS) set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) target_link_libraries(${demo} ${PROJECT_NAME}) install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/Examples/") - message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) - if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - #add_custom_command( TARGET clicked POST_BUILD COMMAND clicked ) - endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - + endif (NANA_CMAKE_BUILD_DEMOS) From a554ff3968956fac6db5d4268874521b4033cc57 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 16:42:40 +0100 Subject: [PATCH 069/309] no click in travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 81a75b7d..650c56a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,8 +70,8 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=OFF + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - make - ls - - clicked + From a5368a26cdd01de892c3e88d51f71cd865748fc8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 16:49:51 +0100 Subject: [PATCH 070/309] no experimental demos --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 650c56a5..7a057af0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,7 +70,7 @@ before_script : - cd bld script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=ON -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - make - ls From a97c326b176813602ac8e22ffcc7e50e55db40bb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 17:18:46 +0100 Subject: [PATCH 071/309] no calculator --- .travis.yml | 1 - CMakeLists.txt | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7a057af0..22a458ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,7 +71,6 @@ before_script : script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - - make - ls diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eab2744..9c0fd9fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,20 +264,21 @@ if (NANA_CMAKE_BUILD_DEMOS) add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - set (demos calculator helloworld_demo notepad ) + set (demos helloworld_demo notepad ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) target_link_libraries(${demo} ${PROJECT_NAME}) if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) + #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) + add_custom_target(do_always_${demo} ALL COMMAND ${demo}) endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) - set (demos widget_show widget_show2 ) + set (demos calculator widget_show widget_show2 ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos file_explorer FreeMe) From 497e5454c588c8e0b1bb4fcb0e8956a46ca48cc3 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 2 Mar 2016 17:38:30 +0100 Subject: [PATCH 072/309] add_test --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c0fd9fc..8b26d32f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -258,6 +258,7 @@ if (NANA_CMAKE_BUILD_DEMOS) if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) if(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) @@ -270,10 +271,11 @@ if (NANA_CMAKE_BUILD_DEMOS) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) target_link_libraries(${demo} ${PROJECT_NAME}) - if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) - add_custom_target(do_always_${demo} ALL COMMAND ${demo}) - endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) + add_test(${demo} COMMAND ${demo}) + #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) From 80dedf5f0d9f13e6b1ab69043d2db76dbbc7350a Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 3 Mar 2016 17:06:46 +0100 Subject: [PATCH 073/309] switch travis to demo dev_nana_in_examples --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 22a458ce..562d2955 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=50 --branch=testing https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=1 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From 8c479529d7efaa97adab7a587fbaffb8139258c3 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 3 Mar 2016 17:12:01 +0100 Subject: [PATCH 074/309] add to travis Xvfb, an X server to emulate display --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 562d2955..5bce9547 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,6 +66,9 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + - sleep 3 # give xvfb some time to start - mkdir bld - cd bld From 8bbfb38a50378bca0fb25d53f3f89e2ba1e91b62 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 3 Mar 2016 17:19:58 +0100 Subject: [PATCH 075/309] add explicit test in travis. we need to set this automatically in cmake. But first we need a general way to exit from an application from the parallel GUI testing function. Now I use fm.close(), and I need to pass a pointer to the main form to that function to do that. A general API::exit() will be much better but don't work. Why? --- .travis.yml | 21 +++++++++++++++++++++ CMakeLists.txt | 24 ++++++------------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5bce9547..d596ff49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,4 +76,25 @@ script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - make - ls + - ./clicked + - ./HelloWord + - ./background-effects + - ./categ + - ./decore + - ./dock + - ./drag-button + - ./draw + - ./file_explorer + #- ./example_menu + - ./example_listbox + #- ./example_combox + #- ./example.button + #- ./MontiHall + - ./a_group_impl + #- ./animate-bmp + #- ./calculator + #- ./helloworld_demo + #- ./notepad + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b26d32f..5fc96b22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if avail #option(NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") #option(NANA_CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") #include_directories("${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") -#list(APPEND NANA_LINKS "${NANA_CMAKE_BOOST_FILESYSTEM_LIB}") +#list(APPEND NANA_LINKS "${NANA_CMAKE_BOOST_FILESYSTEM_LIB}" ) if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) @@ -181,18 +181,6 @@ if (NANA_CMAKE_BUILD_FreeMe) add_definitions(-DBUILD_FreeMe) endif (NANA_CMAKE_BUILD_FreeMe) - -if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) - - if(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) - endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - -endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - - - if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) @@ -265,7 +253,7 @@ if (NANA_CMAKE_BUILD_DEMOS) add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - set (demos helloworld_demo notepad ) + set (demos calculator file_explorer helloworld_demo notepad ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") @@ -274,16 +262,16 @@ if (NANA_CMAKE_BUILD_DEMOS) #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) - add_test(${demo} COMMAND ${demo}) + #add_test(${demo} COMMAND ${demo}) #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) - set (demos calculator widget_show widget_show2 ) + set (demos widget_show widget_show2 ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - list(APPEND demos file_explorer FreeMe) + list(APPEND demos file_explorer FreeMe) # ?? endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) @@ -300,7 +288,7 @@ if (NANA_CMAKE_BUILD_DEMOS) decore dock drag-button draw example.button example_combox example_listbox example_menu filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 - mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image + main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image threading thread-pool various_events window-dragger windows-subclassing ) # Pending: From 39dab0f126dd677257afae79c2755c74034e19f4 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 00:44:48 +0100 Subject: [PATCH 076/309] cleanup and document GUI testing --- .travis.yml | 25 ++++++------ include/nana/gui/wvl.hpp | 30 +++++++++++--- source/gui/wvl.cpp | 85 +++++++++++++++++++++++----------------- 3 files changed, 87 insertions(+), 53 deletions(-) diff --git a/.travis.yml b/.travis.yml index d596ff49..b5b40821 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,25 +76,28 @@ script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - make - ls - - ./clicked - - ./HelloWord + - ./audio_player + - ./a_group_impl + - ./animate-bmp - ./background-effects - ./categ + - ./calculator + - ./clicked - ./decore - ./dock - ./drag-button - ./draw - ./file_explorer - #- ./example_menu + - ./example_menu - ./example_listbox - #- ./example_combox - #- ./example.button - #- ./MontiHall - - ./a_group_impl - #- ./animate-bmp - #- ./calculator - #- ./helloworld_demo - #- ./notepad + - ./example_combox + - ./example.button + - ./HelloWord + - ./MontiHall + - ./helloworld_demo + - ./notepad + + diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index aac2319e..5d6d756c 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -1,14 +1,14 @@ -/* +/** * Nana GUI Library Definition * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/wvl.hpp - * @description: + * @file nana/gui/wvl.hpp + * @description * the header file contains the files required for running of Nana.GUI */ @@ -16,7 +16,6 @@ #define NANA_GUI_WVL_HPP - #include "programming_interface.hpp" #include "screen.hpp" #include "widgets/form.hpp" @@ -60,7 +59,26 @@ namespace nana template using form_loader = detail::form_loader; - void exec(unsigned wait = 0, std::function = {}, unsigned wait_end=0, form *fm= nullptr); + /// @brief Take control of the GUI and optionaly automaticaly tests it. + /// + /// @detail It transfers to nana the program flow control, which begin pumping messages + /// from the underlying OS, interpreting and sending it with suitable arguments + /// to the nana widgets that registered a response in the corresponding event. + /// It also accept arguments to be used in case of automatic GUI testing. + /// Other Way the arguments are ignored. It seems that only works in simple + /// programs with only one active form ?? + void exec(form *main_form = nullptr, ///< used to close the program + unsigned wait = 1, ///< for the GUI to be constructed, in seconds + unsigned wait_end = 1, ///< for the GUI to be destructed, in seconds + std::function = {} ///< emit events to mimics user actions and may asert results + ); + + /// send a click message to this widget - useffull in GUI testing + void click(widget& w); + + /// in seconds + void Wait(unsigned wait = 0); + }//end namespace nana #endif diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 0e7e4adc..08714df2 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -14,18 +14,9 @@ #include #include #include - #include - -inline unsigned Wait_or_not(unsigned wait = 0) -{ -#ifdef NANA_AUTOMATIC_GUI_TESTING - return wait; -#else - return 0; -#endif -} +#define NANA_AUTOMATIC_GUI_TESTING namespace nana { @@ -37,38 +28,60 @@ namespace nana } } - void exec(unsigned wait, std::function f, unsigned wait_end, form *fm ) + void click(widget& w) { - #ifdef NANA_ADD_DEF_AUTOMATIC_GUI_TESTING - if (!wait) - wait = 10; - if (!f) - f = []() {API::exit(); }; - #endif + arg_click arg; + arg.window_handle = w.handle(); + w.events().click.emit(arg); + } - wait = Wait_or_not(wait); + /// in seconds + void Wait(unsigned wait) + { + if (wait) + std::this_thread::sleep_for(std::chrono::seconds{ wait }); + } - std::cout << "Will wait " << wait << " sec...\n"; - std::thread t([wait, &f, wait_end, fm]() - { if (wait) - { - std::cout << "Waiting " << wait << " sec...\n"; - std::this_thread::sleep_for(std::chrono::seconds{ wait } ); - std::cout << "running... \n" ; - f(); - std::cout << "Done... \n"; - std::cout << "Now waiting anothers " << wait_end << " sec...\n"; - std::this_thread::sleep_for(std::chrono::seconds{ wait_end } ); - std::cout << "Done... \n"; - if (fm) - fm->close(); - API::exit(); // why not works? - } - }); - + void pump() + { detail::bedrock::instance().pump_event(nullptr, false); + } + + void exec(form *main_form, //= nullptr, ///< used to close the program + unsigned wait, // = 1, ///< for the GUI to be constructed, in seconds + unsigned wait_end, // = 1, ///< for the GUI to be destructed, in seconds + std::functionf // = {} ///< emit events to mimics user actions and may asert results + ) + { + #ifdef NANA_AUTOMATIC_GUI_TESTING + //if (!wait) + // wait = 1; + //if (!main_form && !f) + // f = []() {API::exit(); }; + + std::cout << "Will wait " << wait << " sec...\n"; + std::thread t([wait, &f, wait_end, main_form]() + { if (wait) + { + std::cout << "Waiting " << wait << " sec...\n"; + Wait( wait ); + std::cout << "running... \n" ; + if (f) f(); + std::cout << "Done... \n"; + std::cout << "Now waiting anothers " << wait_end << " sec...\n"; + Wait(wait_end); + std::cout << "Done... \n"; + if (main_form) + main_form->close(); + API::exit(); // why not works? + } + }); + pump(); if (t.joinable()) t.join(); + #else + pump(); + #endif } }//end namespace nana From 594fee571bcf51b2451c05e5b7a9adea4a8717bd Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 01:00:28 +0100 Subject: [PATCH 077/309] tested --- .travis.yml | 15 ++++++++------- source/gui/wvl.cpp | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5b40821..2034eed2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,24 +78,25 @@ script: - ls - ./audio_player - ./a_group_impl - - ./animate-bmp + #- ./animate-bmp - ./background-effects - ./categ - - ./calculator + #- ./calculator - ./clicked - ./decore - ./dock - ./drag-button - ./draw - ./file_explorer - - ./example_menu + #- ./example_menu - ./example_listbox - - ./example_combox + #- ./example_combox - ./example.button - ./HelloWord - - ./MontiHall - - ./helloworld_demo - - ./notepad + #- ./MontiHall + #- ./helloworld_demo + #- ./notepad + - ./loader_2 diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 08714df2..24ab1241 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -17,7 +17,6 @@ #include #define NANA_AUTOMATIC_GUI_TESTING - namespace nana { namespace detail From 80af0b9a336094d5e63bde31663926e1e8180c4b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 01:04:48 +0100 Subject: [PATCH 078/309] -#define NANA_AUTOMATIC_GUI_TESTING --- source/gui/wvl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 24ab1241..732a1c69 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -16,7 +16,7 @@ #include #include -#define NANA_AUTOMATIC_GUI_TESTING +//#define NANA_AUTOMATIC_GUI_TESTING namespace nana { namespace detail From 07563a4dabd63ea73fc0857b02dd03b84b55eafa Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 01:08:37 +0100 Subject: [PATCH 079/309] more tests --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2034eed2..4ba9c5a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -91,12 +91,12 @@ script: #- ./example_menu - ./example_listbox #- ./example_combox - - ./example.button + #- ./example.button # ?? - ./HelloWord #- ./MontiHall #- ./helloworld_demo #- ./notepad - - ./loader_2 + #- ./loader_2 From a84e82029bb7092c6d2d431b04d4a86365f5f739 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 01:20:51 +0100 Subject: [PATCH 080/309] no ./widget_show2 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4ba9c5a1..ec0373fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -97,6 +97,7 @@ script: #- ./helloworld_demo #- ./notepad #- ./loader_2 + #- ./widget_show2 From e32cf4045fc1a54f789d9a324e582c90839b6412 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 01:27:23 +0100 Subject: [PATCH 081/309] no ./widget_show --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ec0373fe..e1d943a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -98,7 +98,7 @@ script: #- ./notepad #- ./loader_2 #- ./widget_show2 - + #- ./widget_show From 9c2736abe5c562c528dc8deb7af151acea239d03 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 17:16:32 +0100 Subject: [PATCH 082/309] fixing dir --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fc96b22..95da4a64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,7 +271,7 @@ if (NANA_CMAKE_BUILD_DEMOS) set (demos widget_show widget_show2 ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - list(APPEND demos file_explorer FreeMe) # ?? + list(APPEND demos FreeMe) # ?? endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) From 8043b88b1c08857fb0ddc21f1dec0e395e495195 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 17:17:03 +0100 Subject: [PATCH 083/309] fixing dir --- .gitignore | 1 + .travis.yml | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ef6de4d4..e46bb0b6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/makefile-bkl/* *.ilk *.log [Bb]in +[Bb]in/ [Dd]ebug*/ *.lib *.a diff --git a/.travis.yml b/.travis.yml index e1d943a8..c9831c4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,23 +66,26 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : + # travis dont have a fisical monitor. We need to instal an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/ - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" - sleep 3 # give xvfb some time to start - - mkdir bld - - cd bld + # we have: qPCR4vir/nana/nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) + - cd nana-demo + - mkdir bin + - cd bin script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" ../.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - make - ls - - ./audio_player - ./a_group_impl - #- ./animate-bmp + - ./animate-bmp + - ./audio_player - ./background-effects + #- ./calculator ? - ./categ - #- ./calculator - - ./clicked + - ./clicked - ./decore - ./dock - ./drag-button @@ -91,7 +94,7 @@ script: #- ./example_menu - ./example_listbox #- ./example_combox - #- ./example.button # ?? + - ./example.button - ./HelloWord #- ./MontiHall #- ./helloworld_demo From dae3b4e815df0736cb3ccbafcb63b492e4f51147 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 17:33:20 +0100 Subject: [PATCH 084/309] now with move --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c9831c4c..8a0e87e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,13 +71,16 @@ before_script : - "sh -e /etc/init.d/xvfb start" - sleep 3 # give xvfb some time to start # we have: qPCR4vir/nana/nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) - - cd nana-demo + #- cd nana-demo - mkdir bin - cd bin script: - - cmake -G"Unix Makefiles" ../.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON - make + - cd .. + - mv -v bin/ nana-demo/ + - cd nana-demo/bin - ls - ./a_group_impl - ./animate-bmp From 7125ab8f48e661e61a4fd6ab4f33e872da2bfae5 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 4 Mar 2016 23:54:42 +0100 Subject: [PATCH 085/309] exit_all --- include/nana/gui/programming_interface.hpp | 12 +++++-- include/nana/gui/wvl.hpp | 1 + source/gui/programming_interface.cpp | 38 +++++++++++++++++++++- source/gui/wvl.cpp | 30 +++++++++++------ 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 8adfd2eb..db8ffc1c 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -143,9 +143,17 @@ namespace API }; }//end namespace detail - void exit(); + void exit(); ///< close all windows in current thread + void exit_all(); ///< close all windows - std::string transform_shortkey_text(std::string text, wchar_t &shortkey, std::string::size_type *skpos); + /// @brief Searchs whether the text contains a '&' and removes the character for transforming. + /// If the text contains more than one '&' charachers, the others are ignored. e.g + /// text = "&&a&bcd&ef", the result should be "&abcdef", shortkey = 'b', and pos = 2. + std::string transform_shortkey_text + ( std::string text, ///< the text is transformed + wchar_t &shortkey, ///< the character which indicates a short key. + std::string::size_type *skpos ///< retrives the shortkey position if it is not a null_ptr; + ); bool register_shortkey(window, unsigned long); void unregister_shortkey(window); diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index 5d6d756c..176af43d 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -23,6 +23,7 @@ #include "msgbox.hpp" #include "place.hpp" + namespace nana { namespace detail diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index a5f96e98..12670941 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -326,7 +326,7 @@ namespace API return nullptr; } - //exit + //close all windows in current thread void exit() { @@ -363,6 +363,42 @@ namespace API interface_type::close_window(i); } } + //close all windows + void exit_all() + { + std::vector v; + + internal_scope_guard lock; + restrict::wd_manager().all_handles(v); + if (v.size()) + { + std::vector roots; + native_window_type root = nullptr; + //unsigned tid = nana::system::this_thread_id(); + for (auto wd : v) + { + if (/*(wd->thread_id == tid) &&*/ (wd->root != root)) + { + root = wd->root; + bool exists = false; + for (auto i = roots.cbegin(); i != roots.cend(); ++i) + { + if (*i == root) + { + exists = true; + break; + } + } + + if (!exists) + roots.push_back(root); + } + } + + for (auto i : roots) + interface_type::close_window(i); + } + } //transform_shortkey_text //@brief: This function searchs whether the text contains a '&' and removes the character for transforming. diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 732a1c69..24e58ee0 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -29,6 +29,7 @@ namespace nana void click(widget& w) { + std::cout << "Automatically clicking widget "<close(); - API::exit(); // why not works? + std::cout << "Done... Now closing the main form...\n"; + /*if (main_form) + main_form->close();*/ + std::cout << "Closed... Now API::exit ...\n"; + API::exit_all(); // why not works? + std::cout << "Done... Upps - this had not to appear !! \n"; } }); pump(); From 2c04ba7bf33b2f413e12bf2f27c6e4caec77d5eb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 5 Mar 2016 03:17:49 +0100 Subject: [PATCH 086/309] all demos added because exec() don't need main form to exit_all --- .travis.yml | 49 +++++++++++++++++++++++++++++--------- CMakeLists.txt | 13 ++++------ include/nana/config.hpp | 8 ++----- include/nana/gui/wvl.hpp | 5 ++-- source/gui/wvl.cpp | 51 +++++++++++++++++----------------------- 5 files changed, 68 insertions(+), 58 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a0e87e7..3b573ebf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,7 +86,7 @@ script: - ./animate-bmp - ./audio_player - ./background-effects - #- ./calculator ? + - ./calculator - ./categ - ./clicked - ./decore @@ -94,18 +94,45 @@ script: - ./drag-button - ./draw - ./file_explorer - #- ./example_menu + - ./example_menu - ./example_listbox - #- ./example_combox + - ./example_combox - ./example.button + - ./folder_tree_nana + - ./folder_tree_std + - ./framework_design_1 + - ./framework_design_2 + - ./framework_design_3 + - ./group - ./HelloWord - #- ./MontiHall - #- ./helloworld_demo - #- ./notepad - #- ./loader_2 - #- ./widget_show2 - #- ./widget_show - - + - ./helloword_quit + - ./inputbox + - ./label_listener + - ./lambda_event.cpp11 + - ./listbox_inline_widget + - ./listbox_Resolver + - ./loader_1 + - ./loader_2 + - ./mbox + - ./menu_debug + - ./MontiHall + - ./helloworld_demo + - ./notepad + - ./loader_2 + - ./mbox + - ./menu_debug + - ./menu_popuper + - ./modal_form + - ./widget_show2 + - ./widget_show + - ./place_login + - ./png + - ./screen + - ./stretch_image + - ./threading + - ./thread-pool + - ./various_events + - ./window-dragger + - ./windows-subclassing diff --git a/CMakeLists.txt b/CMakeLists.txt index 95da4a64..7b622422 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,6 @@ option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." OFF) option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) -option(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING "Add defoult automatic GUI test?" OFF) option(NANA_CMAKE_BUILD_FreeMe "Build FreeMe (currently broken)?" OFF) @@ -177,10 +176,6 @@ if(NANA_CMAKE_ENABLE_AUDIO) endif(UNIX) endif(NANA_CMAKE_ENABLE_AUDIO) -if (NANA_CMAKE_BUILD_FreeMe) - add_definitions(-DBUILD_FreeMe) -endif (NANA_CMAKE_BUILD_FreeMe) - if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) @@ -249,10 +244,6 @@ if (NANA_CMAKE_BUILD_DEMOS) enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - if(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - add_definitions(-DNANA_ADD_DEF_AUTOMATIC_GUI_TESTING) - endif(NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING) - set (demos calculator file_explorer helloworld_demo notepad ) foreach ( demo ${demos}) @@ -270,6 +261,10 @@ if (NANA_CMAKE_BUILD_DEMOS) set (demos widget_show widget_show2 ) +if (NANA_CMAKE_BUILD_FreeMe) + add_definitions(-DBUILD_FreeMe) +endif (NANA_CMAKE_BUILD_FreeMe) + if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos FreeMe) # ?? endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 99d73d31..4e1eb6ac 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -96,15 +96,11 @@ /////////////////// // Support for NANA_AUTOMATIC_GUI_TESTING -// Will cause the program to self-test the GUI. -// If NANA_ADD_DEF_AUTOMATIC_GUI_TESTING is also defined a default automatic GUI test +// Will cause the program to self-test the GUI. A default automatic GUI test // will be added to all programs which don't have yet one defined. This default test will simple // wait 10 sec. (time to construct, show and execute the GUI) and then exit normally. // -//#define NANA_AUTOMATIC_GUI_TESTING -//#if defined(NANA_AUTOMATIC_GUI_TESTING) - //#define NANA_ADD_DEF_AUTOMATIC_GUI_TESTING -//#endif +#define NANA_AUTOMATIC_GUI_TESTING diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index 176af43d..4da60f25 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -66,9 +66,8 @@ namespace nana /// from the underlying OS, interpreting and sending it with suitable arguments /// to the nana widgets that registered a response in the corresponding event. /// It also accept arguments to be used in case of automatic GUI testing. - /// Other Way the arguments are ignored. It seems that only works in simple - /// programs with only one active form ?? - void exec(form *main_form = nullptr, ///< used to close the program + /// Other Way the arguments are ignored. + void exec( unsigned wait = 1, ///< for the GUI to be constructed, in seconds unsigned wait_end = 1, ///< for the GUI to be destructed, in seconds std::function = {} ///< emit events to mimics user actions and may asert results diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 24e58ee0..1b475c80 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -49,46 +49,39 @@ namespace nana } - void exec(form *main_form, //= nullptr, ///< used to close the program + void exec( unsigned wait, // = 1, ///< for the GUI to be constructed, in seconds unsigned wait_end, // = 1, ///< for the GUI to be destructed, in seconds std::functionf // = {} ///< emit events to mimics user actions and may asert results ) { #ifdef NANA_AUTOMATIC_GUI_TESTING - //if (!wait) - // wait = 1; - //if (!main_form && !f) - // f = []() {API::exit_all(); }; std::cout << "Will wait " << wait << " sec...\n"; - std::thread t([wait, &f, wait_end, main_form]() - { if (wait) - { - Wait( wait ); - std::cout << "running... \n" ; - if (f) - { - f(); - std::cout << "\nCongratulations, this was not trivial !" << std::endl; - }else - { - std::cout << "\nJust a trivial test." << std::endl; - } - std::cout << "Done... \n"; - std::cout << "Now again "; - Wait(wait_end); - std::cout << "Done... Now closing the main form...\n"; - /*if (main_form) - main_form->close();*/ - std::cout << "Closed... Now API::exit ...\n"; - API::exit_all(); // why not works? - std::cout << "Done... Upps - this had not to appear !! \n"; - } - }); + + std::thread t([wait, &f, wait_end]() + { + Wait( wait ); + std::cout << "running... \n" ; + if (f) + { + f(); + std::cout << "\nCongratulations, this was not trivial !" << std::endl; + }else + { + std::cout << "\nJust a trivial test." << std::endl; + } + std::cout << "Done... \n"; + std::cout << "Now again "; + Wait(wait_end); + std::cout << "Done... Now API::exit all ...\n"; + API::exit_all(); + }); + pump(); if (t.joinable()) t.join(); + #else pump(); #endif From cdcf15ee688f0a5684eacf9f5b129305e723156c Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 5 Mar 2016 03:28:20 +0100 Subject: [PATCH 087/309] some demos don't pass --- .travis.yml | 14 +++++++------- include/nana/config.hpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b573ebf..517a34ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,7 @@ before_script : - cd bin script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - cd .. - mv -v bin/ nana-demo/ @@ -86,7 +86,7 @@ script: - ./animate-bmp - ./audio_player - ./background-effects - - ./calculator + #- ./calculator - ./categ - ./clicked - ./decore @@ -94,18 +94,18 @@ script: - ./drag-button - ./draw - ./file_explorer - - ./example_menu + #- ./example_menu - ./example_listbox - - ./example_combox + #- ./example_combox - ./example.button - - ./folder_tree_nana - - ./folder_tree_std + #- ./folder_tree_nana + #- ./folder_tree_std - ./framework_design_1 - ./framework_design_2 - ./framework_design_3 - ./group - ./HelloWord - - ./helloword_quit + #- ./helloword_quit - ./inputbox - ./label_listener - ./lambda_event.cpp11 diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 4e1eb6ac..ae11279d 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -100,7 +100,7 @@ // will be added to all programs which don't have yet one defined. This default test will simple // wait 10 sec. (time to construct, show and execute the GUI) and then exit normally. // -#define NANA_AUTOMATIC_GUI_TESTING +//#define NANA_AUTOMATIC_GUI_TESTING From 506ff45e648c3c4e9725f33beec3f9058d59bc9f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 5 Mar 2016 03:41:46 +0100 Subject: [PATCH 088/309] more demos don't pass --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 517a34ac..7710a982 100644 --- a/.travis.yml +++ b/.travis.yml @@ -106,9 +106,9 @@ script: - ./group - ./HelloWord #- ./helloword_quit - - ./inputbox + #- ./inputbox - ./label_listener - - ./lambda_event.cpp11 + #- ./lambda_event.cpp11 - ./listbox_inline_widget - ./listbox_Resolver - ./loader_1 @@ -118,8 +118,6 @@ script: - ./MontiHall - ./helloworld_demo - ./notepad - - ./loader_2 - - ./mbox - ./menu_debug - ./menu_popuper - ./modal_form From 9d038166e55a0efb0fd30c28710c55cf1e8a68b9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 5 Mar 2016 03:57:13 +0100 Subject: [PATCH 089/309] some dont pass --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7710a982..efe7ea5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -112,22 +112,22 @@ script: - ./listbox_inline_widget - ./listbox_Resolver - ./loader_1 - - ./loader_2 + #- ./loader_2 - ./mbox - ./menu_debug - - ./MontiHall - - ./helloworld_demo - - ./notepad + #- ./MontiHall + #- ./helloworld_demo + #- ./notepad - ./menu_debug - ./menu_popuper - - ./modal_form - - ./widget_show2 - - ./widget_show + #- ./modal_form + #- ./widget_show2 + #- ./widget_show - ./place_login - ./png - - ./screen + #- ./screen - ./stretch_image - - ./threading + #- ./threading # Press a char: - ./thread-pool - ./various_events - ./window-dragger From 7d4387edd41d7940f088c4d13dbe8b23360a54e7 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 5 Mar 2016 04:04:59 +0100 Subject: [PATCH 090/309] 2 more no, but 33 pass --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index efe7ea5a..2c44ccf6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -127,10 +127,10 @@ script: - ./png #- ./screen - ./stretch_image - #- ./threading # Press a char: + - ./threading - ./thread-pool - ./various_events - - ./window-dragger + #- ./window-dragger - ./windows-subclassing From 6ca18613e4857ca7b448660f38bb0b3519aaaee5 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 5 Mar 2016 04:14:10 +0100 Subject: [PATCH 091/309] thread-pool don't pass ? --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2c44ccf6..3e64fdb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -128,7 +128,7 @@ script: #- ./screen - ./stretch_image - ./threading - - ./thread-pool + #- ./thread-pool - ./various_events #- ./window-dragger - ./windows-subclassing From 6a8fb2e37c63038cea3b9f9a199258b07f05a45b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 6 Mar 2016 16:53:52 +0100 Subject: [PATCH 092/309] bedrock's comments --- include/nana/gui/detail/bedrock.hpp | 13 +++++++------ source/gui/detail/bedrock_windows.cpp | 12 ++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index e4872711..128ce532 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -1,13 +1,15 @@ -/* +/** * A Bedrock Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/detail/bedrock.hpp + * @file nana/gui/detail/bedrock.hpp + * + * @brief A Bedrock Implementation */ #ifndef NANA_GUI_DETAIL_BEDROCK_HPP @@ -26,9 +28,8 @@ namespace detail struct basic_window; class window_manager; - //class bedrock - //@brief: bedrock is a fundamental core component, it provides a abstract to the OS platform - // and some basic functions. + + /// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions. class bedrock { bedrock(); diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 2915ec1c..112da9c6 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -1,4 +1,4 @@ -/* +/** * A Bedrock Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,7 +7,8 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/detail/win32/bedrock.cpp + * @file nana/gui/detail/win32/bedrock.cpp + * @brief A Bedrock Implementation * @contributors: Ariel Vina-Rodriguez */ @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -254,6 +256,7 @@ namespace detail { std::stringstream ss; ss<<"Nana.GUI detects a memory leaks in window_manager, "<(wd_manager().number_of_core_window())<<" window(s) are not uninstalled."; + std::cerr << ss.str(); /// \todo add list of cations of open windows and if aut testin GUI do auto Ok after 2 sec. ::MessageBoxA(0, ss.str().c_str(), ("Nana C++ Library"), MB_OK); } @@ -261,8 +264,8 @@ namespace detail delete pi_data_; } - //inc_window - //@brief: increament the number of windows + + /// @brief increament the number of windows in the thread id int bedrock::inc_window(unsigned tid) { //impl refers to the object of private_impl, the object is created when bedrock is creating. @@ -461,6 +464,7 @@ namespace detail { (msgbox(modal_window, "An exception during message pumping!").icon(msgbox::icon_information) <<"An uncaptured non-std exception during message pumping!" + << "\n in form: " << API::window_caption(modal_window) ).show(); internal_scope_guard lock; _m_except_handler(); From 2b5593a8aca387e726073c7a020a0c27ae951b61 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 11 Mar 2016 23:01:24 +0800 Subject: [PATCH 093/309] add a check for STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED --- include/nana/c++defines.hpp | 6 ++++-- include/nana/filesystem/filesystem.hpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 6d5df62b..86159f79 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -153,8 +153,10 @@ #endif #if defined(NANA_MINGW) - //It's a knonwn issue under MinGW - #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED + #ifndef __MINGW64_VERSION_MAJOR + //It's a knonwn issue under MinGW(except MinGW-W64) + #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED + #endif #endif #if (__GNUC_MINOR__ < 8) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index b7cb9cdc..2b44a60d 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -112,7 +112,7 @@ namespace nana { namespace experimental { namespace filesystem public: #if defined(NANA_WINDOWS) using value_type = wchar_t; - const static value_type preferred_separator = L'\\'; //? L'\\' ? + const static value_type preferred_separator = L'\\'; #else using value_type = char; const static value_type preferred_separator = '/'; From ea062959759d1167deb20034c8b6a7ecf50268b5 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 14 Mar 2016 14:29:16 +0800 Subject: [PATCH 094/309] minor changes --- source/gui/detail/bedrock_posix.cpp | 78 +++++++++++++-------------- source/gui/detail/bedrock_windows.cpp | 77 +++++++++++++------------- 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index a8f78c37..a7e20ee4 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -647,7 +647,8 @@ namespace detail static core_window_t* last_mouse_down_window; auto native_window = reinterpret_cast(event_window(xevent)); - auto root_runtime = brock.wd_manager().root_runtime(native_window); + auto & wd_manager = brock.wd_manager(); + auto root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) { @@ -667,7 +668,7 @@ namespace detail if(pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y); + msgwnd = wd_manager.find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y); if(msgwnd) { if (mouse_action::pressed != msgwnd->flags.action) @@ -681,7 +682,7 @@ namespace detail arg.evt_code = event_code::mouse_move; brock.emit(event_code::mouse_move, msgwnd, arg, true, &context); - if (!brock.wd_manager().available(hovered_wd)) + if (!wd_manager.available(hovered_wd)) hovered_wd = nullptr; } break; @@ -701,7 +702,7 @@ namespace detail arg.receiver = native_window; arg.getting = true; if(!brock.emit(event_code::focus, focus, arg, true, &context)) - brock.wd_manager().set_focus(msgwnd, true); + wd_manager.set_focus(msgwnd, true); } break; case FocusOut: @@ -727,7 +728,7 @@ namespace detail if(msgwnd->dimension.width != static_cast(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast(xevent.xconfigure.height)) { auto & cf = xevent.xconfigure; - brock.wd_manager().size(msgwnd, nana::size{static_cast(cf.width), static_cast(cf.height)}, true, true); + wd_manager.size(msgwnd, nana::size{static_cast(cf.width), static_cast(cf.height)}, true, true); } if(msgwnd->pos_native.x != xevent.xconfigure.x || msgwnd->pos_native.y != xevent.xconfigure.y) @@ -745,7 +746,7 @@ namespace detail if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5) break; - msgwnd = brock.wd_manager().find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); + msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); if(nullptr == msgwnd) break; if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) @@ -765,9 +766,9 @@ namespace detail if (new_focus && !new_focus->flags.ignore_mouse_focus) { context.event_window = new_focus; - auto kill_focus = brock.wd_manager().set_focus(new_focus, false); + auto kill_focus = wd_manager.set_focus(new_focus, false); if (kill_focus != new_focus) - brock.wd_manager().do_lazy_refresh(kill_focus, false); + wd_manager.do_lazy_refresh(kill_focus, false); } } @@ -781,7 +782,7 @@ namespace detail arg.evt_code = dbl_click ? event_code::dbl_click : event_code::mouse_down; if(brock.emit(arg.evt_code, msgwnd, arg, true, &context)) { - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) { pressed_wd = msgwnd; //If a root window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event. @@ -790,7 +791,7 @@ namespace detail //call the drawer mouse up event for restoring the surface graphics msgwnd->flags.action = mouse_action::normal; emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } } } @@ -821,7 +822,7 @@ namespace detail } else { - msgwnd = brock.wd_manager().find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); + msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); if(nullptr == msgwnd) break; @@ -852,7 +853,7 @@ namespace detail } //Do mouse_up, this handle may be closed by click handler. - if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled) + if(wd_manager.available(msgwnd) && msgwnd->flags.enabled) { if(hit) msgwnd->flags.action = mouse_action::over; @@ -866,7 +867,7 @@ namespace detail if(click_arg.window_handle) evt_ptr->click.emit(click_arg); - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) { arg.evt_code = event_code::mouse_up; evt_ptr->mouse_up.emit(arg); @@ -875,29 +876,27 @@ namespace detail else if(click_arg.window_handle) msgwnd->together.events_ptr->click.emit(click_arg); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } pressed_wd = nullptr; } break; case DestroyNotify: + if(wd_manager.available(msgwnd)) { - auto & spec = nana::detail::platform_spec::instance(); - if(brock.wd_manager().available(msgwnd)) + //The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window(). + if (msgwnd->root == brock.get_menu()) { - //The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window(). - if (msgwnd->root == brock.get_menu()) - { - brock.erase_menu(false); - brock.delay_restore(3); //Restores if delay_restore not decleared - } - - spec.remove(native_window); - brock.wd_manager().destroy(msgwnd); - - brock.manage_form_loader(msgwnd, false); - brock.wd_manager().destroy_handle(msgwnd); + brock.erase_menu(false); + brock.delay_restore(3); //Restores if delay_restore not decleared } + + auto & spec = ::nana::detail::platform_spec::instance(); + spec.remove(native_window); + wd_manager.destroy(msgwnd); + + brock.manage_form_loader(msgwnd, false); + wd_manager.destroy_handle(msgwnd); } break; case MotionNotify: @@ -915,8 +914,8 @@ namespace detail if(pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, xevent.xmotion.x, xevent.xmotion.y); - if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd)) + msgwnd = wd_manager.find_window(native_window, xevent.xmotion.x, xevent.xmotion.y); + if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd)) { brock.event_msleave(hovered_wd); hovered_wd->flags.action = mouse_action::normal; @@ -924,14 +923,14 @@ namespace detail //if msgwnd is neither a captured window nor a child of captured window, //redirect the msgwnd to the captured window. - auto cap_wd = brock.wd_manager().capture_redirect(msgwnd); + auto cap_wd = wd_manager.capture_redirect(msgwnd); if(cap_wd) msgwnd = cap_wd; } else if(msgwnd) { bool prev_captured_inside; - if(brock.wd_manager().capture_window_entered(xevent.xmotion.x, xevent.xmotion.y, prev_captured_inside)) + if(wd_manager.capture_window_entered(xevent.xmotion.x, xevent.xmotion.y, prev_captured_inside)) { event_code evt_code; if(prev_captured_inside) @@ -970,7 +969,7 @@ namespace detail arg.evt_code = event_code::mouse_move; brock.emit(event_code::mouse_move, msgwnd, arg, true, &context); } - if (!brock.wd_manager().available(hovered_wd)) + if (!wd_manager.available(hovered_wd)) hovered_wd = nullptr; break; case MapNotify: @@ -1035,7 +1034,6 @@ namespace detail keybuf[len] = 0; wchar_t os_code = 0; - auto & wd_manager = brock.wd_manager(); switch(status) { case XLookupKeySym: @@ -1116,7 +1114,7 @@ namespace detail brock.emit(event_code::key_press, msgwnd, arg, true, &context); - if(brock.wd_manager().available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd)) + if(wd_manager.available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd)) { int cmd = (menu_wd && (keyboard::escape == static_cast(arg.key)) ? 1 : 0 ); brock.delay_restore(cmd); @@ -1216,7 +1214,7 @@ namespace detail arg.window_handle = reinterpret_cast(msgwnd); emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } pressed_wd_space = nullptr; } @@ -1245,7 +1243,7 @@ namespace detail { bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); if (set_focus) - brock.wd_manager().set_focus(msgwnd, false); + wd_manager.set_focus(msgwnd, false); arg_keyboard arg; arg.evt_code = event_code::key_release; @@ -1284,7 +1282,7 @@ namespace detail } } - root_runtime = brock.wd_manager().root_runtime(native_window); + root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) { context.event_window = pre_event_window; @@ -1299,10 +1297,10 @@ namespace detail } auto thread_id = ::nana::system::this_thread_id(); - brock.wd_manager().call_safe_place(thread_id); + wd_manager.call_safe_place(thread_id); if(msgwnd) - brock.wd_manager().remove_trash_handle(thread_id); + wd_manager.remove_trash_handle(thread_id); } } diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 112da9c6..8f5a319e 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -791,7 +791,9 @@ namespace detail static restrict::TRACKMOUSEEVENT track = {sizeof track, 0x00000002}; auto native_window = reinterpret_cast(root_window); - auto* root_runtime = brock.wd_manager().root_runtime(native_window); + + auto & wd_manager = brock.wd_manager(); + auto* root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) { @@ -836,7 +838,7 @@ namespace detail bool take_over = false; auto mmi = reinterpret_cast(lParam); - if(msgwnd->min_track_size.width && msgwnd->min_track_size.height) + if(!msgwnd->min_track_size.empty()) { mmi->ptMinTrackSize.x = static_cast(msgwnd->min_track_size.width + msgwnd->extra_width); mmi->ptMinTrackSize.y = static_cast(msgwnd->min_track_size.height + msgwnd->extra_height); @@ -888,7 +890,7 @@ namespace detail arg_focus arg; assign_arg(arg, focus, native_window, true); if (!brock.emit(event_code::focus, focus, arg, true, &context)) - brock.wd_manager().set_focus(msgwnd, true); + wd_manager.set_focus(msgwnd, true); } def_window_proc = true; break; @@ -923,21 +925,21 @@ namespace detail break; pressed_wd = nullptr; - msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); + msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); if(msgwnd && msgwnd->flags.enabled) { if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus) { - auto killed = brock.wd_manager().set_focus(msgwnd, false); + auto killed = wd_manager.set_focus(msgwnd, false); if (killed != msgwnd) - brock.wd_manager().do_lazy_refresh(killed, false); + wd_manager.do_lazy_refresh(killed, false); } arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); if (brock.emit(arg.evt_code, msgwnd, arg, true, &context)) { - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) pressed_wd = msgwnd; } } @@ -951,7 +953,7 @@ namespace detail if (pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); + msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); if ((nullptr == msgwnd) || (pressed_wd && (msgwnd != pressed_wd))) break; @@ -970,9 +972,9 @@ namespace detail auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); if (new_focus && (!new_focus->flags.ignore_mouse_focus)) { - auto kill_focus = brock.wd_manager().set_focus(new_focus, false); + auto kill_focus = wd_manager.set_focus(new_focus, false); if (kill_focus != new_focus) - brock.wd_manager().do_lazy_refresh(kill_focus, false); + wd_manager.do_lazy_refresh(kill_focus, false); } } @@ -989,14 +991,14 @@ namespace detail auto pos = native_interface::cursor_position(); auto rootwd = native_interface::find_window(pos.x, pos.y); native_interface::calc_window_point(rootwd, pos); - if(msgwnd != brock.wd_manager().find_window(rootwd, pos.x, pos.y)) + if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y)) { //call the drawer mouse up event for restoring the surface graphics msgwnd->flags.action = mouse_action::normal; arg.evt_code = event_code::mouse_up; emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } } } @@ -1012,7 +1014,7 @@ namespace detail if (pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); + msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); if(nullptr == msgwnd) break; @@ -1041,7 +1043,7 @@ namespace detail } //Do mouse_up, this handle may be closed by click handler. - if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled) + if(wd_manager.available(msgwnd) && msgwnd->flags.enabled) { arg.evt_code = event_code::mouse_up; emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); @@ -1049,7 +1051,7 @@ namespace detail if (click_arg.window_handle) retain->click.emit(click_arg); - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) { arg.evt_code = event_code::mouse_up; retain->mouse_up.emit(arg); @@ -1058,7 +1060,7 @@ namespace detail else if (click_arg.window_handle) retain->click.emit(click_arg); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } pressed_wd = nullptr; break; @@ -1067,8 +1069,8 @@ namespace detail if (pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); - if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd)) + msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); + if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd)) { brock.event_msleave(hovered_wd); hovered_wd->flags.action = mouse_action::normal; @@ -1076,7 +1078,7 @@ namespace detail //if msgwnd is neither captured window nor the child of captured window, //redirect the msgwnd to the captured window. - auto wd = brock.wd_manager().capture_redirect(msgwnd); + auto wd = wd_manager.capture_redirect(msgwnd); if(wd) msgwnd = wd; } @@ -1084,7 +1086,7 @@ namespace detail else if(msgwnd) { bool prev_captured_inside; - if(brock.wd_manager().capture_window_entered(pmdec.mouse.x, pmdec.mouse.y, prev_captured_inside)) + if(wd_manager.capture_window_entered(pmdec.mouse.x, pmdec.mouse.y, prev_captured_inside)) { event_code evt_code; if(prev_captured_inside) @@ -1129,7 +1131,7 @@ namespace detail track.hwndTrack = native_window; restrict::track_mouse_event(&track); } - if (!brock.wd_manager().available(hovered_wd)) + if (!wd_manager.available(hovered_wd)) hovered_wd = nullptr; break; case WM_MOUSELEAVE: @@ -1145,7 +1147,7 @@ namespace detail if (pointer_wd == root_window) { ::ScreenToClient(pointer_wd, &scr_pos); - auto scrolled_wd = brock.wd_manager().find_window(reinterpret_cast(pointer_wd), scr_pos.x, scr_pos.y); + auto scrolled_wd = wd_manager.find_window(reinterpret_cast(pointer_wd), scr_pos.x, scr_pos.y); def_window_proc = true; auto evt_wd = scrolled_wd; @@ -1155,7 +1157,7 @@ namespace detail { def_window_proc = false; nana::point mspos{ scr_pos.x, scr_pos.y }; - brock.wd_manager().calc_window_point(evt_wd, mspos); + wd_manager.calc_window_point(evt_wd, mspos); arg_wheel arg; arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); @@ -1169,13 +1171,13 @@ namespace detail if (scrolled_wd && (nullptr == evt_wd)) { nana::point mspos{ scr_pos.x, scr_pos.y }; - brock.wd_manager().calc_window_point(scrolled_wd, mspos); + wd_manager.calc_window_point(scrolled_wd, mspos); arg_wheel arg; arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); assign_arg(arg, scrolled_wd, pmdec); brock.emit_drawer(event_code::mouse_wheel, scrolled_wd, arg, &context); - brock.wd_manager().do_lazy_refresh(scrolled_wd, false); + wd_manager.do_lazy_refresh(scrolled_wd, false); } } else @@ -1193,7 +1195,7 @@ namespace detail POINT pos; ::DragQueryPoint(drop, &pos); - msgwnd = brock.wd_manager().find_window(native_window, pos.x, pos.y); + msgwnd = wd_manager.find_window(native_window, pos.x, pos.y); if(msgwnd) { arg_dropfiles dropfiles; @@ -1224,11 +1226,11 @@ namespace detail dropfiles.pos.x = pos.x; dropfiles.pos.y = pos.y; - brock.wd_manager().calc_window_point(msgwnd, dropfiles.pos); + wd_manager.calc_window_point(msgwnd, dropfiles.pos); dropfiles.window_handle = reinterpret_cast(msgwnd); msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } } @@ -1316,7 +1318,7 @@ namespace detail break; case WM_SIZE: if(wParam != SIZE_MINIMIZED) - brock.wd_manager().size(msgwnd, size(pmdec.size.width, pmdec.size.height), true, true); + wd_manager.size(msgwnd, size(pmdec.size.width, pmdec.size.height), true, true); break; case WM_MOVE: brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam)); @@ -1342,7 +1344,7 @@ namespace detail case WM_SYSCHAR: def_window_proc = true; brock.set_keyboard_shortkey(true); - msgwnd = brock.wd_manager().find_shortkey(native_window, static_cast(wParam)); + msgwnd = wd_manager.find_shortkey(native_window, static_cast(wParam)); if(msgwnd) { arg_keyboard arg; @@ -1389,7 +1391,7 @@ namespace detail bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); if (set_focus) - brock.wd_manager().set_focus(msgwnd, false); + wd_manager.set_focus(msgwnd, false); arg_keyboard arg; arg.evt_code = event_code::key_release; @@ -1419,7 +1421,6 @@ namespace detail if(msgwnd) { - auto & wd_manager = brock.wd_manager(); if((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab { bool is_forward = (::GetKeyState(VK_SHIFT) >= 0); @@ -1496,10 +1497,10 @@ namespace detail arg.ignore = false; msgwnd->together.events_ptr->key_char.emit(arg); - if ((false == arg.ignore) && brock.wd_manager().available(msgwnd)) + if ((false == arg.ignore) && wd_manager.available(msgwnd)) brock.emit_drawer(event_code::key_char, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } } return 0; @@ -1532,7 +1533,7 @@ namespace detail arg.window_handle = reinterpret_cast(msgwnd); emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } pressed_wd_space = nullptr; } @@ -1577,12 +1578,12 @@ namespace detail brock.erase_menu(false); brock.delay_restore(3); //Restores if delay_restore not decleared } - brock.wd_manager().destroy(msgwnd); + wd_manager.destroy(msgwnd); nana::detail::platform_spec::instance().release_window_icon(msgwnd->root); break; case WM_NCDESTROY: brock.manage_form_loader(msgwnd, false); - brock.wd_manager().destroy_handle(msgwnd); + wd_manager.destroy_handle(msgwnd); if(--context.window_count <= 0) { @@ -1594,7 +1595,7 @@ namespace detail def_window_proc = true; } - root_runtime = brock.wd_manager().root_runtime(native_window); + root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) { root_runtime->condition.pressed = pressed_wd; From 8f995ee2cf9ec59f12906848f5276b32c0004cf6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 14 Mar 2016 23:20:24 +0800 Subject: [PATCH 095/309] fix an issue that child display incorrect --- include/nana/gui/detail/window_manager.hpp | 4 ++-- source/gui/detail/bedrock_posix.cpp | 10 +++++++--- source/gui/detail/bedrock_windows.cpp | 10 +++++++--- source/gui/detail/window_manager.cpp | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index b04c32dc..0b1f51c9 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -1,7 +1,7 @@ /* * Window Manager Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -129,7 +129,7 @@ namespace detail bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr); void refresh_tree(core_window_t*); - bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen); + bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen, bool refresh_tree = false); bool get_graphics(core_window_t*, nana::paint::graphics&); bool get_visual_rectangle(core_window_t*, nana::rectangle&); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index a7e20ee4..052a61aa 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -389,9 +389,13 @@ namespace detail _m_emit_core(evt_code, wd, false, arg); - if(ask_update) - wd_manager().do_lazy_refresh(wd, false); - else + //A child of wd may not be drawn if it was out of wd's range before wd resized, + //so refresh all children of wd when a resized occurs. + if(ask_update || (event_code::resized == evt_code)) + { + wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code)); + } + else if(wd_manager().available(wd)) wd->other.upd_state = core_window_t::update_state::none; if(thrd) thrd->event_window = prev_wd; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 8f5a319e..bf1b5c28 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -1779,8 +1779,12 @@ namespace detail _m_emit_core(evt_code, wd, false, arg); - if (ask_update) - wd_manager().do_lazy_refresh(wd, false); + //A child of wd may not be drawn if it was out of wd's range before wd resized, + //so refresh all children of wd when a resized occurs. + if (ask_update || (event_code::resized == evt_code)) + { + wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code)); + } else if (wd_manager().available(wd)) wd->other.upd_state = basic_window::update_state::none; @@ -1790,7 +1794,7 @@ namespace detail bool bedrock::emit_drawer(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, thread_context* thrd) { - if (bedrock_object.wd_manager().available(wd) == false) + if (wd_manager().available(wd) == false) return false; core_window_t* prev_event_wd; diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 4aa19757..6096d543 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -1,7 +1,7 @@ /* * Window Manager Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -833,7 +833,7 @@ namespace detail //do_lazy_refresh //@brief: defined a behavior of flush the screen //@return: it returns true if the wnd is available - bool window_manager::do_lazy_refresh(core_window_t* wd, bool force_copy_to_screen) + bool window_manager::do_lazy_refresh(core_window_t* wd, bool force_copy_to_screen, bool refresh_tree) { //Thread-Safe Required! std::lock_guard lock(mutex_); @@ -848,7 +848,7 @@ namespace detail { if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen) { - window_layer::paint(wd, false, false); + window_layer::paint(wd, false, refresh_tree); this->map(wd, force_copy_to_screen); } else if (effects::edge_nimbus::none != wd->effect.edge_nimbus) @@ -857,7 +857,7 @@ namespace detail } } else - window_layer::paint(wd, true, false); //only refreshing if it has an invisible parent + window_layer::paint(wd, true, refresh_tree); //only refreshing if it has an invisible parent } wd->other.upd_state = core_window_t::update_state::none; return true; From 6b6b5270078eda27a7f2a01660a38ff81575648c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 15 Mar 2016 15:46:28 +0800 Subject: [PATCH 096/309] eliminate -Wextra and -pedantic warnings --- include/nana/basic_types.hpp | 6 +- .../nana/detail/linux_X11/platform_spec.hpp | 5 + include/nana/gui/detail/general_events.hpp | 2 +- include/nana/gui/widgets/spinbox.hpp | 2 +- include/nana/gui/widgets/treebox.hpp | 4 +- include/nana/system/shared_wrapper.hpp | 2 +- include/nana/unicode_bidi.hpp | 2 +- source/datetime.cpp | 1 + source/detail/platform_spec_posix.cpp | 4 +- source/filesystem/filesystem.cpp | 1 + source/gui/detail/bedrock_posix.cpp | 10 +- source/gui/detail/native_window_interface.cpp | 14 ++ source/gui/detail/window_layout.cpp | 2 +- source/gui/element.cpp | 14 +- source/gui/msgbox.cpp | 4 +- source/gui/notifier.cpp | 8 + source/gui/place.cpp | 6 +- source/gui/programming_interface.cpp | 3 +- source/gui/screen.cpp | 2 + source/gui/tooltip.cpp | 2 +- source/gui/widgets/button.cpp | 2 +- source/gui/widgets/checkbox.cpp | 2 +- source/gui/widgets/combox.cpp | 8 +- source/gui/widgets/form.cpp | 2 +- source/gui/widgets/label.cpp | 2 +- source/gui/widgets/listbox.cpp | 232 +++++++++--------- source/gui/widgets/skeletons/text_editor.cpp | 10 +- source/gui/widgets/spinbox.cpp | 4 +- source/gui/widgets/tabbar.cpp | 6 +- source/gui/widgets/textbox.cpp | 4 +- source/gui/wvl.cpp | 8 +- source/paint/graphics.cpp | 6 +- source/paint/image.cpp | 12 +- source/paint/pixel_buffer.cpp | 2 +- source/system/dataexch.cpp | 42 ++-- source/system/platform.cpp | 1 + source/system/shared_wrapper.cpp | 2 +- source/unicode_bidi.cpp | 4 +- 38 files changed, 246 insertions(+), 197 deletions(-) diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index e990a681..4fb4385d 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -337,9 +337,9 @@ namespace nana bool operator==(const color& other) const; bool operator!=(const color& other) const; private: - double r_; - double g_; - double b_; + double r_{ 0.0 }; + double g_{ 0.0 }; + double b_{ 0.0 }; double a_{ 0.0 }; //invisible }; diff --git a/include/nana/detail/linux_X11/platform_spec.hpp b/include/nana/detail/linux_X11/platform_spec.hpp index c8866d9d..12bb65c3 100644 --- a/include/nana/detail/linux_X11/platform_spec.hpp +++ b/include/nana/detail/linux_X11/platform_spec.hpp @@ -60,6 +60,8 @@ namespace detail class charset_conv { + charset_conv(const charset_conv&) = delete; + charset_conv& operator=(const charset_conv*) = delete; public: charset_conv(const char* tocode, const char* fromcode); ~charset_conv(); @@ -118,6 +120,9 @@ namespace detail void update_color(); void update_text_color(); private: + drawable_impl_type(const drawable_impl_type&) = delete; + drawable_impl_type& operator=(const drawable_impl_type&) = delete; + unsigned current_color_{ 0xFFFFFF }; unsigned color_{ 0xFFFFFFFF }; unsigned text_color_{ 0xFFFFFFFF }; diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 29dae364..454b407f 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -429,7 +429,7 @@ namespace nana private: unsigned emitting_count_{ 0 }; bool deleted_flags_{ false }; - std::unique_ptr>> dockers_; + std::unique_ptr>> dockers_{ nullptr }; }; struct arg_mouse diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index e3d28505..fd60f070 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -68,7 +68,7 @@ namespace nana private: implementation * const impl_; }; - }; + } }//end namespace drawerbase /// Spinbox Widget diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp index f0cc4cd1..487812ea 100644 --- a/include/nana/gui/widgets/treebox.hpp +++ b/include/nana/gui/widgets/treebox.hpp @@ -307,14 +307,14 @@ namespace nana { _m_value() = t; return *this; - }; + } template item_proxy & value(T&& t) { _m_value() = std::move(t); return *this; - }; + } // Undocumentated methods for internal use trigger::node_type * _m_node() const; diff --git a/include/nana/system/shared_wrapper.hpp b/include/nana/system/shared_wrapper.hpp index b1737cc2..ab14997e 100644 --- a/include/nana/system/shared_wrapper.hpp +++ b/include/nana/system/shared_wrapper.hpp @@ -30,7 +30,7 @@ namespace system typedef void* module_t; void* symbols(module_t handle, const char* symbol); - }; //end struct shared_helper + } //end namespace shared_helper }//end namespace detail class shared_wrapper diff --git a/include/nana/unicode_bidi.hpp b/include/nana/unicode_bidi.hpp index acd2b057..766edf46 100644 --- a/include/nana/unicode_bidi.hpp +++ b/include/nana/unicode_bidi.hpp @@ -60,7 +60,7 @@ namespace nana void _m_resolve_weak_types(); void _m_resolve_neutral_types(); void _m_resolve_implicit_levels(); - void _m_reordering_resolved_levels(const char_type*, std::vector & reordered); + void _m_reordering_resolved_levels(std::vector & reordered); static bidi_category _m_bidi_category(bidi_char); static bidi_char _m_char_dir(char_type); private: diff --git a/source/datetime.cpp b/source/datetime.cpp index 4682c32c..849ec940 100644 --- a/source/datetime.cpp +++ b/source/datetime.cpp @@ -264,6 +264,7 @@ namespace nana } time::time() + : value_{} { struct tm t; localtime(t); diff --git a/source/detail/platform_spec_posix.cpp b/source/detail/platform_spec_posix.cpp index 9713a0c9..accaeed2 100644 --- a/source/detail/platform_spec_posix.cpp +++ b/source/detail/platform_spec_posix.cpp @@ -432,13 +432,13 @@ namespace detail platform_spec::instance().unlock_xlib(); } - int X11_error_handler(Display* disp, XErrorEvent* err) + int X11_error_handler(Display*, XErrorEvent* err) { platform_spec::instance().error_code = err->error_code; return 0; } - int X11_fatal_handler(Display* disp) + int X11_fatal_handler(Display*) { return 0; } diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index ead15a1a..69f467cf 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -813,6 +813,7 @@ namespace nana { namespace experimental { namespace filesystem bool remove(const path& p, std::error_code & ec) { + ec.clear(); auto stat = status(p); if (stat.type() == file_type::directory) return detail::rm_dir(p); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 052a61aa..a8fa2254 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -153,7 +153,7 @@ namespace detail delete impl_; } - void bedrock::map_thread_root_buffer(core_window_t*, bool forced, const rectangle*) + void bedrock::map_thread_root_buffer(core_window_t*, bool /*forced*/, const rectangle*) { //GUI in X11 is thread-independent, so no implementation. } @@ -366,7 +366,7 @@ namespace detail return impl_->estore; } - void bedrock::map_through_widgets(core_window_t* wd, native_drawable_type drawable) + void bedrock::map_through_widgets(core_window_t*, native_drawable_type) { //No implementation for Linux } @@ -523,7 +523,7 @@ namespace detail } } - void window_proc_for_packet(Display * display, nana::detail::msg_packet_tag& msg) + void window_proc_for_packet(Display * /*display*/, nana::detail::msg_packet_tag& msg) { static auto& brock = detail::bedrock::instance(); @@ -642,7 +642,7 @@ namespace detail return wchar_t(keysym); } - void window_proc_for_xevent(Display* display, XEvent& xevent) + void window_proc_for_xevent(Display* /*display*/, XEvent& xevent) { typedef detail::bedrock::core_window_t core_window_t; @@ -1308,7 +1308,7 @@ namespace detail } } - void bedrock::pump_event(window modal_window, bool is_modal) + void bedrock::pump_event(window modal_window, bool /*is_modal*/) { thread_context * context = open_thread_context(); if(0 == context->window_count) diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index ea84c1d3..258f3d1c 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -173,6 +173,8 @@ namespace nana{ mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top); } } +#else + static_cast(pos); //eliminate unused parameter compiler warning. #endif return rectangle{ primary_monitor_size() }; } @@ -547,6 +549,8 @@ namespace nana{ activate_window(reinterpret_cast( ::GetWindow(reinterpret_cast(wd), GW_OWNER) )); +#else + static_cast(wd); //eliminate unused parameter compiler warning. #endif } @@ -565,6 +569,8 @@ namespace nana{ else ::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0); } +#else + static_cast(wd); //eliminate unused parameter compiler warning. #endif } @@ -640,6 +646,7 @@ namespace nana{ ::XFlush(disp); } + static_cast(active); //eliminate unused parameter compiler warning. #endif } @@ -715,6 +722,7 @@ namespace nana{ #if defined(NANA_WINDOWS) ::InvalidateRect(reinterpret_cast(wd), nullptr, true); #elif defined(NANA_X11) + static_cast(wd); //eliminate unused parameter compiler warning. #endif } @@ -963,6 +971,7 @@ namespace nana{ ::SetWindowPos(native_wd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); ::AttachThreadInput(::GetCurrentThreadId(), fg_tid, FALSE); #else + static_cast(activated); //eliminate unused parameter compiler warning. set_window_z_order(wd, nullptr, z_order_action::top); #endif } @@ -1414,6 +1423,11 @@ namespace nana{ if(static_cast(y) > sz.height + ext_height) sz.height = static_cast(y); } +#else + //eliminate unused parameter compiler warning. + static_cast(ext_width); + static_cast(ext_height); + static_cast(true_for_max); #endif return sz; } diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index f44be0a6..d2556323 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -357,7 +357,7 @@ namespace nana //_m_notify_glasses //@brief: Notify the glass windows that are overlapped with the specified vis_rect - void window_layout::_m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& r_visual) + void window_layout::_m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& /*r_visual*/) { typedef category::flags cat_flags; diff --git a/source/gui/element.cpp b/source/gui/element.cpp index b2fdbb7f..e1f4b649 100644 --- a/source/gui/element.cpp +++ b/source/gui/element.cpp @@ -212,7 +212,7 @@ namespace nana class menu_crook : public crook_interface { - bool draw(graph_reference graph, const ::nana::color&, const ::nana::color& fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override + bool draw(graph_reference graph, const ::nana::color&, const ::nana::color& fgcolor, const nana::rectangle& r, element_state, const data& crook_data) override { if(crook_data.check_state == state::unchecked) return true; @@ -266,7 +266,7 @@ namespace nana class border_depressed : public border_interface { - bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, unsigned weight) + bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color&, const ::nana::rectangle& r, element_state estate, unsigned) { graph.rectangle(r, false, static_cast((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E)); graph.rectangle(::nana::rectangle(r).pare_off(1), false, bgcolor); @@ -277,7 +277,7 @@ namespace nana class arrow_solid_triangle : public arrow_interface { - bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, direction dir) override + bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, direction dir) override { ::nana::point pos{ r.x + 3, r.y + 3 }; switch (dir) @@ -318,7 +318,7 @@ namespace nana class arrow_hollow_triangle : public arrow_interface { - bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override + bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override { int x = r.x + 3; int y = r.y + 3; @@ -364,7 +364,7 @@ namespace nana class arrowhead : public arrow_interface { - bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override + bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override { int x = r.x; int y = r.y + 5; @@ -425,7 +425,7 @@ namespace nana class arrow_double : public arrow_interface { - bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override + bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override { int x = r.x; int y = r.y; @@ -486,7 +486,7 @@ namespace nana class annex_button : public element_interface { - bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color& fgcolor, const rectangle& r, element_state estate) override + bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color&, const rectangle& r, element_state estate) override { auto bgcolor = arg_bgcolor; diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index dd20cf6e..8d4914f6 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -702,7 +702,7 @@ namespace nana impl->spinbox.value(std::to_string(impl->value)); - 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&) { impl->label.size({ label_px, 24 }); impl->spinbox.size({ value_px, 24 }); @@ -780,7 +780,7 @@ namespace nana impl->spinbox.value(std::to_string(impl->value)); - 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&) { impl->label.size(::nana::size{ label_px, 24 }); impl->spinbox.size(::nana::size{ value_px, 24 }); diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 4e98e037..4a9f6ac3 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -314,6 +314,8 @@ namespace nana ::Shell_NotifyIcon(impl_->icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); impl_->icon_added = true; +#else + static_cast(str); //to eliminate unused parameter compiler warning. #endif } @@ -330,6 +332,8 @@ namespace nana impl_->set_icon(impl_->icon_handle); ::DestroyIcon(pre_icon); } +#else + static_cast(icon_file); //to eliminate unused parameter compiler warning #endif } @@ -338,6 +342,8 @@ namespace nana #if defined(NANA_WINDOWS) auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); impl_->icons.push_back(icon); +#else + static_cast(icon_file); //to eliminate unused parameter compiler warning. #endif } @@ -352,6 +358,8 @@ namespace nana } else impl_->ani_timer.stop(); +#else + static_cast(ms); //to eliminate unused parameter compiler warning. #endif } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index df89bbeb..1a0e5cb1 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -524,7 +524,7 @@ namespace nana //It will delete the element and recollocate when the window destroyed. event_handle _m_make_destroy(window wd) { - return API::events(wd).destroy.connect([this, wd](const arg_destroy& arg) + return API::events(wd).destroy.connect([this, wd](const arg_destroy&) { for (auto i = elements.begin(), end = elements.end(); i != end; ++i) { @@ -1127,7 +1127,7 @@ namespace nana } } - void collocate(window wd) override + void collocate(window) override { if (!field || !(visible && display)) return; @@ -1563,7 +1563,7 @@ namespace nana } } - void collocate(window wd) override + void collocate(window) override { if (!dockable_field) { diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 12670941..e36e1a36 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -104,8 +104,7 @@ namespace API { if (iwd->effect.edge_nimbus == effects::edge_nimbus::none) { - basic_window::edge_nimbus_action ena = { iwd }; - cont.push_back(ena); + cont.push_back(basic_window::edge_nimbus_action{ iwd, false}); } iwd->effect.edge_nimbus = static_cast(static_cast(en) | static_cast(iwd->effect.edge_nimbus)); } diff --git a/source/gui/screen.cpp b/source/gui/screen.cpp index 1a0be98b..da390bda 100644 --- a/source/gui/screen.cpp +++ b/source/gui/screen.cpp @@ -167,6 +167,8 @@ namespace nana } } } +#else + static_cast(pos); //to eliminate unused parameter compiler warning. #endif return get_primary(); } diff --git a/source/gui/tooltip.cpp b/source/gui/tooltip.cpp index ac76b7d6..433c247b 100644 --- a/source/gui/tooltip.cpp +++ b/source/gui/tooltip.cpp @@ -227,7 +227,7 @@ namespace nana window_->tooltip_move(API::cursor_position(), true); } - void show_duration(window wd, point pos, const std::string& text, std::size_t duration) + void show_duration(window /*wd*/, point pos, const std::string& text, std::size_t duration) { if (nullptr == window_ || window_->tooltip_empty()) { diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index 301c07c7..f1541cfa 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -163,7 +163,7 @@ namespace nana{ namespace drawerbase _m_press(graph, false); } - void trigger::key_press(graph_reference graph, const arg_keyboard& arg) + void trigger::key_press(graph_reference, const arg_keyboard& arg) { bool ch_tabstop_next; switch(arg.key) diff --git a/source/gui/widgets/checkbox.cpp b/source/gui/widgets/checkbox.cpp index 4a14a7fc..c535378c 100644 --- a/source/gui/widgets/checkbox.cpp +++ b/source/gui/widgets/checkbox.cpp @@ -216,7 +216,7 @@ namespace nana{ namespace drawerbase uiobj.check(false); uiobj.react(false); - element_tag el = {}; + element_tag el; el.uiobj = &uiobj; diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index c5df35f8..a4631668 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -615,7 +615,7 @@ namespace nana } } - void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) + void trigger::mouse_down(graph_reference, const arg_mouse& arg) { //drawer_->set_mouse_press(true); drawer_->set_button_state(element_state::pressed, false); @@ -633,7 +633,7 @@ namespace nana } } - void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) + void trigger::mouse_up(graph_reference, const arg_mouse& arg) { if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister()) { @@ -660,7 +660,7 @@ namespace nana } } - void trigger::mouse_wheel(graph_reference graph, const arg_wheel& arg) + void trigger::mouse_wheel(graph_reference, const arg_wheel& arg) { if(drawer_->widget_ptr()->enabled()) { @@ -718,7 +718,7 @@ namespace nana API::lazy_refresh(); } - void trigger::key_char(graph_reference graph, const arg_keyboard& arg) + void trigger::key_char(graph_reference, const arg_keyboard& arg) { if (drawer_->editor()->respond_char(arg)) API::lazy_refresh(); diff --git a/source/gui/widgets/form.cpp b/source/gui/widgets/form.cpp index eab587ad..af43ea37 100644 --- a/source/gui/widgets/form.cpp +++ b/source/gui/widgets/form.cpp @@ -18,7 +18,7 @@ namespace nana namespace form { //class trigger - void trigger::attached(widget_reference wdg, graph_reference graph) + void trigger::attached(widget_reference wdg, graph_reference) { wd_ = &wdg; API::ignore_mouse_focus(wdg, true); diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index ed6c2828..d500eed9 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -437,7 +437,7 @@ namespace nana return total_w; } - bool _m_each_line(graph_reference graph, dstream::linecontainer& line, render_status& rs) + bool _m_each_line(graph_reference graph, dstream::linecontainer&, render_status& rs) { std::wstring text; iterator block_start; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3e214531..56eff953 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2614,15 +2614,15 @@ namespace nana return list_str ; } - void es_lister::categ_selected(size_type cat, bool sel) + void es_lister::categ_selected(size_type cat, bool sel) { - cat_proxy cpx{ess_,cat}; - for (item_proxy &it : cpx ) - { - if (it.selected() != sel) + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) + { + if (it.selected() != sel) it.select(sel); - } - last_selected_abs = last_selected_dpl = index_pair{cat, npos}; + } + last_selected_abs = last_selected_dpl = index_pair{cat, npos}; } class drawer_header_impl @@ -3549,15 +3549,16 @@ namespace nana } } - void trigger::dbl_click(graph_reference graph, const arg_mouse& arg) + void trigger::dbl_click(graph_reference graph, const arg_mouse&) { if (essence_->pointer_where.first == essence_t::parts::header) if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) - { - if (essence(). auto_width(drawer_header_->item_spliter() )) // ? in order - essence().update(); - return; - } + { + //adjust the width of column to its content. + if (essence_->auto_width(drawer_header_->item_spliter() )) + essence_->update(); + return; + } if (essence_->pointer_where.first != essence_t::parts::lister) return; @@ -3571,24 +3572,25 @@ namespace nana if (!item_pos.is_category()) //being the npos of item.second is a category return; - arg_category ai(cat_proxy(essence_, item_pos.cat)); - lister.wd_ptr()->events().category_dbl_click.emit(ai); + arg_category ai(cat_proxy(essence_, item_pos.cat)); + lister.wd_ptr()->events().category_dbl_click.emit(ai); - if(!ai.category_change_blocked()){ - bool do_expand = (lister.expand(item_pos.cat) == false); - lister.expand(item_pos.cat, do_expand); + if(!ai.category_change_blocked()) + { + bool do_expand = (lister.expand(item_pos.cat) == false); + lister.expand(item_pos.cat, do_expand); - if(false == do_expand) - { - auto last = lister.last(); - size_type n = essence_->number_of_lister_items(false); - if (lister.backward(last, n, last)) - offset_y = last; - } - essence_->adjust_scroll_life(); - refresh(graph); - API::lazy_refresh(); - } + if(false == do_expand) + { + auto last = lister.last(); + size_type n = essence_->number_of_lister_items(false); + if (lister.backward(last, n, last)) + offset_y = last; + } + essence_->adjust_scroll_life(); + refresh(graph); + API::lazy_refresh(); + } } } @@ -3603,8 +3605,8 @@ namespace nana { bool up = false; - if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) - return ; + if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) + return ; switch(arg.key) { @@ -3622,49 +3624,46 @@ namespace nana } break; - case keyboard::os_pageup : + case keyboard::os_pageup : up = true; - case keyboard::os_pagedown: - { - auto& scrl = essence_->scroll.v; - if (! scrl.make_page_scroll(!up)) - return; - essence_->lister.select_for_all(false); + case keyboard::os_pagedown: + { + auto& scrl = essence_->scroll.v; + if (! scrl.make_page_scroll(!up)) + return; + essence_->lister.select_for_all(false); - index_pair idx{essence_->scroll_y_dpl()}; - if (!up) - essence_->lister.forward(idx, scrl.range()-1, idx); + index_pair idx{essence_->scroll_y_dpl()}; + if (!up) + essence_->lister.forward(idx, scrl.range()-1, idx); - if (idx.is_item()) - item_proxy::from_display(essence_, idx).select(true); - else - if(!essence_->lister.single_selection()) + if (idx.is_item()) + item_proxy::from_display(essence_, idx).select(true); + else if(!essence_->lister.single_selection()) essence_->lister.categ_selected(idx.cat, true); - essence_->trace_last_selected_item (); + essence_->trace_last_selected_item (); - break; - } - case keyboard::os_home: - { - essence_->lister.select_for_all(false); + break; + } + case keyboard::os_home: + { + essence_->lister.select_for_all(false); - index_pair frst{essence_->lister.first()}; - if (frst.is_item()) - item_proxy::from_display(essence_, frst).select(true); - else - if(!essence_->lister.single_selection()) + index_pair frst{essence_->lister.first()}; + if (frst.is_item()) + item_proxy::from_display(essence_, frst).select(true); + else if(!essence_->lister.single_selection()) essence_->lister.categ_selected(frst.cat, true); - essence_->trace_last_selected_item (); - break; - } - case keyboard::os_end: - essence_->lister.select_for_all(false); - item_proxy::from_display(essence_, essence_->lister.last()).select(true); - essence_->trace_last_selected_item (); - break; - + essence_->trace_last_selected_item (); + break; + } + case keyboard::os_end: + essence_->lister.select_for_all(false); + item_proxy::from_display(essence_, essence_->lister.last()).select(true); + essence_->trace_last_selected_item (); + break; default: return; } @@ -3676,20 +3675,19 @@ namespace nana { switch(arg.key) { - case keyboard::copy: - { - export_options exp_opt {essence_->def_exp_options}; - exp_opt.columns_order = essence_->header.all_headers(true); - exp_opt.only_selected_items = true; - ::nana::system::dataexch().set(essence_->to_string(exp_opt)); - return; - } - case keyboard::select_all : - essence_->lister.select_for_all(true); + case keyboard::copy: + { + export_options exp_opt {essence_->def_exp_options}; + exp_opt.columns_order = essence_->header.all_headers(true); + exp_opt.only_selected_items = true; + ::nana::system::dataexch().set(essence_->to_string(exp_opt)); + return; + } + case keyboard::select_all : + essence_->lister.select_for_all(true); refresh(graph); - API::lazy_refresh(); - break; - + API::lazy_refresh(); + break; default: return; } @@ -3713,23 +3711,24 @@ namespace nana } } - /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() - item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative) - { - return item_proxy{ess, ess->lister.absolute_pair(relative)}; - } - item_proxy item_proxy::from_display(const index_pair &relative) const - { - return item_proxy{ess_, ess_->lister.absolute_pair(relative)}; - } + /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() + item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative) + { + return item_proxy{ess, ess->lister.absolute_pair(relative)}; + } - /// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort() - index_pair item_proxy::to_display() const - { - return ess_->lister.relative_pair(pos_); - } + item_proxy item_proxy::from_display(const index_pair &relative) const + { + return item_proxy{ess_, ess_->lister.absolute_pair(relative)}; + } - bool item_proxy::empty() const + /// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort() + index_pair item_proxy::to_display() const + { + return ess_->lister.relative_pair(pos_); + } + + bool item_proxy::empty() const { return !ess_; } @@ -3752,14 +3751,14 @@ namespace nana return cat_->items.at(pos_.item).flags.checked; } - /// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected - item_proxy & item_proxy::select(bool s) + /// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected + item_proxy & item_proxy::select(bool s) { auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat? if(m.flags.selected == s) return *this; // ignore if no change m.flags.selected = s; // actually change selection - arg_listbox arg{*this, s}; + arg_listbox arg{*this, s}; ess_->lister.wd_ptr()->events().selected.emit(arg); if (m.flags.selected) @@ -4394,7 +4393,7 @@ namespace nana } unsigned listbox::auto_width(size_type pos, unsigned max) { - auto & ess = _m_ess(); + auto & ess = _m_ess(); unsigned max_w = ess.auto_width(pos, max); ess.update(); return max_w; @@ -4480,34 +4479,33 @@ namespace nana return *this; } - listbox::item_proxy listbox::at(const index_pair& pos_abs) const + listbox::item_proxy listbox::at(const index_pair& pos_abs) const { return at(pos_abs.cat).at(pos_abs.item); } // Contributed by leobackes(pr#97) - listbox::index_pair listbox::at ( const point& pos ) const - { - auto & ess=_m_ess(); - auto _where=ess.where(pos.x, pos.y); - index_pair item_pos{npos,npos}; - if(_where.first==drawerbase::listbox::essence_t::parts::lister){ - auto & offset_y = ess.scroll.offset_y_dpl; - ess.lister.forward(offset_y, _where.second, item_pos); - } - return item_pos; - } + listbox::index_pair listbox::at ( const point& pos ) const + { + auto & ess=_m_ess(); + auto _where=ess.where(pos.x, pos.y); + index_pair item_pos{npos,npos}; + if(_where.first==drawerbase::listbox::essence_t::parts::lister) + { + auto & offset_y = ess.scroll.offset_y_dpl; + ess.lister.forward(offset_y, _where.second, item_pos); + } + return item_pos; + } //Contributed by leobackes(pr#97) - listbox::columns_indexs listbox::column_from_pos ( const point& pos ) - { - auto & ess=_m_ess(); - columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); - return col; - } - - + listbox::columns_indexs listbox::column_from_pos ( const point& pos ) + { + auto & ess=_m_ess(); + columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); + return col; + } void listbox::insert(const index_pair& pos, std::string text) { diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index fc6086cc..79731abf 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -53,7 +53,7 @@ namespace nana{ namespace widgets return cmd_; } - virtual bool merge(const undoable_command_interface& rhs) override + virtual bool merge(const undoable_command_interface&) override { return false; } @@ -273,8 +273,8 @@ namespace nana{ namespace widgets : editor_(editor) {} - void merge_lines(std::size_t first, std::size_t second) override{} - void add_lines(std::size_t pos, std::size_t lines) override{} + void merge_lines(std::size_t, std::size_t) override{} + void add_lines(std::size_t, std::size_t) override{} void pre_calc_line(std::size_t, unsigned) override{} void pre_calc_lines(unsigned) override{} @@ -283,12 +283,12 @@ namespace nana{ namespace widgets return editor_.textbase_.lines(); } - std::size_t take_lines(std::size_t pos) const override + std::size_t take_lines(std::size_t) const override { return 1; } - void update_line(std::size_t textline, std::size_t secondary_before) override + void update_line(std::size_t textline, std::size_t) override { int top = editor_._m_text_top_base() + static_cast(editor_.line_height() * (textline - editor_.points_.offset.y)); editor_.graph_.rectangle({ editor_.text_area_.area.x, top, editor_.text_area_.area.width, editor_.line_height() }, true, API::bgcolor(editor_.window_)); diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 880fa7f1..da0a8bd0 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -518,7 +518,7 @@ namespace nana impl_->render(); } - void drawer::focus(graph_reference, const arg_focus& arg) + void drawer::focus(graph_reference, const arg_focus&) { impl_->reset_text(); impl_->render(); @@ -578,7 +578,7 @@ namespace nana } } - void drawer::resized(graph_reference graph, const arg_resized& arg) + void drawer::resized(graph_reference, const arg_resized&) { impl_->reset_text_area(); impl_->render(); diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index 8aa7037e..9e1c05e0 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -43,7 +43,7 @@ namespace nana : public item_renderer { private: - virtual void background(graph_reference graph, const nana::rectangle& r, const ::nana::color& bgcolor) + virtual void background(graph_reference graph, const nana::rectangle&, const ::nana::color& bgcolor) { if(bgcolor_ != bgcolor) { @@ -59,7 +59,6 @@ namespace nana virtual void item(graph_reference graph, const item_t& m, bool active, state_t sta) { - //* const nana::rectangle & r = m.r; color bgcolor; color blcolor; @@ -961,7 +960,8 @@ namespace nana auto bgcolor = API::bgcolor(basis_.wd); auto fgcolor = API::fgcolor(basis_.wd); - item_renderer::item_t m{ ::nana::rectangle{ basis_.graph->size() } }; + item_renderer::item_t m; + m.r = ::nana::rectangle{ basis_.graph->size() }; basis_.renderer->background(*basis_.graph, m.r, bgcolor); diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index a4d4d499..8fedd8eb 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -88,7 +88,7 @@ namespace drawerbase { editor_ = nullptr; } - void drawer::refresh(graph_reference graph) + void drawer::refresh(graph_reference) { editor_->render(API::is_focus_ready(*widget_)); } @@ -121,7 +121,7 @@ namespace drawerbase { API::lazy_refresh(); } - void drawer::mouse_up(graph_reference graph, const arg_mouse& arg) + void drawer::mouse_up(graph_reference, const arg_mouse& arg) { if(editor_->mouse_pressed(arg)) API::lazy_refresh(); diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 1b475c80..6877ef41 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -82,8 +82,12 @@ namespace nana if (t.joinable()) t.join(); - #else - pump(); + #else + static_cast(wait); + static_cast(wait_end); + static_cast(f); //to eliminte unused parameter compiler warning. + + pump(); #endif } }//end namespace nana diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 07153126..57d8138f 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -867,7 +867,7 @@ namespace paint ::DeleteObject(hBmp); ::DeleteDC(hdcMem); #elif defined(NANA_X11) - + static_cast(file_utf8); //eliminate unused parameter compil warning. #endif } } @@ -1201,6 +1201,10 @@ namespace paint if(solid) rectangle(::nana::rectangle(r).pare_off(1), true, solid_clr); } + + //eliminate unused parameter compiler warning. + static_cast(radius_x); + static_cast(radius_y); #endif } } diff --git a/source/paint/image.cpp b/source/paint/image.cpp index f14de479..3d23e3f5 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -73,7 +73,8 @@ namespace paint return true; } #else - if(is_ico_){} //kill the unused compiler warning in Linux. + static_cast(is_ico_); //eliminate the unused compiler warning in Linux. + static_cast(file); //to eliminate the unused parameter compiler warning. #endif return false; } @@ -98,7 +99,9 @@ namespace paint } } #else - if(is_ico_){} //kill the unused compiler warning in Linux. + static_cast(is_ico_); //kill the unused compiler warning in Linux. + static_cast(data); //to eliminate unused parameter compiler warning. + static_cast(bytes); #endif return false; } @@ -129,6 +132,9 @@ namespace paint { #if defined(NANA_WINDOWS) ::DrawIconEx(graph.handle()->context, p_dst.x, p_dst.y, *ptr_, src_r.width, src_r.height, 0, 0, DI_NORMAL); +#else + static_cast(src_r); //eliminate unused parameter compiler warning. + static_cast(p_dst); #endif } } @@ -139,6 +145,8 @@ namespace paint { #if defined(NANA_WINDOWS) ::DrawIconEx(graph.handle()->context, r.x, r.y, *ptr_, r.width, r.height, 0, 0, DI_NORMAL); +#else + static_cast(r); //eliminate unused parameter compiler warning. #endif } } diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index c3330c8d..574c8951 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -977,7 +977,7 @@ namespace nana{ namespace paint } } - void pixel_buffer::gradual_rectangle(const ::nana::rectangle& draw_rct, const ::nana::color& from, const ::nana::color& to, double fade_rate, bool vertical) + void pixel_buffer::gradual_rectangle(const ::nana::rectangle& draw_rct, const ::nana::color& from, const ::nana::color& to, double /*fade_rate*/, bool vertical) { auto sp = storage_.get(); if (nullptr == sp) return; diff --git a/source/system/dataexch.cpp b/source/system/dataexch.cpp index 992a76d3..d229dea0 100644 --- a/source/system/dataexch.cpp +++ b/source/system/dataexch.cpp @@ -82,31 +82,35 @@ namespace nana{ namespace system{ // Bitmaps are huge, so to avoid unnegligible extra copy, this routine does not use private _m_set method. HGLOBAL h_gmem = ::GlobalAlloc(GHND | GMEM_SHARE, header_size + bitmap_bytes); void * gmem = ::GlobalLock(h_gmem); - if (gmem) { - char* p = (char*)gmem; - // Fix BITMAPINFOHEADER obtained from GetDIBits WinAPI - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biHeight = ::abs(bmi.bmiHeader.biHeight); - memcpy(p, &bmi, header_size); - p += header_size; - // many programs do not support bottom-up DIB, so reversing row order is needed. - for (int y=0; y(g); //eliminate unused parameter compiler warning. throw "not implemented yet."; return false; #endif diff --git a/source/system/platform.cpp b/source/system/platform.cpp index 042c5892..092c53e5 100644 --- a/source/system/platform.cpp +++ b/source/system/platform.cpp @@ -93,6 +93,7 @@ namespace system return (::GetAsyncKeyState(button) != 0); #elif defined(NANA_LINUX) || defined(NANA_MACOS) + static_cast(button); //eliminate unused parameter compiler warning. return false; #endif } diff --git a/source/system/shared_wrapper.cpp b/source/system/shared_wrapper.cpp index dce6d621..124f2822 100644 --- a/source/system/shared_wrapper.cpp +++ b/source/system/shared_wrapper.cpp @@ -54,7 +54,7 @@ namespace system ::FreeLibrary(reinterpret_cast(handle)); #endif } - }; //end struct shared_helper + } //end namespace shared_helper }//end namespace detail diff --git a/source/unicode_bidi.cpp b/source/unicode_bidi.cpp index 5ef940ec..f92bd5ee 100644 --- a/source/unicode_bidi.cpp +++ b/source/unicode_bidi.cpp @@ -584,7 +584,7 @@ namespace nana _m_resolve_weak_types(); _m_resolve_neutral_types(); _m_resolve_implicit_levels(); - _m_reordering_resolved_levels(str, reordered); + _m_reordering_resolved_levels(reordered); } unsigned unicode_bidi::_m_paragraph_level(const char_type * begin, const char_type * end) @@ -885,7 +885,7 @@ namespace nana } } - void unicode_bidi::_m_reordering_resolved_levels(const char_type * str, std::vector & reordered) + void unicode_bidi::_m_reordering_resolved_levels(std::vector & reordered) { reordered = levels_; From a559b2d8cc10d2b99f4589aef215a281f35addb8 Mon Sep 17 00:00:00 2001 From: Pr0curo Date: Wed, 16 Mar 2016 09:04:20 +0100 Subject: [PATCH 097/309] include as std::memcpy is defined in header, it is added (see http://en.cppreference.com/w/cpp/string/byte/memcpy) --- source/system/dataexch.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/system/dataexch.cpp b/source/system/dataexch.cpp index d229dea0..cb8ecb97 100644 --- a/source/system/dataexch.cpp +++ b/source/system/dataexch.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #if defined(NANA_WINDOWS) #include From bb53c4c1ecfb422201e20a22ed4e0228ea264347 Mon Sep 17 00:00:00 2001 From: Pr0curo Date: Wed, 16 Mar 2016 09:16:55 +0100 Subject: [PATCH 098/309] correct workaround for missing thread support the Workaround from MeganZ (I suppose you refere to this one: https://github.com/meganz/mingw-std-threads) hast some flaws: is not available, is not available and EPROTO is already defined (but with 53 instead of 71) --- CMakeLists.txt | 1 + include/nana/std_mutex.hpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b622422..46315d96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ if(WIN32) if(MINGW) if(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + add_definitions(-DSTD_THREAD_NOT_SUPPORTED) add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(MINGW) diff --git a/include/nana/std_mutex.hpp b/include/nana/std_mutex.hpp index b508548e..38c07aaf 100644 --- a/include/nana/std_mutex.hpp +++ b/include/nana/std_mutex.hpp @@ -8,12 +8,12 @@ #include #include #include -#include -#include +//#include +//#include #include #include // http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno.h#L53 -#define EPROTO 71 /* Protocol error */ +//#define EPROTO 71 /* Protocol error */ #include #include #else From 6540142e29e489b03fc1571167dcce2875e86fe0 Mon Sep 17 00:00:00 2001 From: Pr0curo Date: Wed, 16 Mar 2016 09:24:22 +0100 Subject: [PATCH 099/309] change includes using the right includes to avoid the mess with the missing threading library support of mingw --- source/gui/wvl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 6877ef41..8942fb17 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -13,8 +13,9 @@ #include #include -#include +#include #include +#include //#define NANA_AUTOMATIC_GUI_TESTING namespace nana From 238e298bc420f3704790e1a41d6d5b262b12082c Mon Sep 17 00:00:00 2001 From: Pr0curo Date: Wed, 16 Mar 2016 09:34:16 +0100 Subject: [PATCH 100/309] add include --- include/nana/std_thread.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/nana/std_thread.hpp b/include/nana/std_thread.hpp index f3cf4bc0..e1df7ef7 100644 --- a/include/nana/std_thread.hpp +++ b/include/nana/std_thread.hpp @@ -5,6 +5,7 @@ #if defined(STD_THREAD_NOT_SUPPORTED) #if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + #include #else #include @@ -13,5 +14,11 @@ namespace std typedef boost::thread thread; } #endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + +#else + +#include + #endif // (STD_THREAD_NOT_SUPPORTED) + #endif // NANA_STD_THREAD_HPP From 8ec21827a09cd00eeab0afeca8beb20de50bde96 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 18 Mar 2016 22:17:13 +0800 Subject: [PATCH 101/309] ignore warnings which are generated by -Weffc++ --- include/nana/audio/player.hpp | 7 +- include/nana/basic_types.hpp | 3 +- include/nana/c++defines.hpp | 6 +- include/nana/deploy.hpp | 5 +- .../nana/detail/linux_X11/platform_spec.hpp | 9 ++- include/nana/detail/win32/platform_spec.hpp | 3 + include/nana/filesystem/filesystem.hpp | 4 ++ include/nana/gui/animation.hpp | 3 +- include/nana/gui/basis.hpp | 10 ++- include/nana/gui/detail/basic_window.hpp | 2 + include/nana/gui/detail/bedrock.hpp | 3 + include/nana/gui/detail/bedrock_pi_data.hpp | 5 ++ include/nana/gui/detail/drawer.hpp | 3 + include/nana/gui/detail/element_store.hpp | 5 ++ include/nana/gui/detail/general_events.hpp | 4 ++ include/nana/gui/detail/handle_manager.hpp | 4 ++ .../nana/gui/detail/inner_fwd_implement.hpp | 4 ++ include/nana/gui/detail/window_layout.hpp | 3 + include/nana/gui/detail/window_manager.hpp | 5 ++ include/nana/gui/dragger.hpp | 2 + include/nana/gui/drawing.hpp | 4 ++ include/nana/gui/element.hpp | 2 + include/nana/gui/msgbox.hpp | 2 + include/nana/gui/notifier.hpp | 2 + include/nana/gui/place.hpp | 2 + include/nana/gui/timer.hpp | 2 + include/nana/gui/widgets/button.hpp | 4 ++ include/nana/gui/widgets/categorize.hpp | 5 +- include/nana/gui/widgets/checkbox.hpp | 3 + include/nana/gui/widgets/combox.hpp | 2 + include/nana/gui/widgets/date_chooser.hpp | 3 +- include/nana/gui/widgets/detail/tree_cont.hpp | 3 + include/nana/gui/widgets/float_listbox.hpp | 2 + include/nana/gui/widgets/label.hpp | 5 +- include/nana/gui/widgets/listbox.hpp | 4 ++ include/nana/gui/widgets/menu.hpp | 4 ++ include/nana/gui/widgets/menubar.hpp | 3 + include/nana/gui/widgets/picture.hpp | 4 ++ include/nana/gui/widgets/scroll.hpp | 2 + .../gui/widgets/skeletons/text_editor.hpp | 4 ++ .../widgets/skeletons/text_token_stream.hpp | 3 + .../nana/gui/widgets/skeletons/textbase.hpp | 3 + include/nana/gui/widgets/slider.hpp | 4 ++ include/nana/gui/widgets/spinbox.hpp | 4 +- include/nana/gui/widgets/tabbar.hpp | 3 + include/nana/gui/widgets/textbox.hpp | 4 ++ include/nana/gui/widgets/toolbar.hpp | 3 + include/nana/gui/widgets/treebox.hpp | 4 ++ include/nana/gui/widgets/widget.hpp | 4 ++ include/nana/gui/wvl.hpp | 1 - include/nana/pat/cloneable.hpp | 10 ++- include/nana/pop_ignore_diagnostic | 5 ++ include/nana/push_ignore_diagnostic | 4 ++ include/nana/unicode_bidi.hpp | 3 + source/audio/player.cpp | 5 +- source/charset.cpp | 22 +++--- source/datetime.cpp | 68 ++++++++----------- source/detail/platform_spec_posix.cpp | 5 ++ source/gui/detail/basic_window.cpp | 18 ++--- source/gui/detail/window_layout.cpp | 16 ++--- source/gui/detail/window_manager.cpp | 35 +++++----- source/gui/place.cpp | 13 +++- source/internationalization.cpp | 4 ++ .../paint/detail/image_process_provider.cpp | 1 + source/paint/image.cpp | 2 +- source/paint/image_process_selector.cpp | 1 + 66 files changed, 288 insertions(+), 109 deletions(-) create mode 100644 include/nana/pop_ignore_diagnostic create mode 100644 include/nana/push_ignore_diagnostic diff --git a/include/nana/audio/player.hpp b/include/nana/audio/player.hpp index c4fc3d87..0dad445f 100644 --- a/include/nana/audio/player.hpp +++ b/include/nana/audio/player.hpp @@ -1,6 +1,6 @@ #ifndef NANA_AUDIO_PLAYER_HPP #define NANA_AUDIO_PLAYER_HPP - +#include #include #ifdef NANA_ENABLE_AUDIO @@ -31,4 +31,7 @@ namespace nana{ namespace audio }//end namespace nana #endif //NANA_ENABLE_AUDIO -#endif \ No newline at end of file + +#include + +#endif diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index 4fb4385d..4d13b6ec 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -15,6 +15,7 @@ #include #include +#include namespace nana { @@ -484,7 +485,7 @@ namespace nana southeast }; }//end namespace nana - +#include #endif diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 86159f79..2dc4c5f2 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -137,11 +137,11 @@ #if ((__GNUC__ < 5) ) # define STD_put_time_NOT_SUPPORTED - #endif + #endif - #if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) + #if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) # undef STD_FILESYSTEM_NOT_SUPPORTED - #endif + #endif #if (__GNUC__ == 4) #if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 069545cb..7fb89c5f 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -14,6 +14,7 @@ #ifndef NANA_DEPLOY_HPP #define NANA_DEPLOY_HPP +#include #include #if defined(VERBOSE_PREPROCESSOR) @@ -209,5 +210,5 @@ namespace std { make_unique(Args&&...) = delete; } #endif //STD_make_unique_NOT_SUPPORTED - -#endif //NANA_MACROS_HPP +#include +#endif //NANA_DEPLOY_HPP diff --git a/include/nana/detail/linux_X11/platform_spec.hpp b/include/nana/detail/linux_X11/platform_spec.hpp index 12bb65c3..e701c203 100644 --- a/include/nana/detail/linux_X11/platform_spec.hpp +++ b/include/nana/detail/linux_X11/platform_spec.hpp @@ -18,6 +18,8 @@ #ifndef NANA_DETAIL_PLATFORM_SPEC_HPP #define NANA_DETAIL_PLATFORM_SPEC_HPP +#include + #include #include #include @@ -193,8 +195,8 @@ namespace detail native_window_type owner; std::vector * owned; }; - public: - int error_code; + public: + int error_code; public: typedef drawable_impl_type::font_ptr_t font_ptr_t; typedef void (*timer_proc_type)(unsigned tid); @@ -202,6 +204,8 @@ namespace detail typedef ::nana::event_code event_code; typedef ::nana::native_window_type native_window_type; + platform_spec(const platform_spec&) = delete; + platform_spec& operator=(const platform_spec&) = delete; platform_spec(); ~platform_spec(); @@ -332,6 +336,7 @@ namespace detail }//end namespace nana +#include // .h ward #endif diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index dc6329fe..dba6062a 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -142,6 +142,9 @@ namespace detail unsigned whitespace_pixels; }string; + drawable_impl_type(const drawable_impl_type&) = delete; + drawable_impl_type& operator=(const drawable_impl_type&) = delete; + drawable_impl_type(); ~drawable_impl_type(); diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 2b44a60d..a62a5707 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -29,6 +29,9 @@ #ifndef NANA_FILESYSTEM_HPP #define NANA_FILESYSTEM_HPP + +#include + #include #include #include @@ -409,4 +412,5 @@ namespace nana { namespace experimental { namespace filesystem //namespace filesystem = experimental::filesystem; } //end namespace nana +#include #endif diff --git a/include/nana/gui/animation.hpp b/include/nana/gui/animation.hpp index d9a62e26..9f0df563 100644 --- a/include/nana/gui/animation.hpp +++ b/include/nana/gui/animation.hpp @@ -12,7 +12,7 @@ #ifndef NANA_GUI_ANIMATION_HPP #define NANA_GUI_ANIMATION_HPP - +#include #include #include @@ -82,4 +82,5 @@ namespace nana impl * impl_; }; } //end namespace nana +#include #endif //NANA_GUI_ANIMATION_HPP diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index 55518554..37fd7f69 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -15,6 +15,8 @@ #ifndef NANA_GUI_BASIS_HPP #define NANA_GUI_BASIS_HPP +#include + #include "../basic_types.hpp" #include "../traits.hpp" //metacomp::fixed_type_set @@ -59,9 +61,9 @@ namespace nana }; //wait for constexpr struct widget_tag{ static const flags value = flags::widget; }; - struct lite_widget_tag : widget_tag{ static const flags value = flags::lite_widget;}; - struct root_tag : widget_tag{ static const flags value = flags::root; }; - struct frame_tag: widget_tag{ static const flags value = flags::frame; }; + struct lite_widget_tag : public widget_tag{ static const flags value = flags::lite_widget; }; + struct root_tag : public widget_tag{ static const flags value = flags::root; }; + struct frame_tag : public widget_tag{ static const flags value = flags::frame; }; }// end namespace category using native_window_type = detail::native_window_handle_impl*; @@ -258,4 +260,6 @@ that return a corresponding nana::appearance with predefined values. }; };//end namespace apper }//end namespace nana + +#include #endif diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index ed2e1db4..e2e68fe1 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP #define NANA_GUI_DETAIL_BASIC_WINDOW_HPP +#include #include "drawer.hpp" #include "events_holder.hpp" #include "widget_colors.hpp" @@ -237,5 +238,6 @@ namespace detail }//end namespace detail }//end namespace nana +#include #endif diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 128ce532..a88e0642 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -33,6 +33,9 @@ namespace detail class bedrock { bedrock(); + + bedrock(const bedrock&) = delete; + bedrock& operator=(const bedrock&) = delete; public: using core_window_t = basic_window; diff --git a/include/nana/gui/detail/bedrock_pi_data.hpp b/include/nana/gui/detail/bedrock_pi_data.hpp index 3154a6b3..4e9e28c8 100644 --- a/include/nana/gui/detail/bedrock_pi_data.hpp +++ b/include/nana/gui/detail/bedrock_pi_data.hpp @@ -1,6 +1,8 @@ #ifndef NANA_DETAIL_BEDROCK_PI_DATA_HPP #define NANA_DETAIL_BEDROCK_PI_DATA_HPP +#include + #include #include "color_schemes.hpp" #include "events_operation.hpp" @@ -20,4 +22,7 @@ namespace nana }; } } + +#include + #endif diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index b680ec6a..26061033 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -13,6 +13,7 @@ #ifndef NANA_GUI_DETAIL_DRAWER_HPP #define NANA_GUI_DETAIL_DRAWER_HPP +#include #include #include "general_events.hpp" #include @@ -170,4 +171,6 @@ namespace nana }//end namespace detail }//end namespace nana +#include + #endif diff --git a/include/nana/gui/detail/element_store.hpp b/include/nana/gui/detail/element_store.hpp index 0035d4be..3ac5b242 100644 --- a/include/nana/gui/detail/element_store.hpp +++ b/include/nana/gui/detail/element_store.hpp @@ -15,9 +15,13 @@ #include #include + #include #include +#include + + namespace nana { namespace detail @@ -48,5 +52,6 @@ namespace detail }; }//end namespace detail } +#include #endif diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 454b407f..f7c9bc54 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -12,6 +12,8 @@ #ifndef NANA_DETAIL_GENERAL_EVENTS_HPP #define NANA_DETAIL_GENERAL_EVENTS_HPP +#include + #include #include "event_code.hpp" #include "internal_scope_guard.hpp" @@ -576,4 +578,6 @@ namespace nana }//end namespace detail }//end namespace nana +#include + #endif diff --git a/include/nana/gui/detail/handle_manager.hpp b/include/nana/gui/detail/handle_manager.hpp index 7e8f670d..716433be 100644 --- a/include/nana/gui/detail/handle_manager.hpp +++ b/include/nana/gui/detail/handle_manager.hpp @@ -25,6 +25,8 @@ #include #include +#include + namespace nana { @@ -288,4 +290,6 @@ namespace nana };//end class handle_manager }//end namespace detail }// end namespace nana +#include + #endif diff --git a/include/nana/gui/detail/inner_fwd_implement.hpp b/include/nana/gui/detail/inner_fwd_implement.hpp index 90589d3c..dd88b9e2 100644 --- a/include/nana/gui/detail/inner_fwd_implement.hpp +++ b/include/nana/gui/detail/inner_fwd_implement.hpp @@ -14,6 +14,7 @@ #ifndef NANA_GUI_INNER_FWD_IMPLEMENT_HPP #define NANA_GUI_INNER_FWD_IMPLEMENT_HPP +#include #include "inner_fwd.hpp" #include "basic_window.hpp" #include "../../paint/graphics.hpp" @@ -172,4 +173,7 @@ namespace nana{ }; } }//end namespace nana + +#include + #endif //NANA_GUI_INNER_FWD_IMPLEMENT_HPP diff --git a/include/nana/gui/detail/window_layout.hpp b/include/nana/gui/detail/window_layout.hpp index f4bdfe0b..34987291 100644 --- a/include/nana/gui/detail/window_layout.hpp +++ b/include/nana/gui/detail/window_layout.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP #define NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP +#include #include #include @@ -84,5 +85,7 @@ namespace detail }//end namespace detail }//end namespace nana +#include + #endif //NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index 0b1f51c9..9a1302a2 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -18,6 +18,8 @@ #ifndef NANA_GUI_DETAIL_WINDOW_MANAGER_HPP #define NANA_GUI_DETAIL_WINDOW_MANAGER_HPP +#include + #include #include "window_layout.hpp" #include "event_code.hpp" @@ -195,4 +197,7 @@ namespace detail };//end class window_manager }//end namespace detail }//end namespace nana + +#include + #endif diff --git a/include/nana/gui/dragger.hpp b/include/nana/gui/dragger.hpp index e34094ef..9e6bbbf2 100644 --- a/include/nana/gui/dragger.hpp +++ b/include/nana/gui/dragger.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_DRAGGER_HPP #define NANA_GUI_DRAGGER_HPP +#include #include "basis.hpp" #include "../basic_types.hpp" #include "../traits.hpp" @@ -44,4 +45,5 @@ namespace nana dragger_impl_t * impl_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/drawing.hpp b/include/nana/gui/drawing.hpp index fb1b966b..06ecece6 100644 --- a/include/nana/gui/drawing.hpp +++ b/include/nana/gui/drawing.hpp @@ -11,6 +11,8 @@ */ #ifndef NANA_GUI_DRAWING_HPP #define NANA_GUI_DRAWING_HPP + +#include #include "widgets/widget.hpp" #include "../traits.hpp" namespace nana @@ -46,4 +48,6 @@ namespace nana window handle_; };//end class drawing }//end namespace nana + +#include #endif diff --git a/include/nana/gui/element.hpp b/include/nana/gui/element.hpp index 599aa87a..93379052 100644 --- a/include/nana/gui/element.hpp +++ b/include/nana/gui/element.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_ELEMENT_HPP #define NANA_GUI_ELEMENT_HPP +#include #include #include #include @@ -349,4 +350,5 @@ namespace nana }//end namespace element }//end namespace nana +#include #endif //NANA_GUI_ELEMENT_HPP diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index af5a1437..e21392e0 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_MSGBOX_HPP #define NANA_GUI_MSGBOX_HPP +#include #include @@ -253,5 +254,6 @@ namespace nana ::nana::rectangle valid_areas_[4]; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/notifier.hpp b/include/nana/gui/notifier.hpp index a557fd45..48442a96 100644 --- a/include/nana/gui/notifier.hpp +++ b/include/nana/gui/notifier.hpp @@ -14,6 +14,7 @@ #define NANA_GUI_NOTIFIER_HPP #include #include +#include namespace nana { @@ -65,4 +66,5 @@ namespace nana implement * impl_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/place.hpp b/include/nana/gui/place.hpp index 8f32545b..b10a8a18 100644 --- a/include/nana/gui/place.hpp +++ b/include/nana/gui/place.hpp @@ -15,6 +15,7 @@ #ifndef NANA_GUI_PLACE_HPP #define NANA_GUI_PLACE_HPP +#include #include #include #include @@ -145,5 +146,6 @@ namespace nana implement * impl_; }; }//end namespace nana +#include #endif //#ifndef NANA_GUI_PLACE_HPP diff --git a/include/nana/gui/timer.hpp b/include/nana/gui/timer.hpp index 893a4e5d..9ae26f32 100644 --- a/include/nana/gui/timer.hpp +++ b/include/nana/gui/timer.hpp @@ -16,6 +16,7 @@ #ifndef NANA_GUI_TIMER_HPP #define NANA_GUI_TIMER_HPP #include +#include namespace nana { @@ -58,4 +59,5 @@ namespace nana implement * const impl_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/button.hpp b/include/nana/gui/widgets/button.hpp index bddeca77..e1813917 100644 --- a/include/nana/gui/widgets/button.hpp +++ b/include/nana/gui/widgets/button.hpp @@ -14,6 +14,8 @@ #define NANA_GUI_WIDGET_BUTTON_HPP #include "widget.hpp" #include +#include + namespace nana{ namespace drawerbase @@ -105,5 +107,7 @@ namespace nana{ void _m_caption(native_string_type&&) override; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/categorize.hpp b/include/nana/gui/widgets/categorize.hpp index 3b8f5b3c..3f211c81 100644 --- a/include/nana/gui/widgets/categorize.hpp +++ b/include/nana/gui/widgets/categorize.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace nana { @@ -141,7 +142,7 @@ namespace nana void mouse_leave(graph_reference, const arg_mouse&) override; private: std::unique_ptr event_agent_; - scheme * scheme_; + scheme * scheme_{nullptr}; }; }//end namespace categorize }//end namespace drawerbase @@ -258,5 +259,5 @@ namespace nana } }; }//end namespace nana - +#include #endif diff --git a/include/nana/gui/widgets/checkbox.hpp b/include/nana/gui/widgets/checkbox.hpp index 8d458be3..8d06b590 100644 --- a/include/nana/gui/widgets/checkbox.hpp +++ b/include/nana/gui/widgets/checkbox.hpp @@ -12,6 +12,8 @@ #ifndef NANA_GUI_WIDGET_CHECKBOX_HPP #define NANA_GUI_WIDGET_CHECKBOX_HPP +#include + #include "widget.hpp" #include #include @@ -106,5 +108,6 @@ namespace drawerbase std::vector ui_container_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/combox.hpp b/include/nana/gui/widgets/combox.hpp index 4d22a30e..7e478557 100644 --- a/include/nana/gui/widgets/combox.hpp +++ b/include/nana/gui/widgets/combox.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGETS_COMBOX_HPP #define NANA_GUI_WIDGETS_COMBOX_HPP +#include #include "widget.hpp" #include "float_listbox.hpp" #include "skeletons/text_editor_part.hpp" @@ -227,4 +228,5 @@ namespace nana nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override; }; } +#include #endif diff --git a/include/nana/gui/widgets/date_chooser.hpp b/include/nana/gui/widgets/date_chooser.hpp index a4e685e1..4d02324b 100644 --- a/include/nana/gui/widgets/date_chooser.hpp +++ b/include/nana/gui/widgets/date_chooser.hpp @@ -12,7 +12,7 @@ #ifndef NANA_GUI_WIDGETS_DATE_CHOOSER_HPP #define NANA_GUI_WIDGETS_DATE_CHOOSER_HPP - +#include #include "widget.hpp" #include @@ -114,5 +114,6 @@ namespace nana void weekstr(unsigned index, const ::std::string&);/// #endif diff --git a/include/nana/gui/widgets/detail/tree_cont.hpp b/include/nana/gui/widgets/detail/tree_cont.hpp index 3618b814..c9684ba6 100644 --- a/include/nana/gui/widgets/detail/tree_cont.hpp +++ b/include/nana/gui/widgets/detail/tree_cont.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP #define NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP #include +#include namespace nana { @@ -515,4 +516,6 @@ namespace detail }//end namespace detail }//end namespace widgets }//end namesace nana + +#include #endif diff --git a/include/nana/gui/widgets/float_listbox.hpp b/include/nana/gui/widgets/float_listbox.hpp index 79a66e2f..590479fd 100644 --- a/include/nana/gui/widgets/float_listbox.hpp +++ b/include/nana/gui/widgets/float_listbox.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP #define NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP +#include #include "widget.hpp" #include @@ -101,5 +102,6 @@ namespace nana std::size_t index() const; }; } +#include #endif diff --git a/include/nana/gui/widgets/label.hpp b/include/nana/gui/widgets/label.hpp index 6b71bd88..f8c97eb9 100644 --- a/include/nana/gui/widgets/label.hpp +++ b/include/nana/gui/widgets/label.hpp @@ -12,8 +12,9 @@ #ifndef NANA_GUI_WIDGET_LABEL_HPP #define NANA_GUI_WIDGET_LABEL_HPP -#include "widget.hpp" +#include "widget.hpp" +#include namespace nana { @@ -80,4 +81,6 @@ namespace nana void _m_caption(native_string_type&&) override; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 42ac9123..373d54ad 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -17,6 +17,8 @@ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP +#include + #include "widget.hpp" #include "detail/inline_widget.hpp" #include @@ -709,4 +711,6 @@ By \a clicking on one header the list get \a reordered, first up, and then down void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana + +#include #endif diff --git a/include/nana/gui/widgets/menu.hpp b/include/nana/gui/widgets/menu.hpp index 335796d4..02372079 100644 --- a/include/nana/gui/widgets/menu.hpp +++ b/include/nana/gui/widgets/menu.hpp @@ -17,6 +17,8 @@ #include #include +#include + namespace nana { namespace drawerbase @@ -198,4 +200,6 @@ namespace nana detail::popuper menu_popuper(menu&, mouse = mouse::right_button); detail::popuper menu_popuper(menu&, window owner, const point&, mouse = mouse::right_button); }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/menubar.hpp b/include/nana/gui/widgets/menubar.hpp index 365d9b1c..3c799936 100644 --- a/include/nana/gui/widgets/menubar.hpp +++ b/include/nana/gui/widgets/menubar.hpp @@ -14,6 +14,7 @@ #define NANA_GUI_WIDGETS_MENUBAR_HPP #include "widget.hpp" #include "menu.hpp" +#include namespace nana { @@ -117,4 +118,6 @@ namespace nana ::nana::event_handle evt_resized_{nullptr}; };//end class menubar }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/picture.hpp b/include/nana/gui/widgets/picture.hpp index bd40f0e0..fc8e9c63 100644 --- a/include/nana/gui/widgets/picture.hpp +++ b/include/nana/gui/widgets/picture.hpp @@ -13,6 +13,8 @@ */ #ifndef NANA_GUI_WIDGET_PICTURE_HPP #define NANA_GUI_WIDGET_PICTURE_HPP +#include + #include "widget.hpp" namespace nana @@ -67,4 +69,6 @@ namespace nana bool transparent() const; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 96d1b023..458ce877 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -15,6 +15,7 @@ #include "widget.hpp" #include +#include namespace nana { @@ -502,4 +503,5 @@ namespace nana } };//end class scroll }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 3189cd18..46a023fd 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -13,6 +13,8 @@ #ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP #define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP +#include + #include "textbase.hpp" #include "text_editor_part.hpp" #include @@ -372,5 +374,7 @@ namespace nana{ namespace widgets }//end namespace widgets }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index 7fbd3801..c5d5a5e7 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -22,6 +22,8 @@ #include #include +#include + namespace nana{ namespace widgets{ namespace skeletons { //The tokens are defined for representing a text, the tokens are divided @@ -941,4 +943,5 @@ namespace nana{ namespace widgets{ namespace skeletons }//end namespace skeletons }//end namespace widgets }//end namepsace nana +#include #endif //NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM diff --git a/include/nana/gui/widgets/skeletons/textbase.hpp b/include/nana/gui/widgets/skeletons/textbase.hpp index 99cc5799..1c4085b2 100644 --- a/include/nana/gui/widgets/skeletons/textbase.hpp +++ b/include/nana/gui/widgets/skeletons/textbase.hpp @@ -13,6 +13,7 @@ #ifndef NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP #define NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP +#include #include #include @@ -536,4 +537,6 @@ namespace skeletons }//end namespace detail }//end namespace widgets }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/slider.hpp b/include/nana/gui/widgets/slider.hpp index c5372034..21b92d47 100644 --- a/include/nana/gui/widgets/slider.hpp +++ b/include/nana/gui/widgets/slider.hpp @@ -11,6 +11,9 @@ */ #ifndef NANA_GUI_WIDGETS_SLIDER_HPP #define NANA_GUI_WIDGETS_SLIDER_HPP + +#include + #include "widget.hpp" #include @@ -141,5 +144,6 @@ namespace nana bool transparent() const; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index fd60f070..e090426a 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -12,6 +12,8 @@ #ifndef NANA_GUI_WIDGET_SPINBOX_HPP #define NANA_GUI_WIDGET_SPINBOX_HPP + +#include #include "widget.hpp" #include "skeletons/text_editor_part.hpp" @@ -110,5 +112,5 @@ namespace nana void _m_caption(native_string_type&&); }; //end class spinbox }//end namespace nana - +#include #endif //NANA_GUI_WIDGET_SPINBOX_HPP diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index b7a88789..c7d20ad1 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -13,6 +13,8 @@ */ #ifndef NANA_GUI_WIDGET_TABBAR_HPP #define NANA_GUI_WIDGET_TABBAR_HPP +#include + #include "widget.hpp" #include #include @@ -410,5 +412,6 @@ namespace nana void erase(std::size_t pos, bool close_attached = true); }; } +#include #endif diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 69fda830..4ce43a3d 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -11,6 +11,8 @@ */ #ifndef NANA_GUI_WIDGET_TEXTBOX_HPP #define NANA_GUI_WIDGET_TEXTBOX_HPP +#include + #include #include "skeletons/textbase_export_interface.hpp" #include "skeletons/text_editor_part.hpp" @@ -214,4 +216,6 @@ namespace nana void _m_typeface(const paint::font&) override; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/toolbar.hpp b/include/nana/gui/widgets/toolbar.hpp index 8a4d3a40..24f27b32 100644 --- a/include/nana/gui/widgets/toolbar.hpp +++ b/include/nana/gui/widgets/toolbar.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGET_TOOLBAR_HPP #define NANA_GUI_WIDGET_TOOLBAR_HPP +#include #include "widget.hpp" @@ -101,4 +102,6 @@ namespace nana bool detached_; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp index 487812ea..69477824 100644 --- a/include/nana/gui/widgets/treebox.hpp +++ b/include/nana/gui/widgets/treebox.hpp @@ -17,6 +17,8 @@ #ifndef NANA_GUI_WIDGETS_TREEBOX_HPP #define NANA_GUI_WIDGETS_TREEBOX_HPP + +#include #include "widget.hpp" #include "detail/compset.hpp" #include "detail/tree_cont.hpp" @@ -452,4 +454,6 @@ namespace nana item_proxy selected() const; ///< returns the selected node };//end class treebox }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 1fdb48fa..5caa7510 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -12,6 +12,8 @@ #ifndef NANA_GUI_WIDGET_HPP #define NANA_GUI_WIDGET_HPP + +#include #include "../basis.hpp" #include "../programming_interface.hpp" #include @@ -524,4 +526,6 @@ namespace nana std::unique_ptr scheme_; };//end class widget_object }//end namespace nana + +#include #endif diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index 4da60f25..0500a6a0 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -15,7 +15,6 @@ #ifndef NANA_GUI_WVL_HPP #define NANA_GUI_WVL_HPP - #include "programming_interface.hpp" #include "screen.hpp" #include "widgets/form.hpp" diff --git a/include/nana/pat/cloneable.hpp b/include/nana/pat/cloneable.hpp index cf3d9d81..7cff2638 100644 --- a/include/nana/pat/cloneable.hpp +++ b/include/nana/pat/cloneable.hpp @@ -13,6 +13,7 @@ #ifndef NANA_PAT_CLONEABLE_HPP #define NANA_PAT_CLONEABLE_HPP +#include #include #include #include @@ -96,10 +97,15 @@ namespace nana{ namespace pat{ typedef int inner_bool::* operator_bool_t; + /* template - struct member_enabled + struct member_enabled //deprecated : public std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int> {}; + */ + + template + using member_enabled = std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int>; public: cloneable() noexcept = default; @@ -207,5 +213,5 @@ namespace nana{ namespace pat{ using mutable_cloneable = cloneable; }//end namespace pat }//end namespace nana - +#include #endif diff --git a/include/nana/pop_ignore_diagnostic b/include/nana/pop_ignore_diagnostic new file mode 100644 index 00000000..23c39a69 --- /dev/null +++ b/include/nana/pop_ignore_diagnostic @@ -0,0 +1,5 @@ + +#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6) +# pragma GCC diagnostic pop +#endif + diff --git a/include/nana/push_ignore_diagnostic b/include/nana/push_ignore_diagnostic new file mode 100644 index 00000000..9ba463ad --- /dev/null +++ b/include/nana/push_ignore_diagnostic @@ -0,0 +1,4 @@ +#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Weffc++" +#endif diff --git a/include/nana/unicode_bidi.hpp b/include/nana/unicode_bidi.hpp index 766edf46..71a5f882 100644 --- a/include/nana/unicode_bidi.hpp +++ b/include/nana/unicode_bidi.hpp @@ -1,6 +1,8 @@ #ifndef NANA_UNICODE_BIDI_HPP #define NANA_UNICODE_BIDI_HPP #include +#include + namespace nana { @@ -71,5 +73,6 @@ namespace nana }; } +#include #endif diff --git a/source/audio/player.cpp b/source/audio/player.cpp index e86f1798..5ede06a4 100644 --- a/source/audio/player.cpp +++ b/source/audio/player.cpp @@ -1,5 +1,8 @@ + +#include #include + #ifdef NANA_ENABLE_AUDIO #include @@ -67,4 +70,4 @@ namespace nana{ namespace audio }//end namespace audio }//end namespace nana -#endif //NANA_ENABLE_AUDIO \ No newline at end of file +#endif //NANA_ENABLE_AUDIO diff --git a/source/charset.cpp b/source/charset.cpp index ddf7207f..686f8182 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -344,11 +344,11 @@ namespace nana { public: charset_string(const std::string& s) - : data_(s), is_unicode_(false) + : data_(s) {} charset_string(std::string&& s) - : data_(std::move(s)), is_unicode_(false) + : data_(std::move(s)) {} charset_string(const std::string& s, unicode encoding) @@ -501,9 +501,9 @@ namespace nana } private: std::string data_; - std::wstring wdata_for_move_; - bool is_unicode_; - unicode utf_x_; + std::wstring wdata_for_move_{}; + bool is_unicode_{ false }; + unicode utf_x_{ unicode::utf8 }; }; class charset_wstring @@ -950,11 +950,11 @@ namespace nana { public: charset_string(const std::string& s) - : data_(s), is_unicode_(false) + : data_(s) {} charset_string(std::string&& s) - : data_(std::move(s)), is_unicode_(false) + : data_(std::move(s)) {} charset_string(const std::string& s, unicode encoding) @@ -1122,9 +1122,9 @@ namespace nana } private: std::string data_; - std::wstring wdata_for_move_; - bool is_unicode_; - unicode utf_x_; + std::wstring wdata_for_move_{}; + bool is_unicode_{ false }; + unicode utf_x_{ unicode::utf8 }; }; @@ -1195,7 +1195,7 @@ namespace nana } private: std::wstring data_; - std::string data_for_move_; + std::string data_for_move_{}; }; #endif } diff --git a/source/datetime.cpp b/source/datetime.cpp index 849ec940..21cfe962 100644 --- a/source/datetime.cpp +++ b/source/datetime.cpp @@ -17,62 +17,65 @@ #include namespace { - void localtime(struct tm& tm) + std::tm localtime() { #if defined(NANA_WINDOWS) && !defined(NANA_MINGW) time_t t; ::time(&t); + std::tm tm; if(localtime_s(&tm, &t) != 0) - { assert(false); - } + + return tm; #else time_t t = std::time(nullptr); struct tm * tm_addr = std::localtime(&t); assert(tm_addr); - tm = *tm_addr; + + return *tm_addr; #endif } + + ::nana::date::value to_dateval(const std::tm& t) + { + return {static_cast(t.tm_year + 1900), static_cast(t.tm_mon + 1), static_cast(t.tm_mday)}; + } + + ::nana::time::value to_timeval(const std::tm& t) + { + return {static_cast(t.tm_hour), static_cast(t.tm_min), static_cast(t.tm_sec)}; + } + } // namespace anonymous namespace nana { - //class date + //class date void date::set(const std::tm& t) { - value_.year = t.tm_year + 1900; - value_.month = t.tm_mon + 1; - value_.day = t.tm_mday; + value_ = to_dateval(t); } date::date() + : value_(to_dateval(*std::localtime(nullptr))) { - struct tm t; - localtime(t); - set(t); } date::date(const std::tm& t) + : value_(to_dateval(t)) { - set(t); } date::date(int year, int month, int day) + : value_({static_cast(year), static_cast(month), static_cast(day)}) { if(1601 <= year && year < 30827 && 0 < month && month < 13 && day > 0) { if(day <= static_cast(date::month_days(year, month))) - { - value_.year = year; - value_.month = month; - value_.day = day; return; - } } - struct tm t; - localtime(t); - set(t); + set(localtime()); } date date::operator - (int off) const @@ -258,40 +261,27 @@ namespace nana //class time void time::set(const std::tm& t) { - value_.hour = t.tm_hour; - value_.minute = t.tm_min; - value_.second = t.tm_sec; + value_ = to_timeval(t); } time::time() - : value_{} + : value_(to_timeval(localtime())) { - struct tm t; - localtime(t); - set(t); } time::time(const std::tm& t) + : value_(to_timeval(t)) { - value_.hour = t.tm_hour; - value_.minute = t.tm_min; - value_.second = t.tm_sec; } time::time(unsigned hour, unsigned minute, unsigned second) + : value_({hour, minute, second}) { if(hour < 24 && minute < 60 && second < 62) - { - value_.hour = hour; - value_.minute = minute; - value_.second = second; return; - } - struct tm t; - localtime(t); - set(t); - } + set(localtime()); + } const time::value& time::read() const { return value_; diff --git a/source/detail/platform_spec_posix.cpp b/source/detail/platform_spec_posix.cpp index accaeed2..a2121991 100644 --- a/source/detail/platform_spec_posix.cpp +++ b/source/detail/platform_spec_posix.cpp @@ -16,6 +16,9 @@ #include #if defined(NANA_POSIX) && defined(NANA_X11) + +#include + #include #include #include @@ -1414,4 +1417,6 @@ namespace detail } }//end namespace detail }//end namespace nana + +#include #endif //NANA_POSIX && NANA_X11 diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 9c1a5ae0..693a9bf7 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -207,10 +207,10 @@ namespace nana { switch(categ) { - case category::root_tag::value: + case category::flags::root: attribute.root = new attr_root_tag; break; - case category::frame_tag::value: + case category::flags::frame: attribute.frame = new attr_frame_tag; break; default: @@ -222,10 +222,10 @@ namespace nana { switch(category) { - case category::root_tag::value: + case category::flags::root: delete attribute.root; break; - case category::frame_tag::value: + case category::flags::frame: delete attribute.frame; break; default: break; @@ -236,7 +236,7 @@ namespace nana //basic_window //@brief: constructor for the root window basic_window::basic_window(basic_window* owner, std::unique_ptr&& wdg_notifier, category::root_tag**) - : widget_notifier(std::move(wdg_notifier)), other(category::root_tag::value) + : widget_notifier(std::move(wdg_notifier)), other(category::flags::root) { drawer.bind(this); _m_init_pos_and_size(nullptr, rectangle()); @@ -256,7 +256,7 @@ namespace nana //@brief: bind a native window and baisc_window void basic_window::bind_native_window(native_window_type wd, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, nana::paint::graphics& graphics) { - if(category::root_tag::value == this->other.category) + if(category::flags::root == this->other.category) { this->root = wd; dimension.width = width; @@ -270,7 +270,7 @@ namespace nana void basic_window::frame_window(native_window_type wd) { - if(category::frame_tag::value == this->other.category) + if(category::flags::frame == this->other.category) other.attribute.frame->container = wd; } @@ -357,12 +357,12 @@ namespace nana void basic_window::_m_initialize(basic_window* agrparent) { - if(other.category == category::root_tag::value) + if(category::flags::root == other.category) { if(agrparent && (nana::system::this_thread_id() != agrparent->thread_id)) agrparent = nullptr; - while(agrparent && (agrparent->other.category != category::root_tag::value)) + while(agrparent && (category::flags::root != agrparent->other.category)) agrparent = agrparent->parent; owner = agrparent; diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index d2556323..10a94e4d 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -53,7 +53,7 @@ namespace nana //get the root graphics auto& graph = *(wd->root_graph); - if (wd->other.category != category::lite_widget_tag::value) + if (category::flags::lite_widget != wd->other.category) graph.bitblt(vr, wd->drawer.graphics, nana::point(vr.x - wd->pos_root.x, vr.y - wd->pos_root.y)); _m_paste_children(wd, is_child_refreshed, have_refreshed, vr, graph, nana::point()); @@ -66,7 +66,7 @@ namespace nana nana::point p_src; for (auto & el : blocks) { - if (el.window->other.category == category::frame_tag::value) + if (category::flags::frame == el.window->other.category) { native_window_type container = el.window->other.attribute.frame->container; native_interface::refresh_window(container); @@ -158,7 +158,7 @@ namespace nana bool window_layout::enable_effects_bground(core_window_t * wd, bool enabled) { - if (wd->other.category != category::widget_tag::value) + if (category::flags::widget != wd->other.category) return false; if (false == enabled) @@ -199,11 +199,11 @@ namespace nana nana::point rpos{ wd->pos_root }; auto & glass_buffer = wd->other.glass_buffer; - if (wd->parent->other.category == category::lite_widget_tag::value) + if (category::flags::lite_widget == wd->parent->other.category) { std::vector layers; core_window_t * beg = wd->parent; - while (beg && (beg->other.category == category::lite_widget_tag::value)) + while (beg && (category::flags::lite_widget == beg->other.category)) { layers.push_back(beg); beg = beg->parent; @@ -229,7 +229,7 @@ namespace nana nana::rectangle ovlp; if (child->visible && overlap(r, rectangle(child->pos_owner, child->dimension), ovlp)) { - if (child->other.category != category::lite_widget_tag::value) + if (category::flags::lite_widget != child->other.category) glass_buffer.bitblt(nana::rectangle(ovlp.x - pre->pos_owner.x, ovlp.y - pre->pos_owner.y, ovlp.width, ovlp.height), child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y)); ovlp.x += pre->pos_root.x; ovlp.y += pre->pos_root.y; @@ -250,7 +250,7 @@ namespace nana nana::rectangle ovlp; if (child->visible && overlap(r_of_wd, rectangle{ child->pos_owner, child->dimension }, ovlp)) { - if (child->other.category != category::lite_widget_tag::value) + if (category::flags::lite_widget != child->other.category) glass_buffer.bitblt(nana::rectangle{ ovlp.x - wd->pos_owner.x, ovlp.y - wd->pos_owner.y, ovlp.width, ovlp.height }, child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y)); ovlp.x += wd->pos_root.x; @@ -285,7 +285,7 @@ namespace nana if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect)) { bool have_child_refreshed = false; - if (child->other.category != category::lite_widget_tag::value) + if (category::flags::lite_widget != child->other.category) { if (is_child_refreshed && (false == child->flags.refreshing)) { diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 6096d543..66d0def6 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -312,7 +312,7 @@ namespace detail wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph); impl_->wd_register.insert(wd, wd->thread_id); - if (owner && owner->other.category == category::frame_tag::value) + if (owner && (category::flags::frame == owner->other.category)) insert_frame(owner, wd); bedrock::inc_window(wd->thread_id); @@ -344,7 +344,7 @@ namespace detail { //Thread-Safe Required! std::lock_guard lock(mutex_); - if(frame->other.category == category::frame_tag::value) + if(category::flags::frame == frame->other.category) frame->other.attribute.frame->attach.push_back(wd); return true; } @@ -357,9 +357,9 @@ namespace detail { //Thread-Safe Required! std::lock_guard lock(mutex_); - if(frame->other.category == category::frame_tag::value) + if(category::flags::frame == frame->other.category) { - if (impl_->wd_register.available(wd) && wd->other.category == category::root_tag::value && wd->root != frame->root) + if (impl_->wd_register.available(wd) && (category::flags::root == wd->other.category) && wd->root != frame->root) { frame->other.attribute.frame->attach.push_back(wd->root); return true; @@ -399,7 +399,7 @@ namespace detail if (wd->flags.destroying) return; - if(wd->other.category == category::root_tag::value) + if(category::flags::root == wd->other.category) { auto &brock = bedrock::instance(); arg_unload arg; @@ -464,7 +464,7 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd) == false) return; - if((wd->other.category == category::root_tag::value) || (wd->other.category != category::frame_tag::value)) + if((category::flags::root == wd->other.category) || (category::flags::frame != wd->other.category)) { impl_->misc_register.erase(wd->root); impl_->wd_register.remove(wd); @@ -484,7 +484,7 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd)) { - if(wd->other.category == category::root_tag::value) + if(category::flags::root == wd->other.category) native_interface::window_icon(wd->root, small_icon, big_icon); } } @@ -504,9 +504,9 @@ namespace detail native_window_type nv = nullptr; switch(wd->other.category) { - case category::root_tag::value: + case category::flags::root: nv = wd->root; break; - case category::frame_tag::value: + case category::flags::frame: nv = wd->other.attribute.frame->container; break; default: //category::widget_tag, category::lite_widget_tag break; @@ -703,7 +703,7 @@ namespace detail wd->dimension = sz; - if(category::lite_widget_tag::value != wd->other.category) + if(category::flags::lite_widget != wd->other.category) { bool graph_state = wd->drawer.graphics.empty(); wd->drawer.graphics.make(sz); @@ -714,13 +714,13 @@ namespace detail if(graph_state != wd->drawer.graphics.empty()) wd->drawer.typeface_changed(); - if(category::root_tag::value == wd->other.category) + if(category::flags::root == wd->other.category) { wd->root_graph->make(sz); if(false == passive) native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)); } - else if(category::frame_tag::value == wd->other.category) + else if(category::flags::frame == wd->other.category) { native_interface::window_size(wd->other.attribute.frame->container, sz); for(auto natwd : wd->other.attribute.frame->attach) @@ -850,6 +850,9 @@ namespace detail { window_layer::paint(wd, false, refresh_tree); this->map(wd, force_copy_to_screen); + + wd->drawer.graphics.save_as_file("d:\\button.bmp"); + wd->root_graph->save_as_file("d:\\button_root.bmp"); } else if (effects::edge_nimbus::none != wd->effect.edge_nimbus) { @@ -1379,7 +1382,7 @@ namespace detail root_attr->menubar = nullptr; } - if (wd->other.category == category::root_tag::value) + if (wd->other.category == category::flags::root) { root_runtime(wd->root)->shortkeys.clear(); wd->other.attribute.root->focus = nullptr; @@ -1459,7 +1462,7 @@ namespace detail } } - if (wd->other.category == category::frame_tag::value) + if (category::flags::frame == wd->other.category) { //remove the frame handle from the WM frames manager. utl::erase(root_attr->frames, wd); @@ -1565,7 +1568,7 @@ namespace detail wd->drawer.detached(); wd->widget_notifier->destroy(); - if(wd->other.category == category::frame_tag::value) + if(category::flags::frame == wd->other.category) { //The frame widget does not have an owner, and close their element windows without activating owner. //close the frame container window, it's a native window. @@ -1616,7 +1619,7 @@ namespace detail for(auto i = wd->children.rbegin(); i != wd->children.rend(); ++i) { core_window_t* child = *i; - if((child->other.category != category::root_tag::value) && _m_effective(child, pos)) + if((child->other.category != category::flags::root) && _m_effective(child, pos)) { child = _m_find(child, pos); if(child) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 1a0e5cb1..c8e6ea9e 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -528,8 +529,14 @@ namespace nana { for (auto i = elements.begin(), end = elements.end(); i != end; ++i) { - if (!API::is_destroying(API::get_parent_window(wd))) - place_ptr_->collocate(); + if (i->handle == wd) + { + elements.erase(i); + + if (!API::is_destroying(API::get_parent_window(wd))) + place_ptr_->collocate(); + break; + } } }); } @@ -2845,3 +2852,5 @@ namespace nana } //end class place }//end namespace nana + +#include diff --git a/source/internationalization.cpp b/source/internationalization.cpp index 1210826e..8ac35899 100644 --- a/source/internationalization.cpp +++ b/source/internationalization.cpp @@ -10,6 +10,8 @@ * @file: nana/internationalization.cpp */ +#include + #include #include #include @@ -513,3 +515,5 @@ namespace nana } //end class i18n_eval } + +#include diff --git a/source/paint/detail/image_process_provider.cpp b/source/paint/detail/image_process_provider.cpp index 1c0c61ab..414d68dc 100644 --- a/source/paint/detail/image_process_provider.cpp +++ b/source/paint/detail/image_process_provider.cpp @@ -1,3 +1,4 @@ +#include #include #include diff --git a/source/paint/image.cpp b/source/paint/image.cpp index 3d23e3f5..529c5c44 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -11,7 +11,7 @@ * @contributors: * nabijaczleweli(pr#106) */ - +#include #include #include #include diff --git a/source/paint/image_process_selector.cpp b/source/paint/image_process_selector.cpp index f95ab20e..9dc76e23 100644 --- a/source/paint/image_process_selector.cpp +++ b/source/paint/image_process_selector.cpp @@ -1,3 +1,4 @@ +#include #include namespace nana From a580237e0523edc854f96a4b2eb21942904ef72c Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 16:50:44 +0100 Subject: [PATCH 102/309] to retrieve a modifiable object from a list item --- include/nana/detail/platform_spec_selector.hpp | 8 ++++---- include/nana/gui/detail/general_events.hpp | 2 +- include/nana/gui/widgets/listbox.hpp | 11 +++++++++++ source/detail/platform_spec_windows.cpp | 6 +++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/nana/detail/platform_spec_selector.hpp b/include/nana/detail/platform_spec_selector.hpp index d230088f..fc4504f8 100644 --- a/include/nana/detail/platform_spec_selector.hpp +++ b/include/nana/detail/platform_spec_selector.hpp @@ -1,15 +1,15 @@ -/* +/** * Selector of Platform Specification * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/detail/platform_spec_selector.hpp + * @file nana/detail/platform_spec_selector.hpp * - * Selects the proper platform_spec header file for the current platform + * @brief Selects the proper platform_spec header file for the current platform */ #include diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 454b407f..c30c2d1c 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -536,7 +536,7 @@ namespace nana struct arg_click : public event_arg { ::nana::window window_handle; ///< A handle to the event window - const arg_mouse* mouse_args; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise. + const arg_mouse* mouse_args{}; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise. }; /// provides some fundamental events that every widget owns. diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 42ac9123..f2c97612 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -295,7 +295,18 @@ namespace nana throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); return *p; } + template + T & value() + { + auto * pany = _m_value(); + if (nullptr == pany) + throw std::runtime_error("listbox::item_proxy.value() is empty"); + T * p = any_cast(_m_value(false)); + if (nullptr == p) + throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); + return *p; + } template item_proxy & value(T&& t) { diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 88317ede..70bc1714 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -1,7 +1,7 @@ -/* +/** * Platform Specification Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -9,7 +9,7 @@ * * @file: nana/detail/platform_spec.cpp * - * This file provides basis class and data structrue that required by nana + * @brief basis classes and data structrues required by nana */ #include From fd2971c87f96fbf0b6e934bcf143ed07d6710ba9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 16:59:54 +0100 Subject: [PATCH 103/309] runtime reduction of incompatibilities and potential crash: rewrite !! --- source/detail/platform_spec_windows.cpp | 169 +++++++++++++++++++++++- 1 file changed, 166 insertions(+), 3 deletions(-) diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 70bc1714..a2968f5b 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -19,9 +19,172 @@ #include #include -#if defined(_MSC_VER) -#include -#endif // _MSVC + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +/****************************************************************** +* * +* VersionHelpers.h -- This module defines helper functions to * +* promote version check with proper * +* comparisons. * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +******************************************************************/ + +#include // for _In_, etc. + +#if !defined(__midl) && !defined(SORTPP_PASS) + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +#ifdef __cplusplus + +#define VERSIONHELPERAPI inline bool + +#else // __cplusplus + +#define VERSIONHELPERAPI FORCEINLINE BOOL + +#endif // __cplusplus + +VERSIONHELPERAPI +IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +VERSIONHELPERAPI +IsWindowsXPOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + +VERSIONHELPERAPI +IsWindowsXPSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1); +} + +VERSIONHELPERAPI +IsWindowsXPSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2); +} + +VERSIONHELPERAPI +IsWindowsXPSP3OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3); +} + +VERSIONHELPERAPI +IsWindowsVistaOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +VERSIONHELPERAPI +IsWindowsVistaSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1); +} + +VERSIONHELPERAPI +IsWindowsVistaSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2); +} + +VERSIONHELPERAPI +IsWindows7OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +} + +VERSIONHELPERAPI +IsWindows7SP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); +} + +#ifndef _WIN32_WINNT_WIN8 // (0x0602) + #define _WIN32_WINNT_WIN8 (0x0602) +#endif // _WIN32_WINNT_WIN8(0x0602) + +VERSIONHELPERAPI +IsWindows8OrGreater() +{ + + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +} + +#ifndef _WIN32_WINNT_WINBLUE // (0x0602) + #define _WIN32_WINNT_WINBLUE (0x0602) +#endif // _WIN32_WINNT_WINBLUE (0x0602) + +VERSIONHELPERAPI +IsWindows8Point1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); +} + +VERSIONHELPERAPI +IsWindowsServer() +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0, 0, VER_NT_WORKSTATION }; + DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL); + + return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask); +} + +#endif // NTDDI_VERSION + +#endif // defined(__midl) + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// + + + +//#if defined(_MSC_VER) +////#include +//bool IsWindowsVistaOrGreater() { return false; } +//bool //VERSIONHELPERAPI +//IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +//{ +// OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; +// DWORDLONG const dwlConditionMask = VerSetConditionMask( +// VerSetConditionMask( +// VerSetConditionMask( +// 0, VER_MAJORVERSION, VER_GREATER_EQUAL), +// VER_MINORVERSION, VER_GREATER_EQUAL), +// VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); +// +// osvi.dwMajorVersion = wMajorVersion; +// osvi.dwMinorVersion = wMinorVersion; +// osvi.wServicePackMajor = wServicePackMajor; +// +// return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +//} +// +// +// +//#endif // _MSVC namespace nana { From a9ef23d8d85bac29ed6aa963d7892121c9a8c895 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 17:03:32 +0100 Subject: [PATCH 104/309] utf8_Error:std::runtime_error +static bool use_throw{true} and emit(); --- source/deploy.cpp | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/source/deploy.cpp b/source/deploy.cpp index 91c4300d..ba6a0907 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -479,6 +479,8 @@ namespace std } //#endif // STD_put_time_NOT_SUPPORTED +#include + namespace nana { bool is_utf8(const char* str, unsigned len) @@ -511,22 +513,52 @@ namespace nana return true; } + struct utf8_Error : std::runtime_error + { + static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? + + utf8_Error(const std::string& what_arg) + :std::runtime_error{ std::string("\nRun-time utf8 Error: ") + what_arg } + {} + + utf8_Error(const char * what_arg) + :utf8_Error{ std::string(what_arg) } + {} + + + void emit() + { + if (use_throw) + throw utf8_Error(*this); + std::cerr << what(); + } + }; + + //bool utf8_Error::use_throw{true}; + bool utf8_Error::use_throw{ false }; + void throw_not_utf8(const std::string& text) { if (!is_utf8(text.c_str(), text.length())) - throw std::invalid_argument("The text is not encoded in UTF8"); + return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + + //throw std::invalid_argument( std::string("The text is not encoded in UTF8: ")+text ) ; } void throw_not_utf8(const char* text, unsigned len) { if (!is_utf8(text, len)) - throw std::invalid_argument("The text is not encoded in UTF8"); + return utf8_Error(std::string("The text is not encoded in UTF8: ") + std::string(text, len) ).emit(); + + //throw std::invalid_argument("The text is not encoded in UTF8"); } void throw_not_utf8(const char* text) { if (!is_utf8(text, std::strlen(text))) - throw std::invalid_argument("The text is not encoded in UTF8"); + return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + + //throw std::invalid_argument("The text is not encoded in UTF8"); } From 10eaa91c3ce6e6898419c852a8d0d85c123375a2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 22:20:48 +0100 Subject: [PATCH 105/309] experimenting with review_utf8 --- include/nana/deploy.hpp | 6 +++++ source/deploy.cpp | 48 +++++++++++++++++++++++++--------- source/gui/msgbox.cpp | 6 +++-- source/gui/widgets/listbox.cpp | 1 + 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 069545cb..0f7cb8c9 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -119,6 +119,12 @@ namespace nana void throw_not_utf8(const char*, unsigned len); void throw_not_utf8(const char*); + /// this text needed change, it needed review ?? + bool review_utf8(const std::string& text); + + /// this text needed change, it needed review ?? + bool review_utf8(std::string& text); + const std::string& to_utf8(const std::string&); std::string to_utf8(const std::wstring&); diff --git a/source/deploy.cpp b/source/deploy.cpp index ba6a0907..0e6b0faf 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -513,19 +513,13 @@ namespace nana return true; } + /// move to *.h ?? struct utf8_Error : std::runtime_error { static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? - - utf8_Error(const std::string& what_arg) - :std::runtime_error{ std::string("\nRun-time utf8 Error: ") + what_arg } - {} - - utf8_Error(const char * what_arg) - :utf8_Error{ std::string(what_arg) } - {} - - + + using std::runtime_error::runtime_error; + void emit() { if (use_throw) @@ -541,8 +535,6 @@ namespace nana { if (!is_utf8(text.c_str(), text.length())) return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); - - //throw std::invalid_argument( std::string("The text is not encoded in UTF8: ")+text ) ; } void throw_not_utf8(const char* text, unsigned len) @@ -562,6 +554,38 @@ namespace nana } + std::string recode_to_utf8(std::string no_utf8) + { + return nana::charset(no_utf8).to_bytes(nana::unicode::utf8); + } + + /// this text needed change, it needed review ?? + bool review_utf8(const std::string& text) + { + if (!is_utf8(text.c_str(), text.length())) + { + utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + return true; /// it needed change, it needed review !! + } + else + return false; + } + + /// this text needed change, it needed review ?? + bool review_utf8(std::string& text) + { + if (!is_utf8(text.c_str(), text.length())) + { + utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + text.swap(recode_to_utf8(text)); + return true; /// it needed change, it needed review !! + } + else + return false; + } + + + const std::string& to_utf8(const std::string& str) { return str; diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 8d4914f6..e3accf06 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -355,13 +355,15 @@ namespace nana msgbox::msgbox(const std::string& title) : wd_(nullptr), title_(title), button_(ok), icon_(icon_none) { - throw_not_utf8(title_); + // throw_not_utf8(title_); + review_utf8(title_); } msgbox::msgbox(window wd, const std::string& title, button_t b) : wd_(wd), title_(title), button_(b), icon_(icon_none) { - throw_not_utf8(title_); + // throw_not_utf8(title_); + review_utf8(title_); } msgbox& msgbox::icon(icon_t ic) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 56eff953..405e88a4 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3148,6 +3148,7 @@ namespace nana { auto cell_txtcolor = fgcolor; auto & m_cell = item.cells[column_pos]; + review_utf8(m_cell.text); nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need From b0815fafca450801e1a6a3bd87043f61d8ef4d63 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 18 Mar 2016 22:22:55 +0100 Subject: [PATCH 106/309] cool, the program disappear inversely --- source/gui/place.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 1a0e5cb1..e712b063 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -528,8 +528,14 @@ namespace nana { for (auto i = elements.begin(), end = elements.end(); i != end; ++i) { - if (!API::is_destroying(API::get_parent_window(wd))) - place_ptr_->collocate(); + if (i->handle == wd) + { + elements.erase(i); + + if (!API::is_destroying(API::get_parent_window(wd))) + place_ptr_->collocate(); + break; + } } }); } From 46d06d3ee66764dca610bd39fa358402fbc6c084 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 23 Mar 2016 15:31:13 +0800 Subject: [PATCH 107/309] fix a datetime issue --- source/datetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/datetime.cpp b/source/datetime.cpp index 21cfe962..d633090d 100644 --- a/source/datetime.cpp +++ b/source/datetime.cpp @@ -57,7 +57,7 @@ namespace nana } date::date() - : value_(to_dateval(*std::localtime(nullptr))) + : value_(to_dateval(localtime())) { } From c0e4a16880708ddac01ebbdcc7ae687b225b17cc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 23 Mar 2016 15:33:30 +0800 Subject: [PATCH 108/309] fix listbox enable_single crash(#121) --- source/gui/widgets/listbox.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 56eff953..ad043f56 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3435,6 +3435,9 @@ namespace nana if (lister.forward(essence_->scroll.offset_y_dpl, ptr_where.second, item_pos)) { auto * item_ptr = (item_pos.is_item() ? &lister.at(item_pos) : nullptr); + + const index_pair abs_item_pos{ item_pos.cat, lister.absolute(item_pos) }; + if(ptr_where.first == parts::lister) { bool sel = true; @@ -3443,28 +3446,32 @@ namespace nana if (arg.shift) lister.select_display_range(lister.last_selected_abs , item_pos, sel); else if (arg.ctrl) - sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected(); + sel = !item_proxy(essence_, abs_item_pos).selected(); else lister.select_for_all(false); //cancel all selections } else - sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected(); + { + //Clicking on a category is ignored when single selection is enabled. + //Fixed by Greentwip(issue #121) + if (item_ptr) + sel = !item_proxy(essence_, abs_item_pos).selected(); + } if(item_ptr) { item_ptr->flags.selected = sel; - index_pair last_selected(item_pos.cat, lister.absolute(item_pos)); - arg_listbox arg{item_proxy{essence_, last_selected}, sel}; + arg_listbox arg{ item_proxy{ essence_, abs_item_pos }, sel }; lister.wd_ptr()->events().selected.emit(arg); if (item_ptr->flags.selected) { - lister.cancel_others_if_single_enabled(true, last_selected); - essence_->lister.last_selected_abs = last_selected; + lister.cancel_others_if_single_enabled(true, abs_item_pos); + essence_->lister.last_selected_abs = abs_item_pos; } - else if (essence_->lister.last_selected_abs == last_selected) + else if (essence_->lister.last_selected_abs == abs_item_pos) essence_->lister.last_selected_abs.set_both(npos); } else if(!lister.single_selection()) @@ -3475,13 +3482,11 @@ namespace nana if(item_ptr) { item_ptr->flags.checked = ! item_ptr->flags.checked; - - index_pair abs_pos{ item_pos.cat, lister.absolute(item_pos) }; - arg_listbox arg{ item_proxy{ essence_, abs_pos }, item_ptr->flags.checked }; + arg_listbox arg{ item_proxy{ essence_, abs_item_pos }, item_ptr->flags.checked }; lister.wd_ptr()->events().checked.emit(arg); if (item_ptr->flags.checked) - lister.cancel_others_if_single_enabled(false, abs_pos); + lister.cancel_others_if_single_enabled(false, abs_item_pos); } else if (! lister.single_check()) lister.categ_checked_reverse(item_pos.cat); From 266def9ee31bec4712eda6083a2a56bf8b1b86cb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 23 Mar 2016 17:19:54 +0100 Subject: [PATCH 109/309] Doxy comments --- include/nana/charset.hpp | 50 ++++++++++++++++++++-------------------- source/charset.cpp | 13 ++++++----- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/nana/charset.hpp b/include/nana/charset.hpp index 41fa4d72..09f79bdf 100644 --- a/include/nana/charset.hpp +++ b/include/nana/charset.hpp @@ -46,7 +46,31 @@ namespace nana class charset_encoding_interface; } - /// An intelligent charset class for character code conversion. + /*!\class charset + \brief An intelligent charset class for character code conversion. + Example: + 1. A UTF-8 string from the socket. + + int len = ::recv(sd, buf, buflen, 0); + textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8)); + + 2. Send the string in text to the socket as UTF-8. + + std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8); + ::send(sd, utf8str.c_str(), utf8str.size(), 0); + + 3, Convert a string to the specified multi-byte character code. + + // Convert to a multibytes string through default system language. + std::string mbstr = nana::charset(a_wstring); + + // If the default system language is English and convert + // a Chinese unicode string to multibytes string through GB2312 + std::setlocale(LC_CTYPE, "zh_CN.GB2312"); + //set::setlocale(LC_CTYPE, ".936"); call it in Windows + std::string mbstr = nana::charset(a_wstring_with_chinese); + + */ class charset { public: @@ -74,27 +98,3 @@ namespace nana }//end namespace nana #endif -/*!\class charset - -Example -1. A UTF-8 string from the socket. - - int len = ::recv(sd, buf, buflen, 0); - textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8)); - -2. Send the string in text to the socket as UTF-8. - - std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8); - ::send(sd, utf8str.c_str(), utf8str.size(), 0); - -3, Convert a string to the specified multi-byte character code. - - //Convert to a multibytes string through default system language. - std::string mbstr = nana::charset(a_wstring); - //If the default system language is English and convert - //a Chinese unicode string to multibytes string through GB2312 - std::setlocale(LC_CTYPE, "zh_CN.GB2312"); - //set::setlocale(LC_CTYPE, ".936"); call it in Windows - std::string mbstr = nana::charset(a_wstring_with_chinese); - -*/ \ No newline at end of file diff --git a/source/charset.cpp b/source/charset.cpp index 686f8182..95753662 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -578,37 +578,38 @@ namespace nana std::string data_for_move_; }; #else + /// return the first code point and move the pointer to next character, springing to the end by errors unsigned long utf8char(const unsigned char*& p, const unsigned char* end) { if(p != end) { - if(*p < 0x80) + if(*p < 0x80) // ASCII char 0-127 or 0-0x80 { return *(p++); } unsigned ch = *p; unsigned long code; - if(ch < 0xC0) + if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { p = end; return 0; } - else if(ch < 0xE0 && (p + 1 <= end)) + else if(ch < 0xE0 && (p + 1 <= end)) // two byte chararcter { code = ((ch & 0x1F) << 6) | (p[1] & 0x3F); p += 2; } - else if(ch < 0xF0 && (p + 2 <= end)) + else if(ch < 0xF0 && (p + 2 <= end)) // 3 byte character { code = ((((ch & 0xF) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F); p += 3; } - else if(ch < 0x1F && (p + 3 <= end)) + else if(ch < 0x1F && (p + 3 <= end)) // 4 byte character { code = ((((((ch & 0x7) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F)) << 6) | (p[3] & 0x3F); p += 4; } - else + else // error, go to end { p = end; return 0; From db9167bb2182f8a3449615581aac74bd003fc479 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 23 Mar 2016 17:21:42 +0100 Subject: [PATCH 110/309] change default error behavior to preserve bad code unit as valid utf8 --- source/charset.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/charset.cpp b/source/charset.cpp index 95753662..ed4d643f 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -591,6 +591,7 @@ namespace nana unsigned long code; if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { + return *(p++); // temp: assume equal p = end; return 0; } From 6b2d5afa6b779dcb4d33d50b14cf2291329ee8f1 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 24 Mar 2016 03:14:18 +0100 Subject: [PATCH 111/309] move utf8_Error to *.h --- include/nana/deploy.hpp | 11 +++++++++++ source/deploy.cpp | 10 +--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index f172fb71..f031c66d 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -114,6 +114,17 @@ namespace std namespace nana { + /// move to *.h ?? + struct utf8_Error : std::runtime_error + { + static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? + + using std::runtime_error::runtime_error; + + void emit(); + }; + + /// Checks whether a specified text is utf8 encoding bool is_utf8(const char* str, unsigned len); void throw_not_utf8(const std::string& text); diff --git a/source/deploy.cpp b/source/deploy.cpp index 0e6b0faf..bf2f69d2 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -513,20 +513,12 @@ namespace nana return true; } - /// move to *.h ?? - struct utf8_Error : std::runtime_error - { - static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ? - - using std::runtime_error::runtime_error; - - void emit() + void utf8_Error::emit() { if (use_throw) throw utf8_Error(*this); std::cerr << what(); } - }; //bool utf8_Error::use_throw{true}; bool utf8_Error::use_throw{ false }; From b2b2bf2858961d525fc768c5989cffe2b0810d1b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 24 Mar 2016 03:30:14 +0100 Subject: [PATCH 112/309] experimenting with def_encoding_error_police in my case all the 5 variant are working very well !! --- source/charset.cpp | 116 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 15 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index ed4d643f..d5e1edda 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1,4 +1,4 @@ -/* +/** * A Character Encoding Set Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,9 +7,9 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/charset.cpp - * @brief: A conversion between unicode characters and multi bytes characters - * @contributions: + * @file nana/charset.cpp + * @brief A conversion between unicode characters and multi bytes characters + * @contributions * UTF16 4-byte decoding issue by Renke Yan. * Pr0curo(pr#98) */ @@ -20,6 +20,7 @@ #include #include #include //Added by Pr0curo(pr#98) +#include //GCC 4.7.0 does not implement the and codecvt_utfx classes #ifndef STD_CODECVT_NOT_SUPPORTED @@ -210,22 +211,23 @@ namespace nana } namespace detail - { + { + /// candidate to be more general?? class locale_initializer { public: static void init() { static bool initialized = false; - if(false == initialized) - { - initialized = true; - //Only set the C library locale - std::setlocale(LC_CTYPE, ""); - } + if (initialized) return; + + initialized = true; + //Only set the C library locale + std::setlocale(LC_CTYPE, ""); } }; + /// convert wchar C string from ? ANSI code page CP_ACP (windows) or LC_CTYPE c locale (-nix) into utf8 std::string bool wc2mb(std::string& mbstr, const wchar_t * s) { if(nullptr == s || *s == 0) @@ -258,7 +260,8 @@ namespace nana #endif return true; } - + + /// convert a char C-string from The system default Windows ANSI code page CP_ACP or from LC_CTYPE c locale (-nix) into utf16 std::wstring bool mb2wc(std::wstring& wcstr, const char* s) { if(nullptr == s || *s == 0) @@ -291,6 +294,7 @@ namespace nana return true; } + /// convert a char C string from The system default Windows ANSI code page CP_ACP or LC_CTYPE c locale (-nix) into utf16 std::string bool mb2wc(std::string& wcstr, const char* s) { if(nullptr == s || *s == 0) @@ -304,6 +308,7 @@ namespace nana { wcstr.resize((chars - 1) * sizeof(wchar_t)); ::MultiByteToWideChar(CP_ACP, 0, s, -1, reinterpret_cast(&wcstr[0]), chars - 1); + // ^ the trick ! } #else locale_initializer::init(); @@ -338,6 +343,84 @@ namespace nana virtual std::wstring&& wstr_move() = 0; }; + /// playing with the idea - we need a mechanisme to set a user selected police - Testing an abtract interphase + struct encoding_error_police + { + virtual unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) = 0; + virtual ~encoding_error_police() = default; + }; + + /// the current nana default: it is safe - you may want to keep it ! use the other at your risk: mainly for debugging + struct utf8_error_police : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + current_code_unit = end; + return 0; + } + + }; + + /// + struct utf8_error_police_def_char : public encoding_error_police + { + static unsigned long def_error_mark ; + + unsigned long error_mark{ def_error_mark }; + utf8_error_police_def_char() = default; + utf8_error_police_def_char( unsigned long mark): error_mark{mark}{} + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + ++current_code_unit; //check (p != end) ? + return error_mark; + } + + }; + + unsigned long utf8_error_police_def_char::def_error_mark{ '*' }; + + /// + struct utf8_error_police_throw : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + //utf8_Error::use_throw = true; + utf8_Error(std::string("The text is not encoded in UTF8: ") + + reinterpret_cast( current_code_unit) ).emit();; + current_code_unit = end; + return 0; + } + + }; + + struct utf8_error_police_latin : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + return *(current_code_unit++) ; + } + }; + + struct utf8_error_police_system : public encoding_error_police + { + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + { + std::wstring wc; + mb2wc(wc, reinterpret_cast(current_code_unit)); + current_code_unit++; + return wc[0]; // use utf16char + } + }; + + + auto def_encoding_error_police = std::make_unique(); // the nana default +// auto def_encoding_error_police = std::make_unique(); +// auto def_encoding_error_police = std::make_unique(); +// auto def_encoding_error_police = std::make_unique('X'); +// auto def_encoding_error_police = std::make_unique(); + + + #ifndef STD_CODECVT_NOT_SUPPORTED class charset_string : public charset_encoding_interface @@ -578,6 +661,8 @@ namespace nana std::string data_for_move_; }; #else + + /// return the first code point and move the pointer to next character, springing to the end by errors unsigned long utf8char(const unsigned char*& p, const unsigned char* end) { @@ -591,9 +676,10 @@ namespace nana unsigned long code; if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { - return *(p++); // temp: assume equal - p = end; - return 0; + //return *(p++); // temp: assume equal + //p = end; + //return 0; + return def_encoding_error_police->next_code_point(p, end); } else if(ch < 0xE0 && (p + 1 <= end)) // two byte chararcter { From c963bb2a3e73130fffebe26b9b0328c7e47fe2a0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 24 Mar 2016 03:43:39 +0100 Subject: [PATCH 113/309] fix error with compiling with gcc in Linux --- source/deploy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/deploy.cpp b/source/deploy.cpp index bf2f69d2..8054c07d 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -569,7 +569,7 @@ namespace nana if (!is_utf8(text.c_str(), text.length())) { utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); - text.swap(recode_to_utf8(text)); + text=recode_to_utf8(text); return true; /// it needed change, it needed review !! } else From a7c58709576fd882e00c857b87bea4d0f61a2ab2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 25 Mar 2016 00:48:49 +0100 Subject: [PATCH 114/309] FIX convert from system non Unicode to Unicode --- source/charset.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index d5e1edda..573e1e91 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1156,10 +1156,10 @@ namespace nana switch(encoding) { case unicode::utf8: - return utf32_to_utf8(wcstr); - case unicode::utf16: - return utf32_to_utf16(wcstr); + return utf16_to_utf8(wcstr); case unicode::utf32: + return utf16_to_utf32(wcstr); + case unicode::utf16: return wcstr; } } From e8df4b4f69fae64eecc1dda4a9a4e10e3d0dad48 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 25 Mar 2016 00:50:09 +0100 Subject: [PATCH 115/309] comments and using system default encoding as utf error "police" --- source/charset.cpp | 21 ++++++++++++++------- source/deploy.cpp | 12 ++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index 573e1e91..42fc386a 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -35,6 +35,7 @@ namespace nana { namespace utf { + /// return a pointer to the code unit of the character at pos const char* char_ptr(const char* text, unsigned pos) { auto ustr = reinterpret_cast(text); @@ -49,10 +50,10 @@ namespace nana continue; } - if (uch < 0xC0) + if (uch < 0xC0) // use police ? return nullptr; - if ((uch < 0xE0) && (ustr + 1 < end)) + if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0 ustr += 2; else if (uch < 0xF0 && (ustr + 2 <= end)) ustr += 3; @@ -65,6 +66,7 @@ namespace nana return reinterpret_cast(ustr); } + /// return a pointer to the code unit of the character at pos - reuse ^ ? const char* char_ptr(const std::string& text_utf8, unsigned pos) { auto ustr = reinterpret_cast(text_utf8.c_str()); @@ -95,6 +97,7 @@ namespace nana return reinterpret_cast(ustr); } + /// return a code point (max 16 bits?) and the len in code units of the character at pos wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len) { if (!text_utf8) @@ -113,10 +116,10 @@ namespace nana if (len) *len = 1; - return *text_utf8; + return *text_utf8; // uch ? } - if (uch < 0xC0) + if (uch < 0xC0) // use police or ?? { if (len) *len = 0; @@ -152,6 +155,7 @@ namespace nana return 0; } + /// return a code point (max 16 bits?) and the len in code units of the character at pos wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len) { const char* ptr; @@ -401,6 +405,7 @@ namespace nana } }; + /// buggie? struct utf8_error_police_system : public encoding_error_police { unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override @@ -408,16 +413,18 @@ namespace nana std::wstring wc; mb2wc(wc, reinterpret_cast(current_code_unit)); current_code_unit++; - return wc[0]; // use utf16char + //wchar_t *p = &wc[0]; + + return wc[0]; // use utf16char but what endian? } }; - auto def_encoding_error_police = std::make_unique(); // the nana default +// auto def_encoding_error_police = std::make_unique(); // the nana default // auto def_encoding_error_police = std::make_unique(); // auto def_encoding_error_police = std::make_unique(); // auto def_encoding_error_police = std::make_unique('X'); -// auto def_encoding_error_police = std::make_unique(); + auto def_encoding_error_police = std::make_unique(); diff --git a/source/deploy.cpp b/source/deploy.cpp index 8054c07d..eb79b86a 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -526,13 +526,13 @@ namespace nana void throw_not_utf8(const std::string& text) { if (!is_utf8(text.c_str(), text.length())) - return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit(); } void throw_not_utf8(const char* text, unsigned len) { if (!is_utf8(text, len)) - return utf8_Error(std::string("The text is not encoded in UTF8: ") + std::string(text, len) ).emit(); + return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit(); //throw std::invalid_argument("The text is not encoded in UTF8"); } @@ -540,7 +540,7 @@ namespace nana void throw_not_utf8(const char* text) { if (!is_utf8(text, std::strlen(text))) - return utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit(); //throw std::invalid_argument("The text is not encoded in UTF8"); @@ -548,7 +548,7 @@ namespace nana std::string recode_to_utf8(std::string no_utf8) { - return nana::charset(no_utf8).to_bytes(nana::unicode::utf8); + return nana::charset(std::move(no_utf8)).to_bytes(nana::unicode::utf8); } /// this text needed change, it needed review ?? @@ -556,7 +556,7 @@ namespace nana { if (!is_utf8(text.c_str(), text.length())) { - utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + utf8_Error(std::string("\nThe const text is not encoded in UTF8: ") + text).emit(); return true; /// it needed change, it needed review !! } else @@ -568,7 +568,7 @@ namespace nana { if (!is_utf8(text.c_str(), text.length())) { - utf8_Error(std::string("The text is not encoded in UTF8: ") + text).emit(); + utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit(); text=recode_to_utf8(text); return true; /// it needed change, it needed review !! } From 8ab30d7457456a31c50320d5ad3684980a1fbd36 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 26 Mar 2016 16:25:56 +0100 Subject: [PATCH 116/309] doxy docs --- include/nana/gui/detail/basic_window.hpp | 67 +++++++++++------------- include/nana/gui/widgets/listbox.hpp | 28 +++++----- include/nana/gui/widgets/slider.hpp | 2 +- source/gui/detail/window_layout.cpp | 6 +-- source/gui/widgets/listbox.cpp | 24 ++++++--- 5 files changed, 69 insertions(+), 58 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index e2e68fe1..22f51122 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -1,4 +1,4 @@ -/* +/** * A Basic Window Widget Definition * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,7 +7,8 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/detail/basic_window.hpp + * @file nana/gui/detail/basic_window.hpp + * @brief A Basic Window Widget Definition */ #ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP @@ -58,20 +59,18 @@ namespace detail ::nana::rectangle effective_range_; };//end class caret_descriptor - //tab_type - //@brief: Define some constant about tab category, these flags can be combine with operator | + /// Define some constant about tab category, these flags can be combine with operator | struct tab_type { enum t { - none, //process by nana - tabstop, //move to the next tabstop window - eating, //process by current window + none, ///< process by nana + tabstop, ///< move to the next tabstop window + eating, ///< process by current window }; }; - //struct basic_window - //@brief: a window data structure descriptor + /// a window data structure descriptor struct basic_window : public events_holder { @@ -88,8 +87,7 @@ namespace detail bool rendered; }; - //basic_window - //@brief: constructor for the root window + /// constructor for the root window basic_window(basic_window* owner, std::unique_ptr&&, category::root_tag**); template @@ -106,8 +104,7 @@ namespace detail ~basic_window(); - //bind_native_window - //@brief: bind a native window and baisc_window + /// bind a native window and baisc_window void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&); void frame_window(native_window_type); @@ -116,13 +113,13 @@ namespace detail bool visible_parents() const; bool displayed() const; bool belong_to_lazy() const; - const basic_window * child_caret() const; //Returns a child which owns a caret + const basic_window * child_caret() const; ///< Returns the child which owns the caret bool is_draw_through() const; ///< Determines whether it is a draw-through window. basic_window * seek_non_lite_widget_ancestor() const; public: - //Override event_holder + /// Override event_holder bool set_events(const std::shared_ptr&) override; general_events * get_events() const override; private: @@ -132,7 +129,7 @@ namespace detail #if defined(NANA_LINUX) || defined(NANA_MACOS) point pos_native; #endif - point pos_root; //coordinate for root window + point pos_root; ///< coordinates of the root window point pos_owner; size dimension; ::nana::size min_track_size; @@ -147,9 +144,9 @@ namespace detail basic_window *owner; native_string_type title; - ::nana::detail::drawer drawer; //Self Drawer with owen graphics - basic_window* root_widget; //A pointer refers to the root basic window, if the window is a root, the pointer refers to itself. - paint::graphics* root_graph; //Refer to the root buffer graphics + ::nana::detail::drawer drawer; ///< Self Drawer with owen graphics + basic_window* root_widget; ///< A pointer refers to the root basic window, if the window is a root, the pointer refers to itself. + paint::graphics* root_graph; ///< Refer to the root buffer graphics cursor predef_cursor; std::unique_ptr widget_notifier; @@ -157,20 +154,20 @@ namespace detail { bool enabled :1; bool dbl_click :1; - bool captured :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle + bool captured :1; ///< if mouse button is down, it always receive mouse move even the mouse is out of its rectangle bool modal :1; - bool take_active:1; //If take_active is false, other.active_window still keeps the focus. + bool take_active:1; ///< If take_active is false, other.active_window still keeps the focus. bool refreshing :1; bool destroying :1; - bool dropable :1; //Whether the window has make mouse_drop event. - bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen. + bool dropable :1; ///< Whether the window has make mouse_drop event. + bool fullscreen :1; ///< When the window is maximizing whether it fit for fullscreen. bool borderless :1; - bool make_bground_declared : 1; //explicitly make bground for bground effects - bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus. - bool ignore_mouse_focus : 1; //A flag indicates whether the widget accepts focus when clicking on it - bool space_click_enabled : 1; //A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key. + bool make_bground_declared : 1; ///< explicitly make bground for bground effects + bool ignore_menubar_focus : 1; ///< A flag indicates whether the menubar sets the focus. + bool ignore_mouse_focus : 1; ///< A flag indicates whether the widget accepts focus when clicking on it + bool space_click_enabled : 1; ///< A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key. unsigned Reserved :18; - unsigned char tab; //indicate a window that can receive the keyboard TAB + unsigned char tab; ///< indicate a window that can receive the keyboard TAB mouse_action action; }flags; @@ -199,7 +196,7 @@ namespace detail struct attr_root_tag { - container frames; //initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame + container frames; ///< initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame container tabstop; std::vector effects_edge_nimbus; basic_window* focus{nullptr}; @@ -211,13 +208,13 @@ namespace detail cursor state_cursor{nana::cursor::arrow}; basic_window* state_cursor_window{ nullptr }; - std::function draw_through; // A draw through renderer for root widgets. + std::function draw_through; ///< A draw through renderer for root widgets. }; const category::flags category; - basic_window *active_window; //if flags.take_active is false, the active_window still keeps the focus, - //if the active_window is null, the parent of this window keeps focus. - paint::graphics glass_buffer; //if effect.bground is avaiable. Refer to window_layout::make_bground. + basic_window *active_window; ///< if flags.take_active is false, the active_window still keeps the focus, + ///< if the active_window is null, the parent of this window keeps focus. + paint::graphics glass_buffer; ///< if effect.bground is avaiable. Refer to window_layout::make_bground. update_state upd_state; union @@ -230,8 +227,8 @@ namespace detail ~other_tag(); }other; - native_window_type root; //root Window handle - unsigned thread_id; //the identifier of the thread that created the window. + native_window_type root; ///< root Window handle + unsigned thread_id; ///< the identifier of the thread that created the window. unsigned index; container children; }; diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 0f1e24e2..82e9abb1 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -517,7 +517,7 @@ namespace nana basic_event checked; basic_event selected; - /// An event occurs when a listbox category is double clicking. + /// An event that occurs when a listbox category is double clicking. basic_event category_dbl_click; }; @@ -536,19 +536,23 @@ namespace nana }//end namespace drawerbase /*! \class listbox -\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. -A category is a text with can be \a selected, \a checked and \a expanded to show the items. -An item is formed by \a column-fields, each corresponding to one of the \a headers. -An item can be \a selected and \a checked. +\brief A rectangle containing a list of strings from which the user can select. +This widget contain a list of \a categories, with in turn contain a list of \a items. +A \a category is a text with can be \a selected, \a checked and \a expanded to show the \a items. +An \a item is formed by \a column-fields, each corresponding to one of the \a headers. +An \a item can be \a selected and \a checked. The user can \a drag the header to \a resize it or to \a reorganize it. By \a clicking on one header the list get \a reordered, first up, and then down alternatively. -1. The resolver is used to resolute an object of the specified type for a listbox item. -3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. +1. The resolver is used to resolute an object of the specified type into (or back from) a listbox item. +3. nana::listbox creates the category 0 by default. + This is an special category, becouse it is invisible, while the associated items are visible. + The optional, user-created categories begin at index 1 and are visibles. + The member functions without the categ parameter operate the items that belong to category 0. 4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: Irreflexivity (comp(x, x) returns false) and - antisymmetry(comp(a, b) != comp(b, a) returns true) + Antisymmetry(comp(a, b) != comp(b, a) returns true) A simple example. bool sort_compare( const std::string& s1, nana::any*, const std::string& s2, nana::any*, bool reverse) @@ -563,10 +567,10 @@ By \a clicking on one header the list get \a reordered, first up, and then down { if(o1 && o2) //some items may not attach a customer object. { - int * i1 = o1->get(); - int * i2 = o2->get(); + int * i1 = any_cast(*o1); + int * i2 = any_cast(*o2); return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2)); - ;//some types may not be int. + // ^ some types may not be int. } return false; } @@ -710,7 +714,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down size_type size_categ() const; /// { diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 10a94e4d..edfafa3c 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -95,9 +95,9 @@ namespace nana } //read_visual_rectangle - //@brief: Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget, - // the visual rectangle is a rectangular block that a window should be displayed on screen. - // The result is a rectangle that is a visible area for its ancesters. + ///@brief Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget, + /// the visual rectangle is a rectangular block that a window should be displayed on screen. + /// The result is a rectangle that is a visible area for its ancesters. bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual) { if (! wd->displayed()) return false; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 723916ba..9604ac24 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -338,6 +338,7 @@ namespace nana column_t(native_string_type&& txt, unsigned px, size_type pos) : text(std::move(txt)), pixels(px), index(pos) {} + /// \todo introduce default cell format }; using container = std::vector ; @@ -1828,9 +1829,7 @@ namespace nana };//end class es_lister - //struct essence_t - //@brief: this struct gives many data for listbox, - // the state of the struct does not effect on member funcions, therefore all data members are public. + /// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public. struct essence_t { enum class item_state{normal, highlighted, pressed, grabbed, floated}; @@ -2644,6 +2643,7 @@ namespace nana item_spliter_ = npos; } + /// return true an set member item_spliter_ if x is in the spliter area after that header item (column) bool mouse_spliter(const nana::rectangle& r, int x) { if(essence_->ptr_state == item_state::highlighted) @@ -3003,9 +3003,19 @@ namespace nana } } - //Draws an item - //@param content_r the rectangle of list content - void _m_draw_item(const category_t& cat, const index_pair& item_pos, const int x, const int y, const int txtoff, unsigned width, const nana::rectangle& content_r, const std::vector& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const + /// Draws an item + void _m_draw_item(const category_t& cat, + const index_pair& item_pos, + const int x, + const int y, + const int txtoff, + unsigned width, + const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn + const std::vector& seqs, + nana::color bgcolor, + nana::color fgcolor, + item_state state + ) const { auto & item = cat.items[item_pos.item]; @@ -3022,7 +3032,7 @@ namespace nana if (item.flags.selected) bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected" else - bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); + bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } unsigned show_w = width - essence_->scroll.offset_x; From 5779b979f7e71b25969d18f31426189ce9355cfe Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 26 Mar 2016 16:32:45 +0100 Subject: [PATCH 117/309] implement some geometrical parameters ?? --- include/nana/gui/widgets/listbox.hpp | 14 ++++++++++++-- source/gui/widgets/listbox.cpp | 11 ++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 82e9abb1..cfad6214 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -529,8 +529,18 @@ namespace nana color_proxy header_floated{ static_cast(0xBABBBC)}; color_proxy item_selected{ static_cast(0xD5EFFC) }; - unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ?? - ext_w = 5; + /// \todo how to implement some geometrical parameters ?? + unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this + unsigned min_header_width{ 20 }; ///< non counting suspension_width + unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...") + unsigned ext_w { 5 }; ///< ?? + unsigned header_height { 20 }; ///< header height header_size + unsigned text_height { 0 }; ///< the trigger will set this to the height of the text font + unsigned item_height_ex { 6 }; ///< 6? item_height = text_height + item_height_ex + unsigned item_height { 0 }; ///< the trigger will set this TO item_height = text_height + item_height_ex + unsigned header_mouse_spliter_area_before{ 2 }; + unsigned header_mouse_spliter_area_after { 3 }; + }; } }//end namespace drawerbase diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 9604ac24..a0d30cdd 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1858,7 +1858,7 @@ namespace nana struct scroll_part { - static const unsigned scale = 16; + static const unsigned scale = 16; // ? int offset_x; index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. // need to be abs??? to see the same item after sort() ?? @@ -1982,8 +1982,9 @@ namespace nana void trace_item_abs( index_pair abs_pos ) { - if(abs_pos.item == npos && abs_pos.cat == scroll.offset_y_abs.cat - && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat + if( abs_pos.item == npos + && abs_pos.cat == scroll.offset_y_abs.cat + && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat return; trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ; @@ -2680,8 +2681,8 @@ namespace nana } //grab_move - //@brief: draw when an item is grabbing. - //@return: 0 = no graphics changed, 1 = just update, 2 = refresh + /// @brief draw when an item is grabbing. + /// @return 0 = no graphics changed, 1 = just update, 2 = refresh int grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) From c1f95c7f3cebd23b511a029364a187e9454d0bb6 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 20:50:51 +0200 Subject: [PATCH 118/309] small fix, more comments --- source/gui/widgets/listbox.cpp | 60 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index a0d30cdd..707eb339 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -329,7 +329,7 @@ namespace nana struct column_t { native_string_type text; ///< "text" header of the column number "index" with weigth "pixels" - unsigned pixels; + unsigned pixels; ///< width bool visible{true}; size_type index; std::function weak_ordering; @@ -411,7 +411,7 @@ namespace nana return cont_.back().index; } - void item_width(size_type pos, unsigned width) + void item_width(size_type pos, unsigned width) ///< set the column width { column(pos).pixels = width; } @@ -428,7 +428,7 @@ namespace nana return 0; } - unsigned pixels() const + unsigned pixels() const ///< the visible width of the whole header { unsigned pixels = 0; for(auto & m : cont_) @@ -471,12 +471,13 @@ namespace nana { if(x < static_cast(col.pixels)) return col.index; - x -= col.pixels; + if (col.visible) + x -= col.pixels; } return npos; } - /// return the left position of the column originaly at index "pos" . + /// return the left position and width (in variable *pixels) of the column originaly at index "pos" . int item_pos(size_type pos, unsigned * pixels) const { int left = 0; @@ -494,7 +495,8 @@ namespace nana } return left; } - /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" + + /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" size_type neighbor(size_type index, bool front) const { size_type n = npos; @@ -510,11 +512,12 @@ namespace nana break; } else if(i->visible) - n = i->index; + n = i->index; } return npos; } - /// return the original index of the currently first visible col + + /// return the original index of the currently first visible col size_type begin() const { for(const auto & m : cont_) @@ -533,7 +536,8 @@ namespace nana } return npos; } - /// move the col originaly at index to the position currently in front (or after) the col originaly at index "to" invalidating some current index + + /// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index void move(size_type index, size_type to, bool front) throw() { if ((index == to) || (index >= cont_.size()) || (to >= cont_.size())) @@ -880,7 +884,8 @@ namespace nana list_.back().key_ptr = ptr; return &list_.back(); } - /// add a new cat created at "pos" and return a ref to it + + /// add a new cat created at "pos" and return a ref to it category_t* create_cat(std::size_t pos, native_string_type&& text) { return &(*list_.emplace(this->get(pos), std::move(text))); @@ -1941,8 +1946,8 @@ namespace nana //number_of_lister_item - //@brief: Returns the number of items that are contained in pixels - //@param,with_rest: Means whether including extra one item that is not completely contained in reset pixels. + /// @brief Returns the number of items that are contained in pixels + /// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels. size_type number_of_lister_items(bool with_rest) const { unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale); @@ -2072,10 +2077,10 @@ namespace nana bool v = (lister.the_number_of_expanded() > screen_number); if(v == true && h == false) - h = (header_s > (sz.width - 2 - scroll.scale)); + h = ( (header_s + 2 + scroll.scale ) > sz.width); // 2? - unsigned width = sz.width - 2 - (v ? scroll.scale : 0); - unsigned height = sz.height - 2 - (h ? scroll.scale : 0); + unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2? + unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2? //event hander for scrollbars auto evt_fn = [this](const arg_scroll& arg) @@ -2168,7 +2173,8 @@ namespace nana return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0); } - std::pair where(int x, int y){ + std::pair where(int x, int y) + { std::pair new_where; if(2 < x && x < static_cast(graph->width()) - 2 && 1 < y && y < static_cast(graph->height()) - 1) @@ -2659,7 +2665,7 @@ namespace nana item_spliter_ = hd.index; // original index return true; } - x -= hd.pixels; + x -= hd.pixels; } } } @@ -2673,7 +2679,7 @@ namespace nana if(is_grab) { ref_xpos_ = pos.x; - if(item_spliter_ != npos) + if(item_spliter_ != npos) // resize header item, not move it orig_item_width_ = essence_->header.column(item_spliter_).pixels; } else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second) @@ -2686,16 +2692,16 @@ namespace nana int grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) - { - draw(rect); - _m_make_float(rect, pos); + { // move header item, not resize it + draw(rect); // first draw the entery header as it was + _m_make_float(rect, pos); // now draw one floating header item //Draw the target strip grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front); return 1; } else - { + { // resize header item, not move it const auto& item = essence_->header.column(item_spliter_); //Resize the item specified by item_spliter_. auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); @@ -3350,18 +3356,18 @@ namespace nana if(essence_->ptr_state == item_state::pressed) { if(essence_->pointer_where.first == parts::header) - { + { // moving a pressed header : grab it (or split-resize?) essence_->ptr_state = item_state::grabbed; nana::point pos = arg.pos; essence_->widget_to_header(pos); drawer_header_->grab(pos, true); API::capture_window(essence_->lister.wd_ptr()->handle(), true); - update = 2; + update = 2; //0 = nothing, 1 = update, 2 = refresh } } if(essence_->ptr_state == item_state::grabbed) - { + { // moving a grabbed header nana::point pos = arg.pos; essence_->widget_to_header(pos); @@ -3713,6 +3719,7 @@ namespace nana //end class trigger //class item_proxy + item_proxy::item_proxy(essence_t * ess) : ess_(ess) {} @@ -3985,6 +3992,7 @@ namespace nana //end class item_proxy //class cat_proxy + //the member cat_ is used for fast accessing to the category cat_proxy::cat_proxy(essence_t * ess, size_type pos) : ess_(ess), @@ -4315,6 +4323,7 @@ namespace nana //Implementation of arg_category //Contributed by leobackes(pr#97) + arg_category::arg_category ( const nana::drawerbase::listbox::cat_proxy& cat ) noexcept : category(cat), block_change_(false) { @@ -4332,6 +4341,7 @@ namespace nana //class listbox + listbox::listbox(window wd, bool visible) { create(wd, rectangle(), visible); From e7b8e603e4a77a69194dbaccc3cd9b9c9ba71c81 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 21:02:40 +0200 Subject: [PATCH 119/309] using geometric_scheme --- include/nana/gui/widgets/listbox.hpp | 27 +++++-- source/gui/widgets/listbox.cpp | 109 ++++++++++++++------------- 2 files changed, 77 insertions(+), 59 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index cfad6214..9ed36a89 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -532,14 +532,14 @@ namespace nana /// \todo how to implement some geometrical parameters ?? unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this unsigned min_header_width{ 20 }; ///< non counting suspension_width - unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...") - unsigned ext_w { 5 }; ///< ?? - unsigned header_height { 20 }; ///< header height header_size - unsigned text_height { 0 }; ///< the trigger will set this to the height of the text font - unsigned item_height_ex { 6 }; ///< 6? item_height = text_height + item_height_ex - unsigned item_height { 0 }; ///< the trigger will set this TO item_height = text_height + item_height_ex - unsigned header_mouse_spliter_area_before{ 2 }; - unsigned header_mouse_spliter_area_after { 3 }; + unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") + unsigned ext_w { 5 }; ///< def= . ?? + unsigned header_height { 20 }; ///< def= . header height header_size + unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font + unsigned item_height_ex { 2 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex + unsigned item_height { 16 }; ///< the trigger will set this TO item_height = text_height + item_height_ex + unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 + unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 }; } @@ -586,6 +586,17 @@ By \a clicking on one header the list get \a reordered, first up, and then down } listbox.anyobj(0, 0, 10); //the type of customer's object is int. listbox.anyobj(0, 0, 20); +5. listbox is a widget_object, with template parameters drawerbase::listbox::trigger and drawerbase::listbox::scheme +amon others. +That means that listbox have a member trigger_ constructed first and accecible with get_drawer_trigger() and +a member (unique pointer to) scheme_ accesible with scheme_type& scheme() created in the constructor +with API::dev::make_scheme() which call API::detail::make_scheme(::nana::detail::scheme_factory()) +which call restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_base&&>(factory)); +which call pi_data_->scheme.create(std::move(factory)); +which call factory.create(scheme_template(std::move(factory))); +which call (new Scheme(static_cast(other))); +and which in create is setted with: API::dev::set_scheme(handle_, scheme_.get()); which save the scheme pointer in +the nana::detail::basic_window member pointer scheme \todo doc: actualize this example listbox.at(0)... \see nana::drawerbase::listbox::cat_proxy \see nana::drawerbase::listbox::item_proxy diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 707eb339..3fde21a8 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1845,10 +1845,10 @@ namespace nana bool auto_draw{true}; bool checkable{false}; bool if_image{false}; - unsigned header_size{25}; - unsigned item_size{24}; - unsigned text_height{0}; - unsigned suspension_width{0}; + //unsigned header_size{25}; + //unsigned item_size{24}; + //unsigned text_height{0}; + //unsigned suspension_width{0}; ::nana::listbox::export_options def_exp_options; @@ -1951,7 +1951,7 @@ namespace nana size_type number_of_lister_items(bool with_rest) const { unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale); - return (lister_s / item_size) + (with_rest && (lister_s % item_size) ? 1 : 0); + return (lister_s / scheme_ptr->item_height) + (with_rest && (lister_s % scheme_ptr->item_height) ? 1 : 0); } //keep the first selected item in the display area: the distances are in display positions! @@ -2068,10 +2068,10 @@ namespace nana window wd = lister.wd_ptr()->handle(); //H scroll enabled - bool h = (header_s > sz.width - 4); - - unsigned lister_s = sz.height - 2 - header_visible_px() - (h ? scroll.scale : 0); - size_type screen_number = (lister_s / item_size); + bool h = (header_s + 4 > sz.width ); // 4? + unsigned head_scroll = 2 + header_visible_px() + (h ? scroll.scale : 0); // 2? + unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0 ; + size_type screen_number = (lister_s / scheme_ptr->item_height); //V scroll enabled bool v = (lister.the_number_of_expanded() > screen_number); @@ -2164,7 +2164,7 @@ namespace nana nana::rectangle checkarea(int x, int y) const { - return nana::rectangle(x + 4, y + (item_size - 16) / 2, 16, 16); + return nana::rectangle(x + 4, y + (static_cast(scheme_ptr->item_height) - 16) / 2, 16, 16); } int item_xpos(const nana::rectangle& r) const @@ -2178,23 +2178,25 @@ namespace nana std::pair new_where; if(2 < x && x < static_cast(graph->width()) - 2 && 1 < y && y < static_cast(graph->height()) - 1) - { - if(header.visible() && y < static_cast(header_size + 1)) - { + { /// we are inside + + if(header.visible() && y < static_cast(scheme_ptr->header_height + 1)) + { /// we are in the header + x -= (2 - scroll.offset_x); new_where.first = parts::header; new_where.second = static_cast(header.item_by_x(x)); } else { - new_where.second = ((y + 1) - header_visible_px()) / item_size; // y>1 ! + new_where.second = ((y + 1) - header_visible_px()) / scheme_ptr->item_height; // y>1 ! new_where.first = parts::lister; if(checkable) { nana::rectangle r; if(rect_lister(r)) { - std::size_t top = new_where.second * item_size + header_visible_px(); + std::size_t top = new_where.second * scheme_ptr->item_height + header_visible_px(); if(checkarea(item_xpos(r), static_cast(top)).is_hit(x, y)) new_where.first = parts::checker; } @@ -2222,7 +2224,7 @@ namespace nana void widget_to_header(nana::point& pos) { --pos.y; - pos.x += (scroll.offset_x - 2); + pos.x += (scroll.offset_x - 2); // why not: pos.x -= (scroll.offset_x + 1); } bool rect_header(nana::rectangle& r) const @@ -2232,7 +2234,7 @@ namespace nana if (lister.wd_ptr()->borderless()) { r = graph->size(); - r.height = header_size; + r.height = scheme_ptr->header_height; return !r.empty(); } @@ -2242,7 +2244,7 @@ namespace nana r.x = 2; r.y = 1; r.width = graph->width() - ex_width; - r.height = header_size; + r.height = scheme_ptr->header_height; return true; } } @@ -2251,7 +2253,7 @@ namespace nana unsigned header_visible_px() const { - return (header.visible() ? header_size : 0); + return (header.visible() ? scheme_ptr->header_height : 0); } bool rect_lister(nana::rectangle& r) const @@ -2317,8 +2319,9 @@ namespace nana return seqs; } - unsigned auto_width(size_type pos, unsigned max = 3000) /// \todo introduce parametr max_header_width + unsigned auto_width(size_type pos, unsigned max = 100000) { + max = std::min(max, scheme_ptr->max_header_width); unsigned max_w{ 0 }; for (const auto &cat : lister.cat_container()) for (const auto &it : cat.items) @@ -2660,7 +2663,8 @@ namespace nana { if(hd.visible) { - if((static_cast(hd.pixels) < x + 2) && (x < static_cast(hd.pixels) + 3)) + if(( static_cast(hd.pixels) < x + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_before)) + && (x < static_cast(hd.pixels) + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_after)) ) { item_spliter_ = hd.index; // original index return true; @@ -2670,7 +2674,7 @@ namespace nana } } else if(essence_->ptr_state == item_state::normal) - item_spliter_ = npos; + item_spliter_ = npos; return false; } @@ -2707,7 +2711,10 @@ namespace nana auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); if(item.pixels != new_w) { - essence_->header.item_width(item_spliter_, (new_w < (essence_->suspension_width + 20) ? essence_->suspension_width + 20 : new_w)); + essence_->header.item_width(item_spliter_, + (new_w < ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) ? + ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) + : new_w) ); new_w = essence_->header.pixels(); if(new_w < (rect.width + essence_->scroll.offset_x)) essence_->scroll.offset_x = (new_w > rect.width ? new_w - rect.width : 0); @@ -2723,7 +2730,7 @@ namespace nana { graph_reference graph = *(essence_->graph); - int text_top = (r.height - essence_->text_height) / 2 + r.y; + int text_top = (r.height - essence_->scheme_ptr->text_height) / 2 + r.y; auto text_color = essence_->lister.wd_ptr()->fgcolor(); auto state = item_state::normal; @@ -2823,11 +2830,11 @@ namespace nana { const auto & item = essence_->header.column(essence_->pointer_where.second); - nana::paint::graphics ext_graph({ item.pixels, essence_->header_size }); + nana::paint::graphics ext_graph({ item.pixels, essence_->scheme_ptr->header_height }); ext_graph.typeface(essence_->graph->typeface()); - int txtop = (essence_->header_size - essence_->text_height) / 2; - _m_draw_header_item(ext_graph, 0, 0, essence_->header_size, txtop, colors::white, item, item_state::floated); + int txtop = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; + _m_draw_header_item(ext_graph, 0, 0, essence_->scheme_ptr->header_height, txtop, colors::white, item, item_state::floated); int xpos = essence_->header.item_pos(item.index, nullptr) + pos.x - ref_xpos_; ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); @@ -2888,7 +2895,7 @@ namespace nana int x = essence_->item_xpos(rect); int y = rect.y; - int txtoff = (essence_->item_size - essence_->text_height) / 2; + int txtoff = (essence_->scheme_ptr->item_height - essence_->scheme_ptr->text_height) / 2; auto i_categ = lister.get(essence_->scroll.offset_y_dpl.cat); @@ -2925,7 +2932,7 @@ namespace nana item_index = lister.absolute_pair(item_index); _m_draw_item(*i_categ, item_index, x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state); - y += essence_->item_size; + y += essence_->scheme_ptr->item_height; } ++i_categ; @@ -2940,7 +2947,7 @@ namespace nana state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal); _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); - y += essence_->item_size; + y += essence_->scheme_ptr->item_height; if(false == i_categ->expand) continue; @@ -2956,7 +2963,7 @@ namespace nana item_pos.item = lister.absolute(item_pos); _m_draw_item(*i_categ, item_pos, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); - y += essence_->item_size; + y += essence_->scheme_ptr->item_height; ++idx.item; } } @@ -2977,14 +2984,14 @@ namespace nana bgcolor = bgcolor.blend(static_cast(0x99defd), 0.8); auto graph = essence_->graph; - graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true, bgcolor); + graph->rectangle(rectangle{ x, y, width, essence_->scheme_ptr->item_height }, true, bgcolor); color txt_color{ static_cast(0x3399) }; facade arrow("double"); arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south); arrow.draw( *graph, {}, txt_color, - { x + 5, y + static_cast(essence_->item_size - 16) / 2, 16, 16 }, + { x + 5, y + static_cast(essence_->scheme_ptr->item_height - 16) / 2, 16, 16 }, element_state::normal); graph->string({ x + 20, y + txtoff }, categ.text, txt_color); @@ -2998,7 +3005,7 @@ namespace nana if (x + 35 + extend_text_w < x + width) { - ::nana::point pos{ x + 30 + static_cast(extend_text_w), y + static_cast(essence_->item_size) / 2 }; + ::nana::point pos{ x + 30 + static_cast(extend_text_w), y + static_cast(essence_->scheme_ptr->item_height) / 2 }; graph->line(pos, { x + static_cast(width)-5, pos.y }, txt_color); } @@ -3047,7 +3054,7 @@ namespace nana auto graph = essence_->graph; //draw the background - graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->item_size }, true, bgcolor); + graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->scheme_ptr->item_height }, true, bgcolor); int item_xpos = x; unsigned extreme_text = x; @@ -3094,7 +3101,7 @@ namespace nana { nana::rectangle img_r(item.img_show_size); img_r.x = content_pos + item_xpos + static_cast(16 - item.img_show_size.width) / 2; - img_r.y = y + static_cast(essence_->item_size - item.img_show_size.height) / 2; + img_r.y = y + static_cast(essence_->scheme_ptr->item_height - item.img_show_size.height) / 2; item.img.stretch(rectangle{ item.img.size() }, *graph, img_r); } content_pos += 18; @@ -3114,7 +3121,7 @@ namespace nana auto wdg_w = header.pixels - static_cast(content_pos); bool visible_state = true; - if (::nana::overlap(content_r, { wdg_x, y, wdg_w, essence_->item_size }, pane_r)) + if (::nana::overlap(content_r, { wdg_x, y, wdg_w, essence_->scheme_ptr->item_height }, pane_r)) { ::nana::point pane_pos; if (wdg_x < content_r.x) @@ -3129,7 +3136,7 @@ namespace nana else visible_state = false; - ::nana::size sz{ wdg_w, essence_->item_size }; + ::nana::size sz{ wdg_w, essence_->scheme_ptr->item_height }; inline_wdg->pane_widget.size(sz); inline_wdg->inline_ptr->resize(sz); @@ -3176,7 +3183,7 @@ namespace nana if (item_state::highlighted == state) it_bgcolor = it_bgcolor.blend(static_cast(0x99defd), 0.8); - graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->item_size }, true, it_bgcolor); + graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->scheme_ptr->item_height }, true, it_bgcolor); cell_txtcolor = m_cell.custom_format->fgcolor; } @@ -3188,10 +3195,10 @@ namespace nana if (static_cast(ts.width) > static_cast(header.pixels) - (content_pos + item_xpos)) // it was an excess { //The text is painted over the next subitem // here beging the ... - int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->suspension_width); + int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->scheme_ptr->suspension_width); // litter rect with the item bg end ... - graph->rectangle(rectangle{ xpos, y + 2, essence_->suspension_width, essence_->item_size - 4 }, true, it_bgcolor); + graph->rectangle(rectangle{ xpos, y + 2, essence_->scheme_ptr->suspension_width, essence_->scheme_ptr->item_height - 4 }, true, it_bgcolor); graph->string(point{ xpos, y + 2 }, L"..."); //Erase the part that over the next subitem only if the right of column is less than right of listbox @@ -3199,21 +3206,21 @@ namespace nana { graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over graph->rectangle(rectangle{ item_xpos + static_cast(header.pixels), y + 2, - ts.width + static_cast(content_pos)-header.pixels, essence_->item_size - 4 }, true); + ts.width + static_cast(content_pos)-header.pixels, essence_->scheme_ptr->item_height - 4 }, true); } extreme_text = (std::max)(extreme_text, item_xpos + content_pos + ts.width); } } } - graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast(essence_->item_size) - 1 }, static_cast(0xEBF4F9)); + graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast(essence_->scheme_ptr->item_height) - 1 }, static_cast(0xEBF4F9)); } item_xpos += static_cast(header.pixels); if (display_order + 1 >= seqs.size() && static_cast(extreme_text) > item_xpos) { - graph->rectangle(rectangle{item_xpos , y + 2, extreme_text - item_xpos, essence_->item_size - 4}, true, item.bgcolor); + graph->rectangle(rectangle{item_xpos , y + 2, extreme_text - item_xpos, essence_->scheme_ptr->item_height - 4}, true, item.bgcolor); } } @@ -3260,13 +3267,13 @@ namespace nana { //Draw selecting inner rectangle auto graph = essence_->graph; - graph->rectangle({ x, y, width, essence_->item_size }, false, static_cast(0x99defd)); + graph->rectangle({ x, y, width, essence_->scheme_ptr->item_height }, false, static_cast(0x99defd)); - graph->rectangle({ x + 1, y + 1, width - 2, essence_->item_size - 2 }, false, colors::white); + graph->rectangle({ x + 1, y + 1, width - 2, essence_->scheme_ptr->item_height - 2 }, false, colors::white); graph->set_pixel(x, y); - graph->set_pixel(x, y + essence_->item_size - 1); + graph->set_pixel(x, y + essence_->scheme_ptr->item_height - 1); graph->set_pixel(x + width - 1, y); - graph->set_pixel(x + width - 1, y + essence_->item_size - 1); + graph->set_pixel(x + width - 1, y + essence_->scheme_ptr->item_height - 1); } private: essence_t * essence_; @@ -3329,9 +3336,9 @@ namespace nana void trigger::typeface_changed(graph_reference graph) { - essence_->text_height = graph.text_extent_size(L"jHWn0123456789/item_size = essence_->text_height + 6; - essence_->suspension_width = graph.text_extent_size(L"...").width; + essence_->scheme_ptr->text_height = graph.text_extent_size(L"jHWn0123456789/scheme_ptr->item_height = essence_->scheme_ptr->text_height + essence_->scheme_ptr->item_height_ex; + essence_->scheme_ptr->suspension_width = graph.text_extent_size("...").width; } void trigger::refresh(graph_reference) From feb26995da493376cfa3896383955b84926ff8f7 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 21:03:40 +0200 Subject: [PATCH 120/309] debug --- include/nana/gui/widgets/listbox.hpp | 6 ++--- source/gui/widgets/listbox.cpp | 34 +++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 9ed36a89..9b29a7a7 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -17,8 +17,6 @@ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP -#include - #include "widget.hpp" #include "detail/inline_widget.hpp" #include @@ -541,6 +539,8 @@ namespace nana unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 + void debug_print(const std::string &msg); + }; } }//end namespace drawerbase @@ -747,6 +747,4 @@ the nana::detail::basic_window member pointer scheme void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana - -#include #endif diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3fde21a8..8ec0e69d 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -28,13 +28,33 @@ #include #include #include +#include // for debug namespace nana -{ +{ + void debug(const std::string &msg, const rectangle&r) + { + std::cerr <<"\n" <scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); + essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); + essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); + essence_->graph = &graph; typeface_changed(graph); @@ -3348,10 +3372,18 @@ namespace nana nana::rectangle r; + essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); + if (essence_->header.visible() && essence_->rect_header(r)) drawer_header_->draw(r); + + debug("Header: ", r); + if (essence_->rect_lister(r)) drawer_lister_->draw(r); + + debug("Lister: ", r); + _m_draw_border(); } From 55819dc7d39beff85453f3623a7c66cfde4d93f9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 21:04:11 +0200 Subject: [PATCH 121/309] small fix --- source/gui/widgets/listbox.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8ec0e69d..f925aea6 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1883,7 +1883,7 @@ namespace nana struct scroll_part { - static const unsigned scale = 16; // ? + static const unsigned scale = 16; // ? int offset_x; index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. // need to be abs??? to see the same item after sort() ?? @@ -2123,7 +2123,7 @@ namespace nana if(h) { - rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); + rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); // -? if(scroll.h.empty()) { scroll.h.create(wd, r); @@ -2138,7 +2138,7 @@ namespace nana if(v) { - rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); + rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); // -? if(scroll.v.empty()) { scroll.v.create(wd, r); @@ -2159,7 +2159,7 @@ namespace nana { if(header_s > r.width) { - if((header_s - scroll.offset_x) < r.width) + if(header_s < r.width - scroll.offset_x) scroll.offset_x = header_s - r.width; } else @@ -2182,7 +2182,7 @@ namespace nana } } - nana::rectangle checkarea(int x, int y) const + nana::rectangle checkarea(int x, int y) const /// move to scheme ?? 16 ? { return nana::rectangle(x + 4, y + (static_cast(scheme_ptr->item_height) - 16) / 2, 16, 16); } @@ -2205,7 +2205,7 @@ namespace nana x -= (2 - scroll.offset_x); new_where.first = parts::header; - new_where.second = static_cast(header.item_by_x(x)); + new_where.second = header.item_by_x(x); } else { From e84f6117614804afbd75e955a0009469df4aed89 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:16:38 +0200 Subject: [PATCH 122/309] original default values --- include/nana/gui/widgets/listbox.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 9b29a7a7..c1ff7ef4 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -529,13 +529,13 @@ namespace nana /// \todo how to implement some geometrical parameters ?? unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this - unsigned min_header_width{ 20 }; ///< non counting suspension_width + unsigned min_header_width{ 20 }; ///< def=20 . non counting suspension_width unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") - unsigned ext_w { 5 }; ///< def= . ?? - unsigned header_height { 20 }; ///< def= . header height header_size + unsigned ext_w { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 + unsigned header_height { 20 }; ///< def=25 . header height header_size unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font unsigned item_height_ex { 2 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex - unsigned item_height { 16 }; ///< the trigger will set this TO item_height = text_height + item_height_ex + unsigned item_height { 16 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 From 09da5347198642a0209efabc0a57a269e43df4d8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:22:38 +0200 Subject: [PATCH 123/309] code review and int/unsigned consistence --- source/gui/widgets/listbox.cpp | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index f925aea6..1a2ff1c3 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2356,8 +2356,8 @@ namespace nana unsigned ext_w = scheme_ptr->ext_w; if (pos == 0 && checkable) // only before the first column (display_order=0 ?) - ext_w += 18; - header.item_width(pos, max_w + ext_w + 1 < max ? max_w + ext_w + 1 : max); + ext_w += 18; // add to geom. scheme (width of the checker) ?? + header.item_width(pos, std::min(max, max_w + ext_w + 1 )); return max_w; } @@ -2842,7 +2842,7 @@ namespace nana { facade arrow("hollow_triangle"); arrow.direction(essence_->lister.sort_reverse() ? ::nana::direction::south : ::nana::direction::north); - arrow.draw(graph, {}, colors::black, { x + static_cast(item.pixels - 16) / 2, -4, 16, 16 }, element_state::normal); + arrow.draw(graph, {}, colors::black, { x + (static_cast(item.pixels) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme? } } @@ -2892,11 +2892,11 @@ namespace nana auto bgcolor = wdptr->bgcolor(); auto fgcolor = wdptr->fgcolor(); - unsigned header_w = essence_->header.pixels(); + int header_w = essence_->header.pixels(); essence_->graph->palette(false, bgcolor); - if(header_w - essence_->scroll.offset_x < rect.width) - essence_->graph->rectangle(rectangle{ point(rect.x + static_cast(header_w)-essence_->scroll.offset_x, rect.y), - size(static_cast(rect.width) + essence_->scroll.offset_x - static_cast(header_w), rect.height) }, + if( header_w - essence_->scroll.offset_x < static_cast(rect.width) ) + essence_->graph->rectangle(rectangle{ point(rect.x + header_w -essence_->scroll.offset_x, rect.y), + size(static_cast(rect.width) + essence_->scroll.offset_x - header_w , rect.height) }, true); es_lister & lister = essence_->lister; @@ -3040,12 +3040,12 @@ namespace nana /// Draws an item void _m_draw_item(const category_t& cat, const index_pair& item_pos, - const int x, - const int y, - const int txtoff, + const int x, ///< left coordinate ? + const int y, ///< top coordinate + const int txtoff, ///< below y to print the text unsigned width, const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn - const std::vector& seqs, + const std::vector& seqs, ///< columns to print nana::color bgcolor, nana::color fgcolor, item_state state @@ -3069,11 +3069,11 @@ namespace nana bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } - unsigned show_w = width - essence_->scroll.offset_x; - if(show_w >= content_r.width) show_w = content_r.width; + unsigned show_w = std::min(content_r.width, width - essence_->scroll.offset_x); auto graph = essence_->graph; - //draw the background + + //draw the background for the whole item graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->scheme_ptr->item_height }, true, bgcolor); int item_xpos = x; @@ -3094,7 +3094,7 @@ namespace nana { if (essence_->checkable) { - content_pos += 18; + content_pos += 18; // checker width, geom scheme? element_state estate = element_state::normal; if (essence_->pointer_where.first == parts::checker) @@ -3120,17 +3120,17 @@ namespace nana if (item.img) { nana::rectangle img_r(item.img_show_size); - img_r.x = content_pos + item_xpos + static_cast(16 - item.img_show_size.width) / 2; - img_r.y = y + static_cast(essence_->scheme_ptr->item_height - item.img_show_size.height) / 2; + img_r.x = content_pos + item_xpos + (16 - static_cast(item.img_show_size.width)) / 2; // center in 16 - geom scheme? + img_r.y = y + (static_cast(essence_->scheme_ptr->item_height) - static_cast(item.img_show_size.height)) / 2; // center item.img.stretch(rectangle{ item.img.size() }, *graph, img_r); } - content_pos += 18; + content_pos += 18; // image width, geom scheme? } } bool draw_column = true; - if (static_cast(content_pos) < header.pixels) + if ( content_pos < static_cast(header.pixels)) // we have room { auto inline_wdg = _m_get_inline_pane(cat, column_pos); if (inline_wdg) From ec2396f3cd33e60ad704f70d65ba7287af2eea81 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:23:50 +0200 Subject: [PATCH 124/309] use essence_->scheme_ptr->ext_w; before text --- source/gui/widgets/listbox.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 1a2ff1c3..6bcdefca 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2836,7 +2836,7 @@ namespace nana } graph.gradual_rectangle({ x, y, item.pixels, height }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true); - graph.string({ x + 5, txtop }, item.text, fgcolor); + graph.string({ x + static_cast(essence_->scheme_ptr->ext_w), txtop }, item.text, fgcolor); if(item.index == essence_->lister.sort_index()) { @@ -3085,9 +3085,9 @@ namespace nana const auto & header = essence_->header.column(column_pos); // deduce the corresponding header which is in a kind of dislay order auto it_bgcolor = bgcolor; - if (header.pixels > 5) + if (header.pixels > essence_->scheme_ptr->ext_w ) { - int content_pos = 5; + int content_pos = essence_->scheme_ptr->ext_w; //Draw the image in the 1st column in display order if (0 == display_order) From 42e6d309c8a6a6f239f939bd5e3f5b31a70a95fc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:25:53 +0200 Subject: [PATCH 125/309] FIX a drawing defect and code review --- source/gui/widgets/listbox.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 6bcdefca..8c802110 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3076,8 +3076,8 @@ namespace nana //draw the background for the whole item graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->scheme_ptr->item_height }, true, bgcolor); - int item_xpos = x; - unsigned extreme_text = x; + int item_xpos = x; + int extreme_text = x; for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed { @@ -3212,23 +3212,25 @@ namespace nana { graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text, cell_txtcolor); // draw full text of the cell index (column) - if (static_cast(ts.width) > static_cast(header.pixels) - (content_pos + item_xpos)) // it was an excess + int item_right = item_xpos + static_cast(header.pixels); + int text_right = item_xpos + content_pos + static_cast(ts.width); + int excess = text_right - item_right ; + if (excess > 0) // it was an excess { //The text is painted over the next subitem // here beging the ... - int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->scheme_ptr->suspension_width); + int xpos = item_right - static_cast(essence_->scheme_ptr->suspension_width); // litter rect with the item bg end ... - graph->rectangle(rectangle{ xpos, y + 2, essence_->scheme_ptr->suspension_width, essence_->scheme_ptr->item_height - 4 }, true, it_bgcolor); - graph->string(point{ xpos, y + 2 }, L"..."); + graph->rectangle(rectangle{ xpos, y /*+ 2*/, essence_->scheme_ptr->suspension_width, essence_->scheme_ptr->item_height /*- 4*/ }, true, it_bgcolor); + graph->string(point{ xpos, y /*+ 2*/ }, L"..."); //Erase the part that over the next subitem only if the right of column is less than right of listbox - if (item_xpos + content_pos < content_r.right() - static_cast(header.pixels)) + if (item_right < content_r.right() ) { graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over - graph->rectangle(rectangle{ item_xpos + static_cast(header.pixels), y + 2, - ts.width + static_cast(content_pos)-header.pixels, essence_->scheme_ptr->item_height - 4 }, true); + graph->rectangle(rectangle( item_right, y /*+ 2*/, excess, essence_->scheme_ptr->item_height /*- 4*/ ), true); } - extreme_text = (std::max)(extreme_text, item_xpos + content_pos + ts.width); + extreme_text = std::max(extreme_text, text_right); } } } @@ -3238,9 +3240,9 @@ namespace nana } item_xpos += static_cast(header.pixels); - if (display_order + 1 >= seqs.size() && static_cast(extreme_text) > item_xpos) + if (display_order + 1 >= seqs.size() && extreme_text > item_xpos) { - graph->rectangle(rectangle{item_xpos , y + 2, extreme_text - item_xpos, essence_->scheme_ptr->item_height - 4}, true, item.bgcolor); + graph->rectangle(rectangle(item_xpos , y + 2, extreme_text - item_xpos, essence_->scheme_ptr->item_height - 4), true, item.bgcolor); } } @@ -3569,7 +3571,6 @@ namespace nana } } - void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) { using item_state = essence_t::item_state; From a2990b49bb4cc2e8179cf24ffbfca931e2d2e3da Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:47:23 +0200 Subject: [PATCH 126/309] reset defaults and debug --- include/nana/gui/widgets/listbox.hpp | 12 +++---- source/gui/widgets/listbox.cpp | 50 ++++++++++++++-------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index c1ff7ef4..422c0bcc 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -532,14 +532,14 @@ namespace nana unsigned min_header_width{ 20 }; ///< def=20 . non counting suspension_width unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") unsigned ext_w { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 - unsigned header_height { 20 }; ///< def=25 . header height header_size + unsigned header_height { 25 }; ///< def=25 . header height header_size unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font - unsigned item_height_ex { 2 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex - unsigned item_height { 16 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex - unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 - unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 + unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex + unsigned item_height { 24 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex + unsigned header_mouse_spliter_area_before{ 2 }; ///< def=2. But 4 is better... IMO + unsigned header_mouse_spliter_area_after { 3 }; ///< def=3. But 4 is better... - void debug_print(const std::string &msg); + //void debug_print(const std::string &msg); }; } diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8c802110..bbda3c47 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -32,29 +32,29 @@ namespace nana { - void debug(const std::string &msg, const rectangle&r) - { - std::cerr <<"\n" <scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); - essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); + //essence_->scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); + //essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); - essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); + //essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); essence_->graph = &graph; typeface_changed(graph); @@ -3374,17 +3374,17 @@ namespace nana nana::rectangle r; - essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); + //essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); if (essence_->header.visible() && essence_->rect_header(r)) drawer_header_->draw(r); - debug("Header: ", r); + //debug("Header: ", r); if (essence_->rect_lister(r)) drawer_lister_->draw(r); - debug("Lister: ", r); + //debug("Lister: ", r); _m_draw_border(); } From b063ce53fb68ff8a50dc8f23e9a6d529b2a80ce2 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 29 Mar 2016 00:08:43 +0800 Subject: [PATCH 127/309] fix bug that ignored API::update_window in drawer event. --- source/gui/detail/window_layout.cpp | 4 ++-- source/gui/detail/window_manager.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index f44be0a6..cc61cdc8 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -1,7 +1,7 @@ /* * Window Layout Implementation * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -24,7 +24,7 @@ namespace nana //class window_layout void window_layout::paint(core_window_t* wd, bool is_redraw, bool is_child_refreshed) { - if (wd->flags.refreshing) + if (is_redraw && wd->flags.refreshing) return; if (nullptr == wd->effect.bground) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index fcb7fe6e..fa81d30d 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -1,7 +1,7 @@ /* * Window Manager Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -810,6 +810,12 @@ namespace detail this->map(wd, forced, update_area); return true; } + else if (forced) + { + window_layer::paint(wd, false, false); + this->map(wd, true, update_area); + return true; + } } else if (redraw) window_layer::paint(wd, true, false); From 40d4bb4314267fe81254d1592d73875af5947ffb Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 29 Mar 2016 00:14:07 +0800 Subject: [PATCH 128/309] improve date_chooser add keyboard support add date_changed event --- include/nana/gui/widgets/date_chooser.hpp | 89 +- source/gui/widgets/date_chooser.cpp | 1244 +++++++++++++-------- 2 files changed, 794 insertions(+), 539 deletions(-) diff --git a/include/nana/gui/widgets/date_chooser.hpp b/include/nana/gui/widgets/date_chooser.hpp index a4e685e1..262a7a3b 100644 --- a/include/nana/gui/widgets/date_chooser.hpp +++ b/include/nana/gui/widgets/date_chooser.hpp @@ -1,7 +1,7 @@ /** * A date chooser Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -18,80 +18,47 @@ namespace nana { + class date_chooser; + + struct arg_datechooser + : public event_arg + { + date_chooser * const widget; + + arg_datechooser(date_chooser* wdg) + : widget(wdg) + {} + }; + namespace drawerbase { namespace date_chooser { + struct date_chooser_events + : public general_events + { + + basic_event date_changed; + }; + class trigger : public drawer_trigger { + class model; public: static const int topbar_height = 34; static const int border_size = 3; - enum class transform_action{none, to_left, to_right, to_enter, to_leave}; - enum class where{none, left_button, right_button, topbar, textarea}; - enum class page{date, month}; - - struct drawing_basis - { - nana::point refpos; - double line_s; - double row_s; - }; - trigger(); - bool chose() const; - nana::date read() const; - void week_name(unsigned index, const std::string&); - private: - where _m_pos_where(graph_reference, const ::nana::point& pos); - void _m_draw_topbar(graph_reference); - void _m_make_drawing_basis(drawing_basis&, graph_reference, const nana::point& refpos); - void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, const ::std::string&, bool primary, bool sel); - void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, int number, bool primary, bool sel); - void _m_draw_ex_days(drawing_basis &, graph_reference, int begx, int begy, bool before); - void _m_draw_days(const nana::point& refpos, graph_reference); - void _m_draw_months(const nana::point& refpos, graph_reference); - bool _m_get_trace(point, int & res); - void _m_perf_transform(transform_action tfid, graph_reference, graph_reference dirtybuf, graph_reference newbuf, const nana::point& refpos); + ~trigger(); + model* get_model() const; private: void refresh(graph_reference) override; - void attached(widget_reference, graph_reference) override; void mouse_move(graph_reference, const arg_mouse&) override; void mouse_leave(graph_reference, const arg_mouse&) override; void mouse_up(graph_reference, const arg_mouse&) override; + void key_press(graph_reference, const arg_keyboard&) override; private: - ::std::string weekstr_[7]; - - widget * widget_; - - bool chose_; - page page_; - where pos_; - nana::point trace_pos_; - - drawing_basis dbasis_; - - struct - { - int year; - int month; - int day; - }chdate_; - - struct - { - int year; - int month; - }chmonth_; - - struct color_tag - { - ::nana::color highlight; - ::nana::color selected; - ::nana::color normal; - ::nana::color bgcolor; - }color_; + model * model_; }; }//end namespace date_chooser @@ -100,18 +67,16 @@ namespace nana /// \see nana::date class date_chooser - : public widget_object + : public widget_object { public: date_chooser(); date_chooser(window, bool visible); - date_chooser(window, const ::std::string& text, bool visible = true); - date_chooser(window, const char* text, bool visible = true); date_chooser(window, const nana::rectangle& r = rectangle(), bool visible = true); bool chose() const; nana::date read() const; - void weekstr(unsigned index, const ::std::string&);///(delta * i); + dr.x = refpos.x + off_x; + dr.width = dirtybuf.width() - off_x; + + graph.bitblt(dr, dirtybuf); + + nr.width = off_x; + graph.bitblt(nr, newbuf, nana::point(static_cast(dr.width), 0)); + + API::update_window(window_handle); + nana::system::sleep(sleep_time); + } + } + else if (tfid == transform_action::to_left) + { + double delta = dirtybuf.width() / double(count); + nana::rectangle dr(refpos.x, refpos.y, 0, dirtybuf.height()); + nana::rectangle nr(0, refpos.y, 0, newbuf.height()); + + for (int i = 1; i < count; ++i) + { + int off_x = static_cast(delta * i); + dr.width = dirtybuf.width() - off_x; + + graph.bitblt(dr, dirtybuf, nana::point(off_x, 0)); + + nr.x = refpos.x + static_cast(dr.width); + nr.width = off_x; + graph.bitblt(nr, newbuf); + + API::update_window(window_handle); + nana::system::sleep(sleep_time); + } + } + else if (tfid == transform_action::to_leave) + { + nana::paint::graphics dzbuf(newbuf.size()); + nana::paint::graphics nzbuf(newbuf.size()); + + nana::rectangle r; + for (int i = 1; i < count; ++i) + { + r.width = static_cast(newbuf.width() - delta * i); + r.height = static_cast(newbuf.height() - delta_h * i); + r.x = static_cast(newbuf.width() - r.width) / 2; + r.y = static_cast(newbuf.height() - r.height) / 2; + + dzbuf.rectangle(true, colors::white); + dirtybuf.stretch(dzbuf, r); + + r.width = static_cast(newbuf.width() + delta * (count - i)); + r.height = static_cast(newbuf.height() + delta_h * (count - i)); + r.x = static_cast(newbuf.width() - r.width) / 2; + r.y = static_cast(newbuf.height() - r.height) / 2; + newbuf.stretch(nzbuf, r); + + nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i)); + graph.bitblt(refpos.x, refpos.y, dzbuf); + + API::update_window(window_handle); + nana::system::sleep(sleep_time); + } + } + else if (tfid == transform_action::to_enter) + { + nana::paint::graphics dzbuf(newbuf.size()); + nana::paint::graphics nzbuf(newbuf.size()); + + nana::rectangle r; + for (int i = 1; i < count; ++i) + { + r.width = static_cast(newbuf.width() + delta * i); + r.height = static_cast(newbuf.height() + delta_h * i); + r.x = static_cast(newbuf.width() - r.width) / 2; + r.y = static_cast(newbuf.height() - r.height) / 2; + dirtybuf.stretch(dzbuf, r); + + r.width = static_cast(newbuf.width() - delta * (count - i)); + r.height = static_cast(newbuf.height() - delta_h * (count - i)); + r.x = static_cast(newbuf.width() - r.width) / 2; + r.y = static_cast(newbuf.height() - r.height) / 2; + nzbuf.rectangle(true, colors::white); + newbuf.stretch(nzbuf, r); + + nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i)); + graph.bitblt(refpos.x, refpos.y, dzbuf); + + API::update_window(window_handle); + nana::system::sleep(sleep_time); + } + } + + graph.bitblt(nana::rectangle(refpos, newbuf.size()), newbuf); + } + + + class trigger::model + { + friend class trigger; + public: + struct view_month_rep + { + int year; + int month; + }; + + enum class where + { + none, + left_button, + right_button, + topbar, + textarea + }; + + enum class page_mode + { + date, + month + }; + + struct drawing_basis + { + nana::point refpos; + double line_s; + double row_s; + }; + + model() + { + const std::string ws[] = { "S", "M", "T", "W", "T", "F", "S" }; + for (int i = 0; i < 7; ++i) + weekstr_[i] = ws[i]; nana::date d; - chdate_.year = chmonth_.year = d.read().year; - chdate_.month = chmonth_.month = d.read().month; - chdate_.day = d.read().day; - - color_.selected = { 0x2F, 0x36, 0x99 }; - color_.highlight = { 0x4D, 0x56, 0xC8 }; - color_.normal = colors::black; - color_.bgcolor = { 0x88, 0xC4, 0xFF }; + date_.year = view_month_.year = d.read().year; + date_.month = view_month_.month = d.read().month; + date_.day = d.read().day; } - bool trigger::chose() const + void move(bool forward, graph_reference graph, window window_handle) { - return chose_; - } - - nana::date trigger::read() const - { - return nana::date(chdate_.year, chdate_.month, chdate_.day); - } - - void trigger::week_name(unsigned index, const std::string& str) - { - throw_not_utf8(str); - if(index < 7) - this->weekstr_[index] = str; - } - - trigger::where trigger::_m_pos_where(graph_reference graph, const ::nana::point& pos) - { - int xend = static_cast(graph.width()) - 1; - int yend = static_cast(graph.height()) - 1; - if(0 < pos.y && pos.y < static_cast(topbar_height)) + if (page_mode::date == page) { - if(static_cast(border_size) < pos.x && pos.x < xend) + step_view_month(forward); + + } + else + { + if (forward) + view_month_.year++; + else + view_month_.year--; + } + + perf_transform(graph, window_handle, (forward ? transform_action::to_left : transform_action::to_right)); + } + + void enter(graph_reference graph, window window_handle) + { + transform_action tfid; + + if (model::page_mode::date == page) + { + page = model::page_mode::month; + tfid = transform_action::to_leave; + + if ((!trace_.is_by_mouse) && (date_.year != view_month_.year)) { - if(pos.x < border_size + 16) + trace_.logic_pos.x = 0; + trace_.logic_pos.y = 0; + } + } + else + { + page = model::page_mode::date; + tfid = transform_action::to_enter; + + if (!trace_.is_by_mouse) + { + if ((date_.year != view_month_.year) || (date_.month != view_month_.month)) + { + trace_.logic_pos.x = 0; + trace_.logic_pos.y = 1; + } + } + } + + perf_transform(graph, window_handle, tfid); + } + + bool respond_key(graph_reference graph, const arg_keyboard& arg, bool& redrawn) + { + redrawn = false; + if (trace_.empty_logic_pos()) + return false; + + unsigned right = 7; + unsigned top = 1; + unsigned bottom = 7; + if (page_mode::month == page) + { + right = 4; + top = 0; + bottom = 3; + } + + switch (arg.key) + { + case keyboard::os_arrow_left: + if (trace_.logic_pos.x > 0) + { + --trace_.logic_pos.x; + } + else if (trace_.logic_pos.y > top) + { + trace_.logic_pos.x = right - 1; + --trace_.logic_pos.y; + } + else + { + move(false, graph, arg.window_handle); + redrawn = true; + } + break; + case keyboard::os_arrow_right: + ++trace_.logic_pos.x; + if (trace_.logic_pos.x == right) + { + if (trace_.logic_pos.y + 1 < bottom) + { + ++trace_.logic_pos.y; + trace_.logic_pos.x = 0; + } + else + { + trace_.logic_pos.x = right - 1; + move(true, graph, arg.window_handle); + redrawn = true; + } + } + + break; + case keyboard::os_arrow_up: + if (trace_.logic_pos.y == top) + trace_.logic_pos.y = bottom - 1; + else + --trace_.logic_pos.y; + break; + case keyboard::os_arrow_down: + if (trace_.logic_pos.y + 1 == bottom) + trace_.logic_pos.y = top; + else + ++trace_.logic_pos.y; + break; + case keyboard::enter: + if (page_mode::month == page) + { + int n = get_trace_logic_pos(); + view_month_.month = n; + this->enter(graph, arg.window_handle); + redrawn = true; + } + else + { + if (!trace_.empty_logic_pos()) + { + auto value = get_trace_logic_pos(); + + if (0 < value && value <= static_cast(::nana::date::month_days(view_month_.year, view_month_.month))) + this->choose(arg.window_handle, value); + else + { + move(value > 0, graph, arg.window_handle); + redrawn = true; + } + } + } + break; + case keyboard::escape: + if (page_mode::date == page) + { + enter(graph, arg.window_handle); + redrawn = true; + } + break; + default: + return false; + } + + trace_.is_by_mouse = false; + return true; + } + + ::nana::date read() const + { + return{date_.year, date_.month, date_.day}; + } + + void weekname(std::size_t pos, std::string&& name) + { + if (pos < 7) + weekstr_[pos] = std::move(name); + } + + where pos_where(const ::nana::size& area, const ::nana::point& pos) + { + int pos_right = static_cast(area.width) - 1; + int pos_bottom = static_cast(area.height) - 1; + if (0 < pos.y && pos.y < static_cast(topbar_height)) + { + if (static_cast(border_size) < pos.x && pos.x < pos_right) + { + if (pos.x < border_size + 16) return where::left_button; - else if(xend - border_size - 16 < pos.x) + else if (pos_right - border_size - 16 < pos.x) return where::right_button; return where::topbar; } } - else if(topbar_height < pos.y && pos.y < yend) + else if (topbar_height < pos.y && pos.y < pos_bottom) { - trace_pos_ = pos; + trace_.ms_pos = pos; + trace_.clear_logic_pos(); + trace_.is_by_mouse = true; + return where::textarea; } return where::none; } - void trigger::_m_draw_topbar(graph_reference graph) + bool set_where(where pos) { - ::nana::color arrow_bgcolor; - ::nana::rectangle arrow_r{ static_cast(border_size), (topbar_height - 16) / 2 + 1, 16, 16 }; - facade arrow("solid_triangle"); - arrow.direction(::nana::direction::west); - arrow.draw(graph, arrow_bgcolor, (pos_ == where::left_button ? color_.highlight : color_.normal), arrow_r, element_state::normal); + if (pos == pos_) + return false; - arrow_r.x = static_cast(graph.width()) - static_cast(border_size + 17); - arrow.direction(::nana::direction::east); - arrow.draw(graph, arrow_bgcolor, (pos_ == where::right_button ? color_.highlight : color_.normal), arrow_r, element_state::normal); - - const char * monthstr[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - - if(graph.width() > 32 + border_size * 2) + if (pos != where::textarea) { - std::string str; - if(page_ == page::date) - { - str = ::nana::internationalization()(monthstr[chmonth_.month - 1]); - str += " "; - } - str += std::to_string(chmonth_.year); - - nana::size txt_s = graph.text_extent_size(str); - - int top = (topbar_height - static_cast(txt_s.height)) / 2 + 1; - - int xpos = static_cast(graph.width() - txt_s.width) / 2; - if(xpos < border_size + 16) xpos = 16 + border_size + 1; - - graph.string({ xpos, top }, str, (pos_ == where::topbar ? color_.highlight : color_.normal)); + trace_.clear_logic_pos(); + trace_.is_by_mouse = false; } + + pos_ = pos; + return true; } - void trigger::_m_make_drawing_basis(drawing_basis& dbasis, graph_reference graph, const nana::point& refpos) + int get_trace_logic_pos() const { - dbasis.refpos = refpos; - const unsigned width = graph.width(); - const unsigned height = graph.height(); + if (trace_.empty_logic_pos()) + return 0; - if(page::date == page_) - { - dbasis.line_s = height / 7.0; - dbasis.row_s = width / 7.0; - } - else if(page::month == page_) - { - dbasis.line_s = height / 3.0; - dbasis.row_s = width / 4.0; - } + int lines = 7, rows = 7; //for page::date - dbasis_ = dbasis; - } - - void trigger::_m_draw_pos(drawing_basis & dbasis, graph_reference graph, int x, int y, const std::string& str_utf8, bool primary, bool sel) - { - nana::rectangle r(static_cast(x * dbasis.row_s), static_cast(y * dbasis.line_s), - static_cast(dbasis.row_s), static_cast(dbasis.line_s)); - - auto color = color_.normal; - auto tpos = trace_pos_ - dbasis.refpos; - - if((pos_ == where::textarea) - && (r.x <= tpos.x) - && (tpos.x < r.x + static_cast(r.width)) - && (r.y <= tpos.y) - && (tpos.y < r.y + static_cast(r.height))) - { - if((page_ != page::date) || y) - { - color = color_.highlight; - graph.rectangle(r, true, color_.bgcolor); - } - } - - if(sel) - { - color = color_.highlight; - graph.rectangle(r, true, color_.bgcolor); - graph.rectangle(r, false, color_.selected); - } - - if(false == primary) - color = { 0xB0, 0xB0, 0xB0 }; - - auto txt_s = graph.text_extent_size(str_utf8); - graph.string({ r.x + static_cast(r.width - txt_s.width) / 2, r.y + static_cast(r.height - txt_s.height) / 2 }, str_utf8, color); - } - - void trigger::_m_draw_pos(drawing_basis & dbasis, graph_reference graph, int x, int y, int number, bool primary, bool sel) - { - _m_draw_pos(dbasis, graph, x, y, std::to_string(number), primary, sel); - } - - void trigger::_m_draw_ex_days(drawing_basis & dbasis, graph_reference graph, int begx, int begy, bool before) - { - int x = nana::date::day_of_week(chmonth_.year, chmonth_.month, 1); - int y = (x ? 1 : 2); - - if(before) - { - int year = chmonth_.year; - int month = chmonth_.month - 1; - if(month == 0) - { - --year; - month = 12; - } - bool same = (chdate_.year == year && chdate_.month == month); - int days = nana::date::month_days(year, month); - - int size = (x ? x : 7); - int beg = days - size + 1; - - for(int i = 0; i < size; ++i) - { - this->_m_draw_pos(dbasis, graph, i, 1, beg + i, false, same && (chdate_.day == beg + i)); - } - } - else - { - int year = chmonth_.year; - int month = chmonth_.month + 1; - if(month == 13) - { - ++year; - month = 1; - } - bool same = (chdate_.year == year && chdate_.month == month); - - int day = 1; - x = begx; - for(y = begy; y < 7; ++y) - { - for(; x < 7; ++x) - { - _m_draw_pos(dbasis, graph, x, y, day, false, same && (chdate_.day == day)); - ++day; - } - x = 0; - } - } - } - - void trigger::_m_draw_days(const nana::point& refpos, graph_reference graph) - { - drawing_basis dbasis; - _m_make_drawing_basis(dbasis, graph, refpos); - - for(int i = 0; i < 7; ++i) - _m_draw_pos(dbasis, graph, i, 0, weekstr_[i], true, false); - - int day = 1; - int x = nana::date::day_of_week(chmonth_.year, chmonth_.month, 1); - int y = (x ? 1 : 2); - - //draw the days that before the first day of this month - _m_draw_ex_days(dbasis, graph, 0, 0, true); - // - int days = static_cast(nana::date::month_days(chmonth_.year, chmonth_.month)); - - bool same = (chdate_.year == chmonth_.year && chdate_.month == chmonth_.month); - while(day <= days) - { - for(; x < 7; ++x) - { - _m_draw_pos(dbasis, graph, x, y, day, true, (same && chdate_.day == day)); - if(++day > days) break; - } - if(day > days) break; - y++; - x = 0; - } - - ++x; - if(x >= 7) - { - x = 0; - ++y; - } - - _m_draw_ex_days(dbasis, graph, x, y, false); - } - - void trigger::_m_draw_months(const nana::point& refpos, graph_reference graph) - { - drawing_basis dbasis; - _m_make_drawing_basis(dbasis, graph, refpos); - - const char * monthstr[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - ::nana::internationalization i18n; - for(int y = 0; y < 3; ++y) - for(int x = 0; x < 4; ++x) - { - int index = x + y * 4; - _m_draw_pos(dbasis, graph, x, y, i18n(monthstr[index]), true, (chmonth_.year == chdate_.year) && (index + 1 == chdate_.month)); - } - } - - bool trigger::_m_get_trace(point pos, int & res) - { - pos -= dbasis_.refpos; - - int lines = 7, rows = 7; //defaultly for page::date - - if(page_ == page::month) + if (page_mode::month == page) { lines = 3; rows = 4; } - int width = static_cast(dbasis_.row_s * rows); - int height = static_cast(dbasis_.line_s * lines); - - if(0 <= pos.x && pos.x < width && 0 <= pos.y && pos.y < height) + int n = trace_.logic_pos.y * rows + trace_.logic_pos.x + 1; + if (page_mode::date == page) { - pos.x = static_cast(pos.x / dbasis_.row_s); - pos.y = static_cast(pos.y / dbasis_.line_s); + if (n < 8) return false; //Here is week title bar + int dw = nana::date::day_of_week(view_month_.year, view_month_.month, 1); + n -= (dw ? dw + 7 : 14); + } + return n; + } + + bool get_trace(point pos, int & res) const + { + pos -= dwbasis_.refpos; + + int lines = 7, rows = 7; //for page::date + + if (page_mode::month == page) + { + lines = 3; + rows = 4; + } + + int width = static_cast(dwbasis_.row_s * rows); + int height = static_cast(dwbasis_.line_s * lines); + + if (0 <= pos.x && pos.x < width && 0 <= pos.y && pos.y < height) + { + pos.x = static_cast(pos.x / dwbasis_.row_s); + pos.y = static_cast(pos.y / dwbasis_.line_s); int n = pos.y * rows + pos.x + 1; - if(page_ == page::date) + if (page_mode::date == page) { - if(n < 8) return false; //Here is week title bar - int dw = nana::date::day_of_week(chmonth_.year, chmonth_.month, 1); + if (n < 8) return false; //Here is week title bar + int dw = nana::date::day_of_week(view_month_.year, view_month_.month, 1); n -= (dw ? dw + 7 : 14); } res = n; @@ -313,291 +439,467 @@ namespace nana return false; } - void trigger::_m_perf_transform(transform_action tfid, graph_reference graph, graph_reference dirtybuf, graph_reference newbuf, const nana::point& refpos) + int days_of_view_month() const { - const int sleep_time = 15; - const int count = 20; - double delta = dirtybuf.width() / double(count); - double delta_h = dirtybuf.height() / double(count); - double fade = 1.0 / count; - - if(tfid == transform_action::to_right) - { - nana::rectangle dr(0, refpos.y, 0, dirtybuf.height()); - nana::rectangle nr(refpos.x, refpos.y, 0, newbuf.height()); - for(int i = 1; i < count; ++i) - { - int off_x = static_cast(delta * i); - dr.x = refpos.x + off_x; - dr.width = dirtybuf.width() - off_x; - - graph.bitblt(dr, dirtybuf); - - nr.width = off_x; - graph.bitblt(nr, newbuf, nana::point(static_cast(dr.width), 0)); - - API::update_window(*widget_); - nana::system::sleep(sleep_time); - } - } - else if(tfid == transform_action::to_left) - { - double delta = dirtybuf.width() / double(count); - nana::rectangle dr(refpos.x, refpos.y, 0, dirtybuf.height()); - nana::rectangle nr(0, refpos.y, 0, newbuf.height()); - - for(int i = 1; i < count; ++i) - { - int off_x = static_cast(delta * i); - dr.width = dirtybuf.width() - off_x; - - graph.bitblt(dr, dirtybuf, nana::point(off_x, 0)); - - nr.x = refpos.x + static_cast(dr.width); - nr.width = off_x; - graph.bitblt(nr, newbuf); - - API::update_window(*widget_); - nana::system::sleep(sleep_time); - } - } - else if(tfid == transform_action::to_leave) - { - nana::paint::graphics dzbuf(newbuf.size()); - nana::paint::graphics nzbuf(newbuf.size()); - - nana::rectangle r; - for(int i = 1; i < count; ++i) - { - r.width = static_cast(newbuf.width() - delta * i); - r.height = static_cast(newbuf.height() - delta_h * i); - r.x = static_cast(newbuf.width() - r.width) / 2; - r.y = static_cast(newbuf.height() - r.height) / 2; - - dzbuf.rectangle(true, colors::white); - dirtybuf.stretch(dzbuf, r); - - r.width = static_cast(newbuf.width() + delta * (count - i)); - r.height = static_cast(newbuf.height() + delta_h * (count - i)); - r.x = static_cast(newbuf.width() - r.width) / 2; - r.y = static_cast(newbuf.height() - r.height) / 2; - newbuf.stretch(nzbuf, r); - - nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i)); - graph.bitblt(refpos.x, refpos.y, dzbuf); - - API::update_window(*widget_); - nana::system::sleep(sleep_time); - } - } - else if(tfid == transform_action::to_enter) - { - nana::paint::graphics dzbuf(newbuf.size()); - nana::paint::graphics nzbuf(newbuf.size()); - - nana::rectangle r; - for(int i = 1; i < count; ++i) - { - r.width = static_cast(newbuf.width() + delta * i); - r.height = static_cast(newbuf.height() + delta_h * i); - r.x = static_cast(newbuf.width() - r.width) / 2; - r.y = static_cast(newbuf.height() - r.height) / 2; - dirtybuf.stretch(dzbuf, r); - - r.width = static_cast(newbuf.width() - delta * (count - i)); - r.height = static_cast(newbuf.height() - delta_h * (count - i)); - r.x = static_cast(newbuf.width() - r.width) / 2; - r.y = static_cast(newbuf.height() - r.height) / 2; - nzbuf.rectangle(true, colors::white); - newbuf.stretch(nzbuf, r); - - nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i)); - graph.bitblt(refpos.x, refpos.y, dzbuf); - - API::update_window(*widget_); - nana::system::sleep(sleep_time); - } - } - - graph.bitblt(nana::rectangle(refpos, newbuf.size()), newbuf); + return ::nana::date::month_days(view_month_.year, view_month_.month); } - void trigger::refresh(graph_reference graph) + void step_view_month(bool is_forward) + { + if (is_forward) + { + if (++view_month_.month == 13) + { + view_month_.month = 1; + ++view_month_.year; + } + } + else if (--view_month_.month == 0) + { + view_month_.month = 12; + --view_month_.year; + } + } + + view_month_rep& view_month() + { + return view_month_; + } + + + void set_view_month(int month) + { + view_month_.month = month; + } + + void choose(window window_handle, int day) + { + date_.year = view_month_.year; + date_.month = view_month_.month; + date_.day = day; + chose_ = true; + + arg_datechooser evt_arg{ static_cast(API::get_widget(window_handle)) }; + API::events(window_handle).date_changed.emit(evt_arg); + } + + bool chose() const + { + return chose_; + } + + void render(graph_reference graph) { const unsigned width = graph.width() - 2; - graph.rectangle(false, { 0xb0, 0xb0, 0xb0 }); + graph.rectangle(false, static_cast(0xb0b0b0)); graph.rectangle({ 1, 1, width, static_cast(topbar_height) }, true, colors::white); _m_draw_topbar(graph); if (graph.height() > 2 + topbar_height) { - nana::point refpos(1, static_cast(topbar_height)+1); + const ::nana::point refpos(1, static_cast(topbar_height)+1); + + _m_calc_basis(graph, refpos); nana::paint::graphics gbuf({ width, graph.height() - 2 - topbar_height }); gbuf.rectangle(true, { 0xf0, 0xf0, 0xf0 }); - switch (page_) + switch (page) { - case page::date: - _m_draw_days(refpos, gbuf); + case page_mode::date: + _m_draw_days(gbuf); break; - case page::month: - _m_draw_months(refpos, gbuf); + case page_mode::month: + _m_draw_months(gbuf); break; default: break; } - graph.bitblt(refpos.x, refpos.y, gbuf); } } - void trigger::attached(widget_reference widget, graph_reference) + void perf_transform(graph_reference graph, window window_handle, transform_action transf) { - widget_ = &widget; + nana::point refpos(1, static_cast(topbar_height)+1); + nana::rectangle r(0, 0, graph.width() - 2, graph.height() - 2 - topbar_height); + + nana::paint::graphics dirtybuf({ r.width, r.height }); + dirtybuf.bitblt(r, graph, refpos); + + render(graph); + + nana::paint::graphics gbuf({ r.width, r.height }); + gbuf.bitblt(r, graph, refpos); + + perf_transform_helper(window_handle, transf, graph, dirtybuf, gbuf, refpos); + } + private: + //renderring functions + + void _m_calc_basis(graph_reference graph, const nana::point& refpos) + { + dwbasis_.refpos = refpos; + unsigned width = graph.width() - 2; + unsigned height = graph.height() - 2; + + if (height < topbar_height) + height = 0; + else + height -= topbar_height; + + if (page_mode::date == page) + { + dwbasis_.line_s = height / 7.0; + dwbasis_.row_s = width / 7.0; + } + else if (page_mode::month == page) + { + dwbasis_.line_s = height / 3.0; + dwbasis_.row_s = width / 4.0; + } + } + + void _m_draw_topbar(graph_reference graph) + { + ::nana::color arrow_bgcolor; + ::nana::rectangle arrow_r{ static_cast(border_size), (topbar_height - 16) / 2 + 1, 16, 16 }; + facade arrow("solid_triangle"); + arrow.direction(::nana::direction::west); + arrow.draw(graph, arrow_bgcolor, (pos_ == where::left_button ? colors_.highlighted : colors_.normal), arrow_r, element_state::normal); + + arrow_r.x = static_cast(graph.width()) - static_cast(border_size + 17); + arrow.direction(::nana::direction::east); + arrow.draw(graph, arrow_bgcolor, (pos_ == where::right_button ? colors_.highlighted : colors_.normal), arrow_r, element_state::normal); + + const char * monthstr[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + + if (graph.width() > 32 + border_size * 2) + { + std::string str; + if (page_mode::date == page) + { + str = ::nana::internationalization()(monthstr[this->view_month_.month - 1]); + str += " "; + } + str += std::to_string(view_month_.year); + + nana::size txt_s = graph.text_extent_size(str); + + int top = (topbar_height - static_cast(txt_s.height)) / 2 + 1; + + int xpos = static_cast(graph.width() - txt_s.width) / 2; + if (xpos < border_size + 16) xpos = 16 + border_size + 1; + + graph.string({ xpos, top }, str, (pos_ == where::topbar ? colors_.highlighted : colors_.normal)); + } + } + + void _m_draw_pos(graph_reference graph, const upoint& logic_pos, const std::string& text_utf8, bool primary, bool sel) + { + nana::rectangle r(static_cast(logic_pos.x * dwbasis_.row_s), static_cast(logic_pos.y * dwbasis_.line_s), + static_cast(dwbasis_.row_s), static_cast(dwbasis_.line_s)); + + auto color = colors_.normal; + + if (trace_.is_by_mouse ? ((pos_ == where::textarea) && r.is_hit(trace_.ms_pos - dwbasis_.refpos)) : (trace_.logic_pos == logic_pos)) + { + if ((page != page_mode::date) || logic_pos.y) + { + color = colors_.highlighted; + graph.rectangle(r, true, colors_.bgcolor); + + if (trace_.is_by_mouse) + trace_.logic_pos = logic_pos; + } + } + + if (sel) + { + color = colors_.highlighted; + graph.rectangle(r, true, colors_.bgcolor); + graph.rectangle(r, false, colors_.selected); + + if (trace_.empty_logic_pos()) + trace_.logic_pos = logic_pos; + } + + if (false == primary) + color = { 0xB0, 0xB0, 0xB0 }; + + auto txt_s = graph.text_extent_size(text_utf8); + graph.string({ r.x + static_cast(r.width - txt_s.width) / 2, r.y + static_cast(r.height - txt_s.height) / 2 }, text_utf8, color); + } + + void _m_draw_ex_days(graph_reference graph, const upoint& begin_logic_pos, bool before) + { + int x = nana::date::day_of_week(view_month_.year, view_month_.month, 1); + int y = (x ? 1 : 2); + + int year = view_month_.year; + if (before) + { + + int month = view_month_.month - 1; + if (month == 0) + { + --year; + month = 12; + } + bool same = (date_.year == year && date_.month == month); + auto days = nana::date::month_days(year, month); + + unsigned size = (x ? x : 7); + unsigned beg = days - size + 1; + + for (upoint logic_pos{0, 1}; logic_pos.x < size; ++ logic_pos.x) + { + this->_m_draw_pos(graph, logic_pos, std::to_string(beg + logic_pos.x), false, same && (static_cast(date_.day) == beg + logic_pos.x)); + } + } + else + { + int month = view_month_.month + 1; + if (month == 13) + { + ++year; + month = 1; + } + bool same = (date_.year == year && date_.month == month); + + int day = 1; + + for (upoint logic_pos{begin_logic_pos}; logic_pos.y < 7; ++logic_pos.y) + { + for (; logic_pos.x < 7; ++logic_pos.x) + { + _m_draw_pos(graph, logic_pos, std::to_string(day), false, same && (date_.day == day)); + ++day; + } + logic_pos.x = 0; + } + } + } + + void _m_draw_days(graph_reference graph) + { + upoint logic_pos{ 0, 0 }; + for (; logic_pos.x < 7; ++logic_pos.x) + _m_draw_pos(graph, logic_pos, weekstr_[logic_pos.x], true, false); + + //draw the days that before the first day of this month + _m_draw_ex_days(graph, {}, true); + + int days = static_cast(nana::date::month_days(view_month_.year, view_month_.month)); + + bool same = (date_.year == view_month_.year && date_.month == view_month_.month); + + logic_pos.x = ::nana::date::day_of_week(view_month_.year, view_month_.month, 1); + logic_pos.y = (logic_pos.x ? 1 : 2); + + int day = 1; + while (day <= days) + { + for (; logic_pos.x < 7; ++logic_pos.x) + { + _m_draw_pos(graph, logic_pos, std::to_string(day), true, (same && date_.day == day)); + if (++day > days) break; + } + if (day > days) break; + logic_pos.y++; + logic_pos.x = 0; + } + + ++logic_pos.x; + if (logic_pos.x >= 7) + { + logic_pos.x = 0; + ++logic_pos.y; + } + + _m_draw_ex_days(graph, logic_pos, false); + } + + void _m_draw_months(graph_reference graph) + { + const char * monthstr[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + ::nana::internationalization i18n; + + for (unsigned y = 0; y < 3; ++y) + for (upoint logic_pos{0, y}; logic_pos.x < 4; ++logic_pos.x) + { + int index = logic_pos.x + logic_pos.y * 4; + _m_draw_pos(graph, logic_pos, i18n(monthstr[index]), true, (view_month_.year == date_.year) && (index + 1 == date_.month)); + } + } + private: + page_mode page{ page_mode::date }; + private: + ::std::string weekstr_[7]; + + bool chose_{ false }; //indicates whether the date is chose + where pos_{ where::none }; + + struct + { + bool is_by_mouse{ true }; + point ms_pos; //the mouse position + upoint logic_pos{ 8, 8 }; //pos(8, 8) indicates the end position. + + void clear_logic_pos() + { + logic_pos.x = logic_pos.y = 8; + } + + bool empty_logic_pos() const + { + return (logic_pos.x == 8); + } + }trace_; + + drawing_basis dwbasis_; + + struct color_rep + { + ::nana::color highlighted{ static_cast(0x4d56c8) }; + ::nana::color selected{ static_cast(0x2f3699) }; + ::nana::color normal{ colors::black }; + ::nana::color bgcolor{ static_cast(0x88c4ff) }; + }colors_; + + view_month_rep view_month_; + + struct date_mode + { + int year; + int month; + int day; + }date_; + }; + //class trigger: public drawer_trigger + + trigger::trigger() + : model_(new model) + { + } + + trigger::~trigger() + { + delete model_; + } + + auto trigger::get_model() const -> model* + { + return model_; + } + + void trigger::refresh(graph_reference graph) + { + model_->render(graph); } void trigger::mouse_move(graph_reference graph, const arg_mouse& arg) { - where pos = _m_pos_where(graph, arg.pos); - if(pos == pos_ && pos_ != where::textarea) return; - pos_ = pos; - refresh(graph); - API::lazy_refresh(); + auto pos = model_->pos_where(graph.size(), arg.pos); + if (model_->set_where(pos) || (model::where::textarea == pos)) + { + model_->render(graph); + API::lazy_refresh(); + } } void trigger::mouse_leave(graph_reference graph, const arg_mouse&) { - if(where::none == pos_) return; - pos_ = where::none; - refresh(graph); - API::lazy_refresh(); + if (model_->set_where(model::where::none)) + { + model_->render(graph); + API::lazy_refresh(); + } } void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) { bool redraw = true; - where pos = _m_pos_where(graph, arg.pos); - transform_action tfid = transform_action::none; + auto pos = model_->pos_where(graph.size(), arg.pos); + //transform_action tfid = transform_action::none; + bool transformed = false; - if(pos == where::topbar) + if (pos == model::where::topbar) { - switch(page_) + if (model::page_mode::date == model_->page) { - case page::date: - page_ = page::month; - tfid = transform_action::to_leave; - break; - default: - redraw = false; + model_->enter(graph, arg.window_handle); + transformed = true; } + else + redraw = false; } - else if(pos == where::textarea) + else if (pos == model::where::textarea) { int ret = 0; - switch(page_) + + bool good_trace = model_->get_trace(arg.pos, ret); + + switch (model_->page) { - case page::date: - if(_m_get_trace(arg.pos, ret)) + case model::page_mode::date: + if (good_trace) { - if(ret < 1) + if (ret < 1) { - if(--chmonth_.month == 0) - { - --chmonth_.year; - chmonth_.month = 12; - } - tfid = transform_action::to_right; + model_->move(false, graph, arg.window_handle); + transformed = true; } else { - int days = nana::date::month_days(chmonth_.year, chmonth_.month); - if(ret > days) + auto days = model_->days_of_view_month(); + if (ret > days) { - if(++chmonth_.month == 13) - { - ++chmonth_.year; - chmonth_.month = 1; - } - tfid = transform_action::to_left; + model_->move(true, graph, arg.window_handle); + transformed = true; } else //Selecting a day in this month { - chdate_.year = chmonth_.year; - chdate_.month = chmonth_.month; - chdate_.day = ret; - chose_ = true; + model_->choose(arg.window_handle, ret); } } } break; - case page::month: - if(_m_get_trace(arg.pos, ret)) - chmonth_.month = ret; - page_ = page::date; - tfid = transform_action::to_enter; + case model::page_mode::month: + if (good_trace) + model_->view_month().month = ret; + + model_->enter(graph, arg.window_handle); + transformed = true; break; default: redraw = false; } } - else if(pos == where::left_button || pos == where::right_button) + else if (model::where::left_button == pos || model::where::right_button == pos) { - int end_m; - int beg_m; - int step; - if(pos == where::left_button) - { - end_m = 1; - beg_m = 12; - step = -1; - tfid = transform_action::to_right; - } - else - { - end_m = 12; - beg_m = 1; - step = 1; - tfid = transform_action::to_left; - } - switch(page_) - { - case page::date: - if(chmonth_.month == end_m) - { - chmonth_.month = beg_m; - chmonth_.year += step; - } - else - chmonth_.month += step; - break; - case page::month: - chmonth_.year += step; - break; - default: - redraw = false; - } + model_->move((model::where::right_button == pos), graph, arg.window_handle); + transformed = true; } + else + redraw = false; - if(redraw) + if (redraw) { - if(tfid != transform_action::none) - { - nana::point refpos(1, static_cast(topbar_height) + 1); - nana::rectangle r(0, 0, graph.width() - 2, graph.height() - 2 - topbar_height); + if (!transformed) + model_->render(graph); - nana::paint::graphics dirtybuf({ r.width, r.height }); - dirtybuf.bitblt(r, graph, refpos); + API::lazy_refresh(); + } + } - refresh(graph); - - nana::paint::graphics gbuf({ r.width, r.height }); - gbuf.bitblt(r, graph, refpos); - - _m_perf_transform(tfid, graph, dirtybuf, gbuf, refpos); - } - else + void trigger::key_press(graph_reference graph, const arg_keyboard& arg) + { + bool redrawn = false; + if (model_->respond_key(graph, arg, redrawn)) + { + if (!redrawn) refresh(graph); API::lazy_refresh(); @@ -616,18 +918,6 @@ namespace nana create(wd, rectangle(), visible); } - date_chooser::date_chooser(window wd, const std::string& text, bool visible) - { - throw_not_utf8(text); - create(wd, rectangle(), visible); - caption(text); - } - - date_chooser::date_chooser(window wd, const char* text, bool visible) - : date_chooser(wd, std::string(text), visible) - { - } - date_chooser::date_chooser(window wd, const rectangle& r, bool visible) { create(wd, r, visible); @@ -635,17 +925,17 @@ namespace nana bool date_chooser::chose() const { - return get_drawer_trigger().chose(); + return get_drawer_trigger().get_model()->chose(); } nana::date date_chooser::read() const { - return get_drawer_trigger().read(); + return get_drawer_trigger().get_model()->read(); } - void date_chooser::weekstr(unsigned index, const ::std::string& str) + void date_chooser::weekstr(unsigned index, ::std::string str) { - get_drawer_trigger().week_name(index, str); + get_drawer_trigger().get_model()->weekname(index, std::move(str)); API::refresh_window(*this); } //end class date_chooser From 6b1cba13570804f98d1927f6de84daa4bc7ff890 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 29 Mar 2016 01:22:34 +0800 Subject: [PATCH 129/309] enable/disable tab when textbox is switched between single/multi-line --- source/gui/widgets/textbox.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index b6d678af..3567d87e 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -392,8 +392,12 @@ namespace drawerbase { { internal_scope_guard lock; auto editor = get_drawer_trigger().editor(); - if(editor && editor->multi_lines(ml)) - API::update_window(handle()); + if (editor && editor->multi_lines(ml)) + { + auto wd = handle(); + API::eat_tabstop(wd, ml); //textbox handles the Tab pressing when it is multi-line. + API::update_window(wd); + } return *this; } From ca1e7810c7a16b4ebf1f3cd392b3738b64cf2f37 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 31 Mar 2016 20:17:53 +0800 Subject: [PATCH 130/309] fix label escape character issue --- .../widgets/skeletons/text_token_stream.hpp | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index c5d5a5e7..fea7cbf8 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -194,13 +194,24 @@ namespace nana{ namespace widgets{ namespace skeletons return token::tag_begin; } + //Escape - if(ch == '\\') + if(this->format_enabled_ && (ch == '\\')) { if(iptr_ + 1 < endptr_) { ch = *(iptr_ + 1); - iptr_ += 2; + + if ('<' == ch || '>' == ch) //two characters need to be escaped. + { + iptr_ += 2; + } + else + { + //ignore escape + ch = '\\'; + iptr_++; + } } else { @@ -208,8 +219,8 @@ namespace nana{ namespace widgets{ namespace skeletons return token::eof; } } - - ++iptr_; + else + ++iptr_; idstr_.clear(); idstr_.append(1, ch); @@ -277,6 +288,8 @@ namespace nana{ namespace widgets{ namespace skeletons return token::eof; } + + if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || '_' == ch) { --iptr_; From 8da9520d01bb6fdbc196a532a5503b1d3869582e Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 31 Mar 2016 23:34:15 +0200 Subject: [PATCH 131/309] only central repaint? --- source/gui/widgets/listbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index bbda3c47..33232611 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3242,7 +3242,7 @@ namespace nana item_xpos += static_cast(header.pixels); if (display_order + 1 >= seqs.size() && extreme_text > item_xpos) { - graph->rectangle(rectangle(item_xpos , y + 2, extreme_text - item_xpos, essence_->scheme_ptr->item_height - 4), true, item.bgcolor); + graph->rectangle(rectangle(item_xpos , y /*+ 2*/, extreme_text - item_xpos, essence_->scheme_ptr->item_height /*- 4*/), true, item.bgcolor); } } From 5f870bcf6943297131d5483f128618604847e913 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 8 Apr 2016 23:10:00 +0800 Subject: [PATCH 132/309] enhance support for multi-threading environment --- include/nana/detail/win32/platform_spec.hpp | 13 +- .../nana/gui/detail/internal_scope_guard.hpp | 14 +- .../gui/detail/native_window_interface.hpp | 5 +- include/nana/gui/programming_interface.hpp | 2 + include/nana/pat/cloneable.hpp | 7 - source/gui/detail/bedrock_pi.cpp | 14 +- source/gui/detail/bedrock_windows.cpp | 8 ++ source/gui/detail/native_window_interface.cpp | 65 +++++++-- source/gui/place_parts.hpp | 131 ++++++++++-------- source/gui/programming_interface.cpp | 5 + 10 files changed, 182 insertions(+), 82 deletions(-) diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index dba6062a..179204e5 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -1,7 +1,7 @@ /* * Platform Specification Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -25,6 +25,7 @@ #include #include #include +#include namespace nana { @@ -63,9 +64,15 @@ namespace detail bool forced; }; + struct arg_affinity_execute + { + const std::function * function_ptr; + }; + enum { tray = 0x501, + async_activate, async_set_focus, map_thread_root_buffer, @@ -74,6 +81,10 @@ namespace detail operate_caret, //wParam: 1=Destroy, 2=SetPos remote_thread_set_window_pos, remote_thread_set_window_text, + + //Execute a function in a thread with is associated with a specified native window + affinity_execute, + user, }; }; diff --git a/include/nana/gui/detail/internal_scope_guard.hpp b/include/nana/gui/detail/internal_scope_guard.hpp index c4bdaaf6..6ad8ae80 100644 --- a/include/nana/gui/detail/internal_scope_guard.hpp +++ b/include/nana/gui/detail/internal_scope_guard.hpp @@ -1,7 +1,7 @@ /* * Forward Declaration of Internal Scope Guard * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -26,6 +26,18 @@ namespace nana internal_scope_guard(); ~internal_scope_guard(); }; + + class internal_revert_guard + { + internal_revert_guard(const internal_revert_guard&) = delete; + internal_revert_guard(internal_revert_guard&&) = delete; + + internal_revert_guard& operator=(const internal_revert_guard&) = delete; + internal_revert_guard& operator=(internal_revert_guard&&) = delete; + public: + internal_revert_guard(); + ~internal_revert_guard(); + }; } #endif \ No newline at end of file diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index aade67a5..737423bf 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -1,7 +1,7 @@ /* * Platform Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -36,6 +36,9 @@ namespace detail using native_string_type = ::nana::detail::native_string_type; + //Execute a function in a thread which is associated with the specified native window. + static void affinity_execute(native_window_type, const std::function&); + static nana::size primary_monitor_size(); static rectangle screen_area_from_point(const point&); static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&); diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index db8ffc1c..ffb5a5dd 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -60,6 +60,8 @@ namespace API //@brief: The interfaces defined in namespace dev are used for developing the nana.gui namespace dev { + void affinity_execute(window window_handle, const std::function&); + bool set_events(window, const std::shared_ptr&); template diff --git a/include/nana/pat/cloneable.hpp b/include/nana/pat/cloneable.hpp index 7cff2638..c6f5d1c9 100644 --- a/include/nana/pat/cloneable.hpp +++ b/include/nana/pat/cloneable.hpp @@ -97,13 +97,6 @@ namespace nana{ namespace pat{ typedef int inner_bool::* operator_bool_t; - /* - template - struct member_enabled //deprecated - : public std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int> - {}; - */ - template using member_enabled = std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int>; public: diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 830887ea..f4716435 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -1,7 +1,7 @@ /* * A Bedrock Platform-Independent Implementation * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -36,6 +36,18 @@ namespace nana detail::bedrock::instance().wd_manager().internal_lock().unlock(); } //end class internal_scope_guard + + //class internal_revert_guard + internal_revert_guard::internal_revert_guard() + { + detail::bedrock::instance().wd_manager().internal_lock().revert(); + } + + internal_revert_guard::~internal_revert_guard() + { + detail::bedrock::instance().wd_manager().internal_lock().forward(); + } + //end class internal_revert_guard //class event_arg void event_arg::stop_propagation() const diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index bf1b5c28..7bd5d505 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -669,6 +669,14 @@ namespace detail case nana::detail::messages::tray: notifications_window_proc(wd, wParam, lParam); return true; + case nana::detail::messages::affinity_execute: + if (wParam) + { + auto arg = reinterpret_cast(wParam); + if (arg->function_ptr) + (*arg->function_ptr)(); + } + break; default: break; } diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 258f3d1c..b21eb270 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -1,7 +1,7 @@ /* * Platform Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -13,6 +13,9 @@ #include #include #include +#include +#include + #if defined(NANA_WINDOWS) #if defined(STD_THREAD_NOT_SUPPORTED) #include @@ -23,8 +26,6 @@ #include "../../paint/detail/image_ico.hpp" #elif defined(NANA_X11) #include - #include - #include #endif namespace nana{ @@ -131,9 +132,13 @@ namespace nana{ } } if (async) + { ::ShowWindowAsync(wd, cmd); - else - ::ShowWindow(wd, cmd); + return; + } + + internal_revert_guard revert; + ::ShowWindow(wd, cmd); } #elif defined(NANA_X11) namespace restrict @@ -143,6 +148,33 @@ namespace nana{ #endif //struct native_interface + void native_interface::affinity_execute(native_window_type native_handle, const std::function& fn) + { + if (!fn) + return; + +#if defined(NANA_WINDOWS) + auto mswin = reinterpret_cast(native_handle); + if (::IsWindow(mswin)) + { + if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(mswin, nullptr)) + { + detail::messages::arg_affinity_execute arg; + arg.function_ptr = &fn; + + internal_revert_guard revert; + ::SendMessage(mswin, detail::messages::affinity_execute, reinterpret_cast(&arg), 0); + + return; + } + } + + fn(); +#else + fn(); +#endif + } + nana::size native_interface::primary_monitor_size() { #if defined(NANA_WINDOWS) @@ -1119,11 +1151,18 @@ namespace nana{ auto native_interface::window_caption(native_window_type wd) -> native_string_type { + native_string_type str; + #if defined(NANA_WINDOWS) + auto & lock = bedrock::instance().wd_manager().internal_lock(); + bool is_current_thread = (::GetCurrentThreadId() == ::GetWindowThreadProcessId(reinterpret_cast(wd), nullptr)); + + if (!is_current_thread) + lock.revert(); + int length = ::GetWindowTextLength(reinterpret_cast(wd)); if(length > 0) { - native_string_type str; //One for NULL terminator which GetWindowText will write. str.resize(length+1); @@ -1131,9 +1170,11 @@ namespace nana{ //Remove the null terminator writtien by GetWindowText str.resize(length); - - return str; } + + if (!is_current_thread) + lock.forward(); + #elif defined(NANA_X11) nana::detail::platform_scope_guard psg; ::XTextProperty txtpro; @@ -1145,14 +1186,13 @@ namespace nana{ { if(size > 1) { - std::string text = *strlist; + str = *strlist; ::XFreeStringList(strlist); - return text; } } } #endif - return native_string_type(); + return str; } void native_interface::capture_window(native_window_type wd, bool cap) @@ -1314,7 +1354,10 @@ namespace nana{ if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast(wd), nullptr)) ::PostMessage(reinterpret_cast(wd), nana::detail::messages::async_set_focus, 0, 0); else + { + internal_revert_guard revert; ::SetFocus(reinterpret_cast(wd)); + } } #elif defined(NANA_X11) nana::detail::platform_scope_guard lock; diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 25708b93..da6291f1 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -1,7 +1,7 @@ /* * Parts of Class Place * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -277,66 +277,11 @@ namespace nana void add_pane(factory & fn) { - rectangle r{ point(), this->size()}; - - //get a rectangle excluding caption - r.y = 20; - if (r.height > 20) - r.height -= 20; - else - r.height = 0; - - if (!tabbar_) + auto fn_ptr = &fn; + API::dev::affinity_execute(*this, [this, fn_ptr] { - if (panels_.size() > 0) - { - tabbar_.reset(new tabbar_lite(*this)); - - tabbar_->events().selected.clear(); - tabbar_->events().selected([this] - { - auto handle = tabbar_->attach(tabbar_->selected()); - if (handle) - caption_.caption(API::window_caption(handle)); - else - caption_.caption(::std::string()); - }); - - tabbar_->move({ 0, r.bottom() - 20, r.width, 20 }); - r.height -= 20; - - std::size_t pos = 0; - for (auto & pn : panels_) - { - tabbar_->push_back(::nana::charset(pn.widget_ptr->caption())); - tabbar_->attach(pos++, *pn.widget_ptr); - } - } - } - else - r.height -= 20; - - auto wdg = fn(*this); - - if (tabbar_) - { - tabbar_->push_back(::nana::charset(wdg->caption())); - tabbar_->attach(panels_.size(), wdg->handle()); - } - - if (panels_.empty()) - { - caption_.caption(wdg->caption()); - } - - panels_.emplace_back(); - panels_.back().widget_ptr.swap(wdg); - - for (auto & pn : panels_) - { - if (pn.widget_ptr) - pn.widget_ptr->move(r); - } + _m_add_pane(*fn_ptr); + }); } void float_away(const ::nana::point& move_pos) @@ -382,6 +327,72 @@ namespace nana { return (nullptr != container_); } + private: + void _m_add_pane(factory & fn) + { + rectangle r{ point(), this->size() }; + + //get a rectangle excluding caption + r.y = 20; + if (r.height > 20) + r.height -= 20; + else + r.height = 0; + + if (!tabbar_) + { + if (panels_.size() > 0) + { + tabbar_.reset(new tabbar_lite(*this)); + + tabbar_->events().selected.clear(); + tabbar_->events().selected([this] + { + auto handle = tabbar_->attach(tabbar_->selected()); + if (handle) + caption_.caption(API::window_caption(handle)); + else + caption_.caption(::std::string()); + }); + + tabbar_->move({ 0, r.bottom() - 20, r.width, 20 }); + r.height -= 20; + + std::size_t pos = 0; + for (auto & pn : panels_) + { + tabbar_->push_back(::nana::charset(pn.widget_ptr->caption())); + tabbar_->attach(pos++, *pn.widget_ptr); + } + } + } + else + r.height -= 20; + + auto wdg = fn(*this); + if (wdg) + { + if (tabbar_) + { + tabbar_->push_back(::nana::charset(wdg->caption())); + tabbar_->attach(panels_.size(), wdg->handle()); + } + + if (panels_.empty()) + { + caption_.caption(wdg->caption()); + } + + panels_.emplace_back(); + panels_.back().widget_ptr.swap(wdg); + + for (auto & pn : panels_) + { + if (pn.widget_ptr) + pn.widget_ptr->move(r); + } + } + } private: window host_window_{nullptr}; place_parts::dock_notifier_interface* notifier_{ nullptr }; diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index e36e1a36..d3075bcf 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -179,6 +179,11 @@ namespace API namespace dev { + void affinity_execute(window window_handle, const std::function& fn) + { + interface_type::affinity_execute(root(window_handle), fn); + } + bool set_events(window wd, const std::shared_ptr& gep) { auto iwd = reinterpret_cast(wd); From a27a85d0c99987f130ebf02a115c46adc83f4e23 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 9 Apr 2016 04:13:22 +0800 Subject: [PATCH 133/309] add listbox model feature --- include/nana/gui/widgets/listbox.hpp | 626 ++++++++++++- source/gui/detail/window_manager.cpp | 3 - source/gui/widgets/listbox.cpp | 1276 +++++++++++++++++--------- 3 files changed, 1420 insertions(+), 485 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 373d54ad..e54b7415 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include namespace nana { @@ -35,6 +37,543 @@ namespace nana { namespace listbox { + class const_virtual_pointer + { + struct intern + { + public: + virtual ~intern() = default; + }; + + template + struct real_pointer + : public intern + { + const T * ptr; + + real_pointer(const T* p) + : ptr(p) + {} + }; + + const_virtual_pointer(const const_virtual_pointer&) = delete; + const_virtual_pointer& operator=(const const_virtual_pointer&) = delete; + + const_virtual_pointer(const_virtual_pointer&&) = delete; + const_virtual_pointer& operator=(const_virtual_pointer&&) = delete; + public: + template + explicit const_virtual_pointer(const Type* p) + : intern_(new real_pointer{p}) + { + } + + ~const_virtual_pointer() + { + delete intern_; + } + + template + const typename std::remove_const::type *get() + { + using value_type = typename std::remove_const::type; + auto target = dynamic_cast*>(intern_); + return (target ? target->ptr : nullptr); + } + private: + intern * intern_; + }; + + struct cell + { + struct format + { + ::nana::color bgcolor; + ::nana::color fgcolor; + + format() = default; + format(const ::nana::color& bgcolor, const ::nana::color& fgcolor); + }; + + using format_ptr = ::std::unique_ptr; + + ::std::string text; + format_ptr custom_format; + + cell() = default; + cell(const cell&); + cell(cell&&); + cell(::std::string); + cell(::std::string, const format&); + cell(::std::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor); + + cell& operator=(const cell&); + cell& operator=(cell&&); + }; + + class container_interface + { + friend class model_guard; + public: + virtual ~container_interface() = default; + + virtual void clear() = 0; + virtual void erase(std::size_t pos) = 0; + + virtual std::size_t size() const = 0; + virtual bool immutable() const = 0; + + virtual void emplace(std::size_t pos) = 0; + virtual void emplace_back() = 0; + + virtual void assign(std::size_t pos, const std::vector& cells) = 0; + virtual std::vector to_cells(std::size_t pos) const = 0; + + virtual bool push_back(const_virtual_pointer&) = 0; + + virtual void * pointer() = 0; + virtual const void* pointer() const = 0; + }; + + template + struct container_translator + { + using value_translator = std::function& cells)>; + using cell_translator = std::function(const Value&)>; + + value_translator to_value; + cell_translator to_cell; + }; + + template + class basic_container + : public container_interface + { + }; + + template + class standalone_container + : public basic_container + { + using value_type = typename STLContainer::value_type; + using value_translator = typename container_translator::value_translator; + using cell_translator = typename container_translator::cell_translator; + public: + standalone_container(STLContainer&& cont, value_translator vtrans, cell_translator ctrans) + : container_(std::move(cont)), + translator_({ vtrans, ctrans }) + {} + + standalone_container(const STLContainer& cont, value_translator vtrans, cell_translator ctrans) + : container_(cont), + translator_({ vtrans, ctrans }) + {} + private: + void clear() override + { + container_.clear(); + } + + void erase(std::size_t pos) override + { + auto i = container_.begin(); + std::advance(i, static_cast(pos)); + container_.erase(i); + } + + std::size_t size() const override + { + return container_.size(); + } + + bool immutable() const override + { + return false; + } + + void emplace(std::size_t pos) override + { + auto i = container_.begin(); + std::advance(i, static_cast(pos)); + + container_.emplace(i); + } + + void emplace_back() override + { + container_.emplace_back(); + } + + void assign(std::size_t pos, const std::vector& cells) override + { + container_.at(pos) = translator_.to_value(cells); + } + + std::vector to_cells(std::size_t pos) const override + { + return translator_.to_cell(container_.at(pos)); + } + + bool push_back(const_virtual_pointer& dptr) override + { + auto value = dptr.get(); + if (value) + { + container_.push_back(*value); + return true; + } + return false; + } + + void* pointer() override + { + return &container_; + } + + const void* pointer() const override + { + return &container_; + } + private: + STLContainer container_; + container_translator translator_; + }; + + + template + class shared_container + : public basic_container + { + using value_type = typename STLContainer::value_type; + using value_translator = typename container_translator::value_translator; + using cell_translator = typename container_translator::cell_translator; + + public: + using container_reference = STLContainer&; + + + shared_container(container_reference cont, value_translator vtrans, cell_translator ctrans) + : container_(cont), translator_({ vtrans, ctrans }) + { + + } + private: + void clear() override + { + container_.clear(); + } + + void erase(std::size_t pos) override + { + auto i = container_.begin(); + std::advance(i, static_cast(pos)); + container_.erase(i); + } + + std::size_t size() const override + { + return container_.size(); + } + + bool immutable() const override + { + return false; + } + + void emplace(std::size_t pos) override + { + auto i = container_.begin(); + std::advance(i, static_cast(pos)); + + container_.emplace(i); + } + + void emplace_back() override + { + container_.emplace_back(); + } + + void assign(std::size_t pos, const std::vector& cells) override + { + container_.at(pos) = translator_.to_value(cells); + } + + std::vector to_cells(std::size_t pos) const override + { + return translator_.to_cell(container_.at(pos)); + } + + bool push_back(const_virtual_pointer& dptr) override + { + auto value = dptr.get(); + if (value) + { + container_.push_back(*value); + return true; + } + return false; + } + + void* pointer() override + { + return &container_; + } + + const void* pointer() const override + { + return &container_; + } + private: + container_reference container_; + container_translator translator_; + }; + + template + class shared_immutable_container + : public basic_container + { + using value_type = typename STLContainer::value_type; + using cell_translator = typename container_translator::cell_translator; + + + public: + using container_reference = const STLContainer&; + + + shared_immutable_container(container_reference cont, cell_translator ctrans) + : container_(cont), ctrans_(ctrans) + { + } + private: + void clear() override + { + throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); + } + + void erase(std::size_t pos) override + { + throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); + } + + std::size_t size() const override + { + return container_.size(); + } + + bool immutable() const override + { + return true; + } + + void emplace(std::size_t pos) override + { + throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); + } + + void emplace_back() override + { + throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); + } + + void assign(std::size_t pos, const std::vector& cells) override + { + throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); + } + + std::vector to_cells(std::size_t pos) const override + { + return ctrans_(container_.at(pos)); + } + + bool push_back(const_virtual_pointer& dptr) override + { + throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); + } + + void* pointer() override + { + return nullptr; + } + + const void* pointer() const override + { + return &container_; + } + private: + container_reference container_; + cell_translator ctrans_; + }; + + class model_interface + { + public: + virtual ~model_interface() = default; + + virtual void lock() = 0; + virtual void unlock() = 0; + + virtual container_interface* container() = 0; + virtual const container_interface* container() const = 0; + }; + + class model_guard + { + model_guard(const model_guard&) = delete; + model_guard& operator=(const model_guard&) = delete; + public: + model_guard(model_interface* model) + : model_(model) + { + model->lock(); + } + + model_guard(model_guard&& other) + : model_(other.model_) + { + other.model_ = nullptr; + } + + ~model_guard() noexcept + { + if (model_) + model_->unlock(); + } + + model_guard& operator=(model_guard&& other) + { + if (this != &other) + { + if (model_) + model_->unlock(); + + model_ = other.model_; + other.model_ = nullptr; + } + return *this; + } + + template + STLContainer& container() + { + using stlcontainer = typename std::decay::type; + + if (!model_) + throw std::runtime_error("nana::listbox empty model_guard"); + + using type = basic_container; + auto p = dynamic_cast(model_->container()); + if (nullptr == p) + throw std::invalid_argument("invalid listbox model container type"); + + if (nullptr == p->pointer()) + throw std::runtime_error("the modal is immutable"); + + return *static_cast(p->pointer()); + } + + template + const STLContainer& container() const + { + using stlcontainer = typename std::decay::type; + + if (!model_) + throw std::runtime_error("nana::listbox empty model_guard"); + + using type = basic_container; + auto p = dynamic_cast(model_->container()); + if (nullptr == p) + throw std::invalid_argument("invalid listbox model container type"); + + return *static_cast(p->pointer()); + } + private: + model_interface* model_; + }; + + template + class standalone_model_container + : public model_interface + { + public: + using value_translator = typename container_translator::value_translator; + using cell_translator = typename container_translator::cell_translator; + + standalone_model_container(STLContainer&& container, value_translator vtrans, cell_translator ctrans) + : container_(std::move(container), std::move(vtrans), std::move(ctrans)) + { + } + + standalone_model_container(const STLContainer& container, value_translator vtrans, cell_translator ctrans) + : container_(container, std::move(vtrans), std::move(ctrans)) + { + } + + void lock() override + { + mutex_.lock(); + } + + void unlock() override + { + mutex_.unlock(); + } + + container_interface* container() override + { + return &container_; + } + + const container_interface* container() const override + { + return &container_; + } + private: + Mutex mutex_; + standalone_container container_; + }; + + template + class shared_model_container + : public model_interface + { + public: + using value_translator = typename container_translator::value_translator; + using cell_translator = typename container_translator::cell_translator; + + shared_model_container(STLContainer& container, value_translator vtrans, cell_translator ctrans) + : container_ptr_(new shared_container(container, std::move(vtrans), std::move(ctrans))) + { + } + + shared_model_container(const STLContainer& container, cell_translator ctrans) + : container_ptr_(new shared_immutable_container(container, std::move(ctrans))) + { + } + + void lock() override + { + mutex_.lock(); + } + + void unlock() override + { + mutex_.unlock(); + } + + container_interface* container() override + { + return container_ptr_.get(); + } + + const container_interface* container() const override + { + return container_ptr_.get(); + } + private: + Mutex mutex_; + std::unique_ptr container_ptr_; + }; + using size_type = std::size_t; using native_string_type = ::nana::detail::native_string_type; @@ -89,36 +628,15 @@ namespace nana using inline_notifier_interface = detail::inline_widget_notifier_interface; - struct cell - { - struct format - { - ::nana::color bgcolor; - ::nana::color fgcolor; - /// ::nana::paint::font font; \todo - format() = default; - format(const ::nana::color& bgcolor, const ::nana::color& fgcolor); - }; - - using format_ptr = ::std::unique_ptr; - - ::std::string text; - format_ptr custom_format; - - cell() = default; - cell(const cell&); - cell(cell&&); - cell(::std::string); - cell(::std::string, const format&); - cell(::std::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor); - - cell& operator=(const cell&); - cell& operator=(cell&&); - }; + // struct essence_t + //@brief: this struct gives many data for listbox, + // the state of the struct does not effect on member funcions, therefore all data members are public. + struct essence_t; class oresolver { public: + oresolver(essence_t*); oresolver& operator<<(bool); oresolver& operator<<(short); oresolver& operator<<(unsigned short); @@ -141,7 +659,10 @@ namespace nana oresolver& operator<<(std::nullptr_t); std::vector && move_cells(); + + ::nana::listbox& listbox(); private: + essence_t* const ess_; std::vector cells_; }; @@ -174,11 +695,6 @@ namespace nana using selection = std::vector; - /// struct essence_t - ///@brief: this struct gives many data for listbox, - /// the state of the struct does not effect on member funcions, therefore all data members are public. - struct essence_t; - struct category_t; class drawer_header_impl; class drawer_lister_impl; @@ -256,7 +772,7 @@ namespace nana template item_proxy & resolve_from(const T& t) { - oresolver ores; + oresolver ores(_m_ess()); ores << t; auto && cells = ores.move_cells(); auto cols = columns(); @@ -355,6 +871,8 @@ namespace nana { public: using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface; + template using value_translator = typename container_translator::value_translator; + template using cell_translator = typename container_translator::cell_translator; cat_proxy() = default; cat_proxy(essence_t*, size_type pos); @@ -364,7 +882,11 @@ namespace nana template item_proxy append(T&& t, bool set_value = false) { - oresolver ores; + oresolver ores(ess_); + + //Troubleshoot: + //If a compiler error that no operator<< overload found for type T occurs, please define a overload operator<<(oresolver&, const T&). + //If a listbox have a model set, try call append_model instead. if (set_value) ores << t; //copy it if it is rvalue and set_value is true. else @@ -381,6 +903,33 @@ namespace nana return iter; } + template + void append_model(const T& t) + { + _m_try_append_model(const_virtual_pointer{ &t }); + _m_update(); + } + + template + void model(STLContainer&& container, ValueTranslator vtrans, CellTranslator ctrans) + { + _m_reset_model(new standalone_model_container::type, Mutex>(std::forward(container), std::move(vtrans), std::move(ctrans))); + } + + template + void shared_model(STLContainer& container, ValueTranslator vtrans, CellTranslator ctrans) + { + _m_reset_model(new shared_model_container::type, Mutex>(container, std::move(vtrans), std::move(ctrans))); + } + + template + void shared_model(const STLContainer& container, CellTranslator ctrans) + { + _m_reset_model(new shared_model_container::type, Mutex>(container, std::move(ctrans))); + } + + model_guard model(); + /// Appends one item at the end of this category with the specifies text in the column fields void append(std::initializer_list texts_utf8); void append(std::initializer_list texts); @@ -448,8 +997,10 @@ namespace nana void inline_factory(size_type column, pat::cloneable> factory); private: void _m_append(std::vector && cells); + void _m_try_append_model(const_virtual_pointer&); void _m_cat_by_pos(); void _m_update(); + void _m_reset_model(model_interface*); private: essence_t* ess_{nullptr}; category_t* cat_{nullptr}; @@ -480,7 +1031,7 @@ namespace nana }; /// The event argument type for listbox's category_dbl_click - struct arg_category + struct arg_listbox_category : public event_arg { drawerbase::listbox::cat_proxy category; @@ -491,7 +1042,7 @@ namespace nana /// Determines whether expension/shrink of category is blocked bool category_change_blocked() const noexcept; - arg_category(const drawerbase::listbox::cat_proxy&) noexcept; + arg_listbox_category(const drawerbase::listbox::cat_proxy&) noexcept; private: mutable bool block_change_; }; @@ -507,7 +1058,7 @@ namespace nana basic_event selected; /// An event occurs when a listbox category is double clicking. - basic_event category_dbl_click; + basic_event category_dbl_click; }; struct scheme @@ -600,7 +1151,6 @@ By \a clicking on one header the list get \a reordered, first up, and then down unsigned header_width(size_type position) const; unsigned auto_width(size_type position, unsigned max=3000); - cat_proxy append(std::string); ///< Appends a new category to the end cat_proxy append(std::wstring); ///< Appends a new category to the end void append(std::initializer_list); ///< Appends categories to the end @@ -707,7 +1257,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down private: drawerbase::listbox::essence_t & _m_ess() const; nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const; - drawerbase::listbox::category_t* _m_at_key(std::shared_ptr); + drawerbase::listbox::category_t* _m_at_key(std::shared_ptr&); void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 66d0def6..9045945f 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -850,9 +850,6 @@ namespace detail { window_layer::paint(wd, false, refresh_tree); this->map(wd, force_copy_to_screen); - - wd->drawer.graphics.save_as_file("d:\\button.bmp"); - wd->root_graph->save_as_file("d:\\button_root.bmp"); } else if (effects::edge_nimbus::none != wd->effect.edge_nimbus) { diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 56eff953..0ff2ff24 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace nana { @@ -35,6 +36,28 @@ namespace nana { namespace listbox { + class model_lock_guard + { + model_lock_guard(const model_lock_guard&) = delete; + model_lock_guard& operator=(const model_lock_guard&) = delete; + public: + model_lock_guard(model_interface* model) + : model_ptr_(model) + { + if (model_ptr_) + model_ptr_->lock(); + } + + ~model_lock_guard() + { + if (model_ptr_) + model_ptr_->unlock(); + } + private: + model_interface* const model_ptr_; + }; + + //struct cell cell::format::format(const ::nana::color& bgcolor, const ::nana::color& fgcolor) : bgcolor{ bgcolor }, fgcolor{ fgcolor } @@ -87,241 +110,8 @@ namespace nana } //end struct cell - //definition of iresolver/oresolver - oresolver& oresolver::operator<<(bool n) - { - cells_.emplace_back(n ? "true" : "false"); - return *this; - } - oresolver& oresolver::operator<<(short n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - oresolver& oresolver::operator<<(unsigned short n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - - oresolver& oresolver::operator<<(int n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - - oresolver& oresolver::operator<<(unsigned int n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - - oresolver& oresolver::operator<<(long n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - - oresolver& oresolver::operator<<(unsigned long n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - oresolver& oresolver::operator<<(long long n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - - oresolver& oresolver::operator<<(unsigned long long n) - { - cells_.emplace_back(std::to_string(n)); - return *this; - } - - oresolver& oresolver::operator<<(float f) - { - cells_.emplace_back(std::to_string(f)); - return *this; - } - - oresolver& oresolver::operator<<(double f) - { - cells_.emplace_back(std::to_string(f)); - return *this; - } - - oresolver& oresolver::operator<<(long double f) - { - cells_.emplace_back(std::to_string(f)); - return *this; - } - - oresolver& oresolver::operator<<(const char* text) - { - cells_.emplace_back(text); - return *this; - } - - oresolver& oresolver::operator<<(const wchar_t* text) - { - cells_.emplace_back(to_utf8(text)); - return *this; - } - - oresolver& oresolver::operator<<(const std::string& text) - { - cells_.emplace_back(text); - return *this; - } - - oresolver& oresolver::operator<<(const std::wstring& text) - { - cells_.emplace_back(to_utf8(text)); - return *this; - } - - oresolver& oresolver::operator<<(std::wstring&& text) - { - cells_.emplace_back(to_utf8(text)); - return *this; - } - - oresolver& oresolver::operator<<(cell cl) - { - cells_.emplace_back(std::move(cl)); - return *this; - } - - oresolver& oresolver::operator<<(std::nullptr_t) - { - cells_.emplace_back(); - cells_.back().text.assign(1, wchar_t(0)); //means invalid cell - return *this; - } - - std::vector&& oresolver::move_cells() - { - return std::move(cells_); - } - - iresolver& iresolver::operator>>(bool& n) - { - if (pos_ < cells_.size()) - n = (std::stoi(cells_[pos_++].text) == 0); - return *this; - } - - iresolver& iresolver::operator>>(short& n) - { - if (pos_ < cells_.size()) - n = std::stoi(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(unsigned short& n) - { - if (pos_ < cells_.size()) - n = static_cast(std::stoul(cells_[pos_++].text)); - return *this; - } - - iresolver& iresolver::operator>>(int& n) - { - if (pos_ < cells_.size()) - n = std::stoi(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(unsigned int& n) - { - if (pos_ < cells_.size()) - n = std::stoul(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(long& n) - { - if (pos_ < cells_.size()) - n = std::stol(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(unsigned long& n) - { - if (pos_ < cells_.size()) - n = std::stoul(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(long long& n) - { - if (pos_ < cells_.size()) - n = std::stoll(cells_[pos_++].text); - return *this; - } - iresolver& iresolver::operator>>(unsigned long long& n) - { - if (pos_ < cells_.size()) - n = std::stoull(cells_[pos_++].text); - return *this; - } - iresolver& iresolver::operator>>(float& f) - { - if (pos_ < cells_.size()) - f = std::stof(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(double& f) - { - if (pos_ < cells_.size()) - f = std::stod(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(long double& f) - { - if (pos_ < cells_.size()) - f = std::stold(cells_[pos_++].text); - return *this; - } - - iresolver& iresolver::operator>>(std::string& text) - { - if (pos_ < cells_.size()) - text = cells_[pos_++].text; - return *this; - } - - iresolver& iresolver::operator>>(std::wstring& text) - { - if (pos_ < cells_.size()) - text = to_wstring(cells_[pos_++].text); - - return *this; - } - - iresolver::iresolver(const std::vector& cl) - : cells_(cl) - {} - - iresolver& iresolver::operator>>(cell& cl) - { - if (pos_ < cells_.size()) - cl = cells_[pos_++]; - return *this; - } - - iresolver& iresolver::operator>>(std::nullptr_t) - { - ++pos_; - return *this; - } - //end class iresolver/oresolver - - /// Essence of the columns Header + // Essence of the columns Header class es_header { public: @@ -565,7 +355,7 @@ namespace nana struct essence_t; - struct item_t + struct item_data { using container = std::vector; @@ -583,12 +373,12 @@ namespace nana mutable std::unique_ptr anyobj; - item_t() + item_data() { flags.selected = flags.checked = false; } - item_t(const item_t& r) + item_data(const item_data& r) : cells(r.cells), bgcolor(r.bgcolor), fgcolor(r.fgcolor), @@ -597,19 +387,19 @@ namespace nana anyobj(r.anyobj ? new nana::any(*r.anyobj) : nullptr) {} - item_t(container&& cont) + item_data(container&& cont) : cells(std::move(cont)) { flags.selected = flags.checked = false; } - item_t(std::string&& s) + item_data(std::string&& s) { flags.selected = flags.checked = false; cells.emplace_back(std::move(s)); } - item_t(std::string&& s, const nana::color& bg, const nana::color& fg) + item_data(std::string&& s, const nana::color& bg, const nana::color& fg) : bgcolor(bg), fgcolor(fg) { @@ -617,7 +407,7 @@ namespace nana cells.emplace_back(std::move(s)); } - item_t& operator=(const item_t& r) + item_data& operator=(const item_data& r) { if (this != &r) { @@ -654,11 +444,14 @@ namespace nana struct category_t { - using container = std::deque; + using container = std::deque; native_string_type text; std::vector sorted; container items; + + std::unique_ptr model_ptr; + bool expand{true}; //A cat may have a key object to identify the category @@ -677,7 +470,8 @@ namespace nana { for (auto & m : items) { - if (m.flags.selected == false) return false; + if (false == m.flags.selected) + return false; } return !items.empty(); } @@ -688,13 +482,15 @@ namespace nana public: using container = std::list; + using item_type = item_data; + std::function(std::size_t) > fetch_ordering_comparer; es_lister() { //#0 is a default category - list_.emplace_back(); + categories_.emplace_back(); } void bind(essence_t* ess, widget& wd) @@ -720,7 +516,7 @@ namespace nana if (allocate_if_empty) { - item.anyobj.reset(new nana::any); //make_unique + std::make_unique().swap(item.anyobj); return item.anyobj.get(); } } @@ -738,15 +534,47 @@ namespace nana auto weak_ordering_comp = fetch_ordering_comparer(sorted_index_); if(weak_ordering_comp) { - for(auto & cat: list_) + for (auto & cat : categories_) { auto bi = std::begin(cat.sorted); auto ei = std::end(cat.sorted); - std::sort(bi, ei, [&cat, &weak_ordering_comp, this](std::size_t x, std::size_t y){ + + if (cat.model_ptr) + { + std::sort(bi, ei, [&cat, &weak_ordering_comp, this](std::size_t x, std::size_t y){ //The predicate must be a strict weak ordering. //!comp(x, y) != comp(x, y) auto & mx = cat.items[x]; auto & my = cat.items[y]; + + auto mx_cells = cat.model_ptr->container()->to_cells(x); + auto my_cells = cat.model_ptr->container()->to_cells(y); + + if (mx_cells.size() <= sorted_index_ || my_cells.size() <= sorted_index_) + { + std::string a; + if (mx_cells.size() > sorted_index_) + a = mx_cells[sorted_index_].text; + + std::string b; + if (my_cells.size() > sorted_index_) + b = my_cells[sorted_index_].text; + + return weak_ordering_comp(a, mx.anyobj.get(), b, my.anyobj.get(), sorted_reverse_); + } + + return weak_ordering_comp(mx_cells[sorted_index_].text, mx.anyobj.get(), my_cells[sorted_index_].text, my.anyobj.get(), sorted_reverse_); + }); + } + else + { + std::sort(bi, ei, [&cat, &weak_ordering_comp, this](std::size_t x, std::size_t y){ + //The predicate must be a strict weak ordering. + //!comp(x, y) != comp(x, y) + + auto & mx = cat.items[x]; + auto & my = cat.items[y]; + if (mx.cells.size() <= sorted_index_ || my.cells.size() <= sorted_index_) { std::string a; @@ -762,37 +590,67 @@ namespace nana return weak_ordering_comp(mx.cells[sorted_index_].text, mx.anyobj.get(), my.cells[sorted_index_].text, my.anyobj.get(), sorted_reverse_); }); + } } } else { //No user-defined comparer is provided, and default comparer is applying. - for(auto & cat: list_) + for (auto & cat : categories_) { - std::sort(std::begin(cat.sorted), std::end(cat.sorted), [&cat, this](std::size_t x, std::size_t y){ - auto & item_x = cat.items[x]; - auto & item_y = cat.items[y]; + if (cat.model_ptr) + { + std::sort(std::begin(cat.sorted), std::end(cat.sorted), [&cat, this](std::size_t x, std::size_t y){ + auto mx_cells = cat.model_ptr->container()->to_cells(x); + auto my_cells = cat.model_ptr->container()->to_cells(y); - if (item_x.cells.size() <= sorted_index_ || item_y.cells.size() <= sorted_index_) + if (mx_cells.size() <= sorted_index_ || my_cells.size() <= sorted_index_) { std::string a; - if (item_x.cells.size() > sorted_index_) - a = item_x.cells[sorted_index_].text; + if (mx_cells.size() > sorted_index_) + a = mx_cells[sorted_index_].text; std::string b; - if (item_y.cells.size() > sorted_index_) - b = item_y.cells[sorted_index_].text; + if (my_cells.size() > sorted_index_) + b = my_cells[sorted_index_].text; return (sorted_reverse_ ? a > b : a < b); } - auto & a = item_x.cells[sorted_index_].text; - auto & b = item_y.cells[sorted_index_].text; + auto & a = mx_cells[sorted_index_].text; + auto & b = my_cells[sorted_index_].text; return (sorted_reverse_ ? a > b : a < b); }); + } + else + { + std::sort(std::begin(cat.sorted), std::end(cat.sorted), [&cat, this](std::size_t x, std::size_t y){ + + auto & mx = cat.items[x]; + auto & my = cat.items[y]; + + if (mx.cells.size() <= sorted_index_ || my.cells.size() <= sorted_index_) + { + std::string a; + if (mx.cells.size() > sorted_index_) + a = mx.cells[sorted_index_].text; + + std::string b; + if (my.cells.size() > sorted_index_) + b = my.cells[sorted_index_].text; + + return (sorted_reverse_ ? a > b : a < b); + } + + auto & a = mx.cells[sorted_index_].text; + auto & b = my.cells[sorted_index_].text; + return (sorted_reverse_ ? a > b : a < b); + }); + } } } scroll_refresh(); } + void scroll_refresh(); /// sort() and ivalidate any existing reference from display position to absolute item, that is after sort() display offset point to different items @@ -858,31 +716,31 @@ namespace nana ///Append a new category with a specified name and return a pointer to it. category_t* create_cat(native_string_type&& text) { - list_.emplace_back(std::move(text)); - return &list_.back(); + categories_.emplace_back(std::move(text)); + return &categories_.back(); } /// will use the key to insert new cat before the first cat with compare less than the key, or at the end of the list of cat and return a ref to that new cat. ? - category_t* create_cat(std::shared_ptr ptr) + category_t* create_cat(std::shared_ptr& ptr) { - for (auto i = list_.begin(); i != list_.end(); ++i) + for (auto i = categories_.begin(); i != categories_.end(); ++i) { if (i->key_ptr && i->key_ptr->compare(ptr.get())) { - i = list_.emplace(i); - i->key_ptr = ptr; + i = categories_.emplace(i); + i->key_ptr.swap(ptr); return &(*i); } } - list_.emplace_back(); - list_.back().key_ptr = ptr; - return &list_.back(); + categories_.emplace_back(); + categories_.back().key_ptr = ptr; + return &categories_.back(); } /// add a new cat created at "pos" and return a ref to it category_t* create_cat(std::size_t pos, native_string_type&& text) { - return &(*list_.emplace(this->get(pos), std::move(text))); + return &(*categories_.emplace(this->get(pos), std::move(text))); } /// Insert before item in absolute "pos" a new item with "text" in column 0, and place it in last display position of this cat @@ -896,10 +754,35 @@ namespace nana catobj.sorted.push_back(n); - if (pos.item < n) - catobj.items.emplace(catobj.items.begin() + pos.item, std::move(text)); + if (catobj.model_ptr) + { + auto container = catobj.model_ptr->container(); + std::size_t item_index; + // + if (pos.item < n) + { + catobj.items.emplace(catobj.items.begin() + pos.item); + container->emplace(pos.item); + item_index = pos.item; + } + else + { + item_index = container->size(); + catobj.items.emplace_back(); + container->emplace_back(); + } + + std::vector cells; + cells.emplace_back(std::move(text)); + container->assign(item_index, cells); + } else - catobj.items.emplace_back(std::move(text)); + { + if (pos.item < n) + catobj.items.emplace(catobj.items.begin() + pos.item, std::move(text)); + else + catobj.items.emplace_back(std::move(text)); + } return true; } @@ -928,11 +811,63 @@ namespace nana return npos ; } + static void throw_if_immutable_model(model_interface* model) + { + if (model && model->container()->immutable()) + { + //Precondition check for the insert/erase operation, it throws if the model is immutable + throw std::runtime_error("nana::listbox disallow to insert/remove items because of immutable model"); + } + } + + void throw_if_immutable_model(const index_pair& pos) const + { + if (pos.cat < categories_.size()) + { + auto i = categories_.cbegin(); + std::advance(i, pos.cat); + if (i->model_ptr && i->model_ptr->container()->immutable()) + throw std::runtime_error("nana::listbox disallow the operation because of immutable modal"); + } + } + + void assign_model(const index_pair& pos, const std::vector& cells) + { + if (pos.cat < categories_.size()) + { + auto i = categories_.cbegin(); + std::advance(i, pos.cat); + if (i->model_ptr) + { + if (i->model_ptr->container()->immutable()) + throw std::runtime_error("nana::listbox disallow to modify the item because of immutable model"); + + i->model_ptr->container()->assign(pos.item, cells); + } + } + } + + bool have_model(const index_pair& pos) const + { + return (get(pos.cat)->model_ptr != nullptr); + } + category_t::container::value_type& at_abs(const index_pair& pos) { return get(pos.cat)->items.at(pos.item); } + std::vector at_model_abs(const index_pair& pos) const + { + auto model_ptr = get(pos.cat)->model_ptr.get(); + + model_lock_guard lock(model_ptr); + if (model_ptr) + return model_ptr->container()->to_cells(pos.item); + + return{}; + } + /// return a ref to the real item object at display!!! position pos using current sorting only if it is active, and at absolute position if no sorting is currently active. category_t::container::value_type& at(const index_pair& pos) { @@ -944,6 +879,22 @@ namespace nana return get(pos.cat)->items.at(index); } + std::vector at_model(const index_pair& pos) const + { + auto model_ptr = get(pos.cat)->model_ptr.get(); + if (!model_ptr) + return{}; + + model_lock_guard lock(model_ptr); + + auto index = pos.item; + + if (sorted_index_ != npos) + index = absolute(pos); + + return model_ptr->container()->to_cells(index); + } + const category_t::container::value_type& at(const index_pair& pos) const { auto index = pos.item; @@ -954,19 +905,36 @@ namespace nana return get(pos.cat)->items.at(index); } + // Removes all items of a specified category + // It throws when the category is out of range or has an immutable model. void clear(size_type cat) { auto& catobj = *get(cat); + + model_lock_guard lock(catobj.model_ptr.get()); + if (catobj.model_ptr) + { + //The immutable modal can't be cleared. + throw_if_immutable_model(catobj.model_ptr.get()); + + catobj.model_ptr->container()->clear(); + } + catobj.items.clear(); catobj.sorted.clear(); } - /// clear all items in all cat, but not the container of cat self. + + // Clears all items in all cat, but not the container of cat self. void clear() { - for(auto & m : list_) + // Check whether there is a immutable model + for (auto & cat : categories_) + throw_if_immutable_model(cat.model_ptr.get()); + + auto n = categories_.size(); + for (decltype(n) i = 0; i < n; ++i) { - m.items.clear(); - m.sorted.clear(); + clear(i); } } @@ -1048,7 +1016,7 @@ namespace nana else n = i->items.size() - (from.item + 1); - for(++i, ++from.cat; i != list_.end(); ++i, ++from.cat) + for(++i, ++from.cat; i != categories_.end(); ++i, ++from.cat) { ++n; //this is a category if(from.cat != to.cat) @@ -1066,31 +1034,58 @@ namespace nana return n; } - std::vector& get_cells(category_t * cat, size_type pos) const + std::vector& get_cells(category_t * cat, std::size_t pos) const { if (!cat) throw std::out_of_range("nana::listbox: category is null"); + if (cat->model_ptr) + throw std::runtime_error("nana::listbox disallow to get item cells, because there are model cells"); + return cat->items.at(pos).cells; } + std::vector get_model_cells(category_t* cat, std::size_t pos) const + { + if (!cat) + throw std::out_of_range("nana::listbox: category is null"); + + if (!(cat->model_ptr)) + throw std::runtime_error("nana::listbox: the category hasn't a model"); + + return cat->model_ptr->container()->to_cells(pos); + } + void text(category_t* cat, size_type pos, size_type col, cell&& cl, size_type columns) { if ((col < columns) && (pos < cat->items.size())) { - auto & cont = cat->items[pos].cells; - if (col < cont.size()) + std::vector model_cells; + + model_lock_guard lock(cat->model_ptr.get()); + if (cat->model_ptr) { - cont[col] = std::move(cl); + throw_if_immutable_model(cat->model_ptr.get()); + model_cells = cat->model_ptr->container()->to_cells(pos); + } + + auto & cells = (cat->model_ptr ? model_cells : cat->items[pos].cells); + + if (col < cells.size()) + { + cells[col] = std::move(cl); if (sorted_index_ == col) sort(); } else { //If the index of specified sub item is over the number of sub items that item contained, //it fills the non-exist items. - cont.resize(col); - cont.emplace_back(std::move(cl)); + cells.resize(col); + cells.emplace_back(std::move(cl)); } + + if (cat->model_ptr) + cat->model_ptr->container()->assign(pos, model_cells); } } @@ -1098,19 +1093,32 @@ namespace nana { if ((col < columns) && (pos < cat->items.size())) { - auto & cont = cat->items[pos].cells; - if (col < cont.size()) + std::vector model_cells; + + model_lock_guard lock(cat->model_ptr.get()); + if (cat->model_ptr) { - cont[col].text = std::move(str); + throw_if_immutable_model(cat->model_ptr.get()); + model_cells = cat->model_ptr->container()->to_cells(pos); + } + + auto & cells = (cat->model_ptr ? model_cells : cat->items[pos].cells); + + if (col < cells.size()) + { + cells[col].text.swap(str); if (sorted_index_ == col) sort(); } else { //If the index of specified sub item is over the number of sub items that item contained, //it fills the non-exist items. - cont.resize(col); - cont.emplace_back(std::move(str)); + cells.resize(col); + cells.emplace_back(std::move(str)); } + + if (cat->model_ptr) + cat->model_ptr->container()->assign(pos, model_cells); } } @@ -1123,21 +1131,35 @@ namespace nana //If the category is the first one, it just clears the items instead of removing whole category. if(0 == cat) { + if (i->model_ptr) + { + throw_if_immutable_model(i->model_ptr.get()); + i->model_ptr->container()->clear(); + } + i->items.clear(); i->sorted.clear(); } else - list_.erase(i); + categories_.erase(i); } void erase() { //Do not remove the first category. - auto i = list_.begin(); + auto i = categories_.begin(); + + if (i->model_ptr) + { + throw_if_immutable_model(i->model_ptr.get()); + i->model_ptr->container()->clear(); + } + i->items.clear(); i->sorted.clear(); - if(list_.size() > 1) - list_.erase(++i, list_.end()); + + if (categories_.size() > 1) + categories_.erase(++i, categories_.end()); } bool expand(size_type cat, bool exp) @@ -1161,12 +1183,12 @@ namespace nana container& cat_container() { - return list_; + return categories_; } const container& cat_container() const { - return list_; + return categories_; } //Enable/Disable the ordered categories @@ -1186,8 +1208,8 @@ namespace nana size_type the_number_of_expanded() const { - size_type n = list_.size() - 1; - for(auto & i : list_) + size_type n = categories_.size() - 1; + for (auto & i : categories_) { if(i.expand) n += i.items.size(); @@ -1198,7 +1220,7 @@ namespace nana void check_for_all(bool ck) { index_pair pos; - for(auto & cat : list_) + for (auto & cat : categories_) { pos.item = 0; for(auto & m : cat.items) @@ -1220,7 +1242,7 @@ namespace nana { selection vec; index_pair id; - for(auto & cat : list_) + for (auto & cat : categories_) { id.item = 0; for(auto & m : cat.items) @@ -1268,7 +1290,7 @@ namespace nana { bool changed = false; index_pair i; - for(auto & cat : list_) + for (auto & cat : categories_) { i.item = 0; for(auto & m : cat.items) @@ -1293,27 +1315,32 @@ namespace nana return changed; } - /// return absolute positions, no relative to display - void item_selected(selection& vec) const // change to selection item_selected(); + /// get absolute positions, no relative to display. Returns true if all items are checked. + bool item_selected(selection& s) const { index_pair id; - for(auto & cat : list_) + bool is_all_checked = true; + for (auto & cat : categories_) { id.item = 0; for(auto & m : cat.items) { - if(m.flags.selected) - vec.push_back(id); // absolute positions, no relative to display + if (m.flags.selected) + { + s.push_back(id); // absolute positions, no relative to display + is_all_checked &= m.flags.checked; + } ++id.item; } ++id.cat; } + return is_all_checked; } index_pair find_first_selected() { index_pair id; - for(auto & cat : list_) + for (auto & cat : categories_) { id.item = 0; for(auto & m : cat.items) @@ -1327,31 +1354,6 @@ namespace nana return {npos,npos}; } - /// return absolute positions, no relative to display - bool item_selected_all_checked(selection& vec) const - { - index_pair id; - bool ck = true; - - for (auto & cat : list_) - { - id.item = 0; - for (auto & m : cat.items) - { - if (m.flags.selected) - { - vec.push_back(id); // absolute positions, no relative to display - ck &= m.flags.checked; - } - ++id.item; - } - ++id.cat; - } - - //Just returns true when the all selected items are checked. - return ck; - } - /// cat_index) + if (categories_.size() > cat_index) return categ_checked(cat_index, !categ_checked(cat_index)); return false; } @@ -1590,11 +1592,11 @@ namespace nana /// can be used as the absolute position of the last absolute item, or as the display pos of the last displayed item index_pair last() const { - index_pair i{ list_.size() - 1, list_.back().items.size() }; + index_pair i{ categories_.size() - 1, categories_.back().items.size() }; if (i.cat) { - if (i.item && list_.back().expand) + if (i.item && categories_.back().expand) --i.item; else i.item = npos; @@ -1626,12 +1628,12 @@ namespace nana bool good(size_type cat) const { - return (cat < list_.size()); + return (cat < categories_.size()); } bool good(const index_pair& pos) const { - return ((pos.cat < list_.size()) && (pos.item < size_item(pos.cat))); + return ((pos.cat < categories_.size()) && (pos.item < size_item(pos.cat))); } /// if good return the same item (in arg item), or just the next cat and true, but If fail return false bool good_item(index_pair pos, index_pair& item) const @@ -1655,7 +1657,7 @@ namespace nana return true; } - if (++i == list_.end()) // item out of range and no more cat + if (++i == categories_.end()) // item out of range and no more cat return false; item.cat = pos.cat + 1; // select the next cat @@ -1713,7 +1715,7 @@ namespace nana return false; auto cat = get(from.cat); - auto cat_end = list_.end(); + auto cat_end = categories_.end(); auto items_left = (cat->expand ? cat->items.size() : 0); @@ -1768,7 +1770,7 @@ namespace nana return true; } - while(i != list_.cbegin()) + while (i != categories_.cbegin()) { --i; --from.cat; @@ -1792,20 +1794,20 @@ namespace nana /// categories iterator container::iterator get(size_type pos) { - if (pos >= list_.size()) + if (pos >= categories_.size()) throw std::out_of_range("nana::listbox: invalid category index"); - auto i = list_.begin(); + auto i = categories_.begin(); std::advance(i, pos); return i; } container::const_iterator get(size_type pos) const { - if (pos >= list_.size()) + if (pos >= categories_.size()) throw std::out_of_range("nana::listbox: invalid category index"); - auto i = list_.cbegin(); + auto i = categories_.cbegin(); std::advance(i, pos); return i; } @@ -1819,7 +1821,7 @@ namespace nana bool sorted_reverse_{false}; bool ordered_categories_{false}; ///< A switch indicates whether the categories are ordered. /// The ordered categories always creates a new category at a proper position(before the first one which is larger than it). - container list_; // rename to categories_ + container categories_; bool single_selection_{ false }; bool single_selection_category_limited_{ false }; @@ -1836,6 +1838,7 @@ namespace nana enum class item_state{normal, highlighted, pressed, grabbed, floated}; enum class parts{unknown = -1, header, lister, checker}; + ::nana::listbox* listbox_ptr{nullptr}; ::nana::listbox::scheme_type* scheme_ptr{nullptr}; ::nana::paint::graphics *graph{nullptr}; bool auto_draw{true}; @@ -2311,24 +2314,40 @@ namespace nana return seqs; } - unsigned auto_width(size_type pos, unsigned max = 3000) /// \todo introduce parametr max_header_width + //Updates the column width and returns the pixels of item text which is largest. + unsigned update_column_width(size_type pos, unsigned max = 3000) /// \todo introduce parametr max_header_width { unsigned max_w{ 0 }; for (const auto &cat : lister.cat_container()) + { + model_lock_guard lock(cat.model_ptr.get()); + + std::vector model_cells; + std::size_t item_index = 0; for (const auto &it : cat.items) { - if (pos >= it.cells.size()) continue; + if (cat.model_ptr) + model_cells = cat.model_ptr->container()->to_cells(item_index); + + auto & cells = cat.model_ptr ? model_cells : it.cells; + + if (pos >= cells.size()) + continue; + // precalcule text geometry - unsigned ts = static_cast (graph->text_extent_size(it.cells[pos].text).width); + unsigned ts = static_cast (graph->text_extent_size(cells[pos].text).width); if (max_w < ts) max_w = ts; } + } + if (!max_w) return 0; - unsigned ext_w = scheme_ptr->ext_w; + unsigned width_px = scheme_ptr->ext_w + max_w + 5; if (pos == 0 && checkable) // only before the first column (display_order=0 ?) - ext_w += 18; - header.item_width(pos, max_w + ext_w + 1 < max ? max_w + ext_w + 1 : max); + width_px += 18; + + header.item_width(pos, width_px < max ? width_px : max); return max_w; } @@ -2362,6 +2381,249 @@ namespace nana } }; + //definition of iresolver/oresolver + oresolver::oresolver(essence_t* ess) + : ess_(ess) + {} + + oresolver& oresolver::operator<<(bool n) + { + cells_.emplace_back(std::string(n ? "true" : "false")); + return *this; + } + oresolver& oresolver::operator<<(short n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(unsigned short n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(int n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(unsigned int n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(long n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(unsigned long n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + oresolver& oresolver::operator<<(long long n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(unsigned long long n) + { + cells_.emplace_back(std::to_string(n)); + return *this; + } + + oresolver& oresolver::operator<<(float f) + { + cells_.emplace_back(std::to_string(f)); + return *this; + } + + oresolver& oresolver::operator<<(double f) + { + cells_.emplace_back(std::to_string(f)); + return *this; + } + + oresolver& oresolver::operator<<(long double f) + { + cells_.emplace_back(std::to_string(f)); + return *this; + } + + oresolver& oresolver::operator<<(const char* text) + { + cells_.emplace_back(std::string(text)); + return *this; + } + + oresolver& oresolver::operator<<(const wchar_t* text) + { + cells_.emplace_back(to_utf8(text)); + return *this; + } + + oresolver& oresolver::operator<<(const std::string& text) + { + cells_.emplace_back(text); + return *this; + } + + oresolver& oresolver::operator<<(const std::wstring& text) + { + cells_.emplace_back(to_utf8(text)); + return *this; + } + + oresolver& oresolver::operator<<(std::wstring&& text) + { + cells_.emplace_back(to_utf8(text)); + return *this; + } + + oresolver& oresolver::operator<<(cell cl) + { + cells_.emplace_back(std::move(cl)); + return *this; + } + + oresolver& oresolver::operator<<(std::nullptr_t) + { + cells_.emplace_back(); + cells_.back().text.assign(1, wchar_t(0)); //means invalid cell + return *this; + } + + std::vector&& oresolver::move_cells() + { + return std::move(cells_); + } + + ::nana::listbox& oresolver::listbox() + { + return *ess_->listbox_ptr; + } + + iresolver& iresolver::operator>>(bool& n) + { + if (pos_ < cells_.size()) + n = (std::stoi(cells_[pos_++].text) == 0); + return *this; + } + + iresolver& iresolver::operator>>(short& n) + { + if (pos_ < cells_.size()) + n = std::stoi(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(unsigned short& n) + { + if (pos_ < cells_.size()) + n = static_cast(std::stoul(cells_[pos_++].text)); + return *this; + } + + iresolver& iresolver::operator>>(int& n) + { + if (pos_ < cells_.size()) + n = std::stoi(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(unsigned int& n) + { + if (pos_ < cells_.size()) + n = std::stoul(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(long& n) + { + if (pos_ < cells_.size()) + n = std::stol(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(unsigned long& n) + { + if (pos_ < cells_.size()) + n = std::stoul(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(long long& n) + { + if (pos_ < cells_.size()) + n = std::stoll(cells_[pos_++].text); + return *this; + } + iresolver& iresolver::operator>>(unsigned long long& n) + { + if (pos_ < cells_.size()) + n = std::stoull(cells_[pos_++].text); + return *this; + } + iresolver& iresolver::operator>>(float& f) + { + if (pos_ < cells_.size()) + f = std::stof(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(double& f) + { + if (pos_ < cells_.size()) + f = std::stod(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(long double& f) + { + if (pos_ < cells_.size()) + f = std::stold(cells_[pos_++].text); + return *this; + } + + iresolver& iresolver::operator>>(std::string& text) + { + if (pos_ < cells_.size()) + text = cells_[pos_++].text; + return *this; + } + + iresolver& iresolver::operator>>(std::wstring& text) + { + if (pos_ < cells_.size()) + text = to_wstring(cells_[pos_++].text); + + return *this; + } + + iresolver::iresolver(const std::vector& cl) + : cells_(cl) + {} + + iresolver& iresolver::operator>>(cell& cl) + { + if (pos_ < cells_.size()) + cl = cells_[pos_++]; + return *this; + } + + iresolver& iresolver::operator>>(std::nullptr_t) + { + ++pos_; + return *this; + } + //end class iresolver/oresolver + class inline_indicator : public ::nana::detail::inline_widget_indicator { @@ -2399,7 +2661,11 @@ namespace nana void modify(index_type pos, const value_type& value) const override { - auto & cells = ess_->lister.at_abs(pos).cells; + ess_->lister.throw_if_immutable_model(pos); + + auto model_cells = ess_->lister.at_model_abs(pos); + auto & cells = ess_->lister.have_model(pos) ? model_cells : ess_->lister.at_abs(pos).cells; + if (cells.size() <= column_pos_) cells.resize(column_pos_ + 1); @@ -2415,6 +2681,10 @@ namespace nana } cells[column_pos_].text = value; + + if (model_cells.size()) + ess_->lister.assign_model(pos, model_cells); + ess_->update(); } } @@ -2472,14 +2742,14 @@ namespace nana start_pos = pos; else { - index_pair last(list_.size() - 1); + index_pair last(categories_.size() - 1); - if (list_.back().expand) + if (categories_.back().expand) { - if (list_.back().items.empty()) + if (categories_.back().items.empty()) last.item = npos; else - last.item = list_.back().items.size() - 1; + last.item = categories_.back().items.size() - 1; } else last.item = ::nana::npos; @@ -2494,11 +2764,17 @@ namespace nana void es_lister::erase(const index_pair& pos) { - auto & catobj = *get(pos.cat); - if (pos.item < catobj.items.size()) + auto & cat = *get(pos.cat); + if (pos.item < cat.items.size()) { - catobj.items.erase(catobj.items.begin() + pos.item); - catobj.sorted.erase(std::find(catobj.sorted.begin(), catobj.sorted.end(), catobj.items.size())); + if (cat.model_ptr) + { + throw_if_immutable_model(cat.model_ptr.get()); + cat.model_ptr->container()->erase(pos.item); + } + + cat.items.erase(cat.items.begin() + pos.item); + cat.sorted.erase(std::find(cat.sorted.begin(), cat.sorted.end(), cat.items.size())); sort(); } @@ -2515,7 +2791,7 @@ namespace nana if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat { bool good = false; - for(size_type i = 0, size = list_.size(); i < size; ++i) // run all cat + for (size_type i = 0, size = categories_.size(); i < size; ++i) // run all cat { if(size_item(i)) { @@ -2614,15 +2890,15 @@ namespace nana return list_str ; } - void es_lister::categ_selected(size_type cat, bool sel) + void es_lister::categ_selected(size_type cat, bool sel) { - cat_proxy cpx{ess_,cat}; - for (item_proxy &it : cpx ) - { - if (it.selected() != sel) + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) + { + if (it.selected() != sel) it.select(sel); - } - last_selected_abs = last_selected_dpl = index_pair{cat, npos}; + } + last_selected_abs = last_selected_dpl = index_pair{cat, npos}; } class drawer_header_impl @@ -2852,8 +3128,11 @@ namespace nana { internal_scope_guard lock; - size_type n = essence_->number_of_lister_items(true); - if(0 == n)return; + //The count of items to be drawn + auto item_count = essence_->number_of_lister_items(true); + if (0 == item_count) + return; + widget * wdptr = essence_->lister.wd_ptr(); auto bgcolor = wdptr->bgcolor(); auto fgcolor = wdptr->fgcolor(); @@ -2909,9 +3188,12 @@ namespace nana std::size_t size = i_categ->items.size(); index_pair item_index{ idx.cat, 0 }; - for(std::size_t offs = essence_->scroll.offset_y_dpl.item; offs < size; ++offs, ++idx.item) + + for (std::size_t offs = essence_->scroll.offset_y_dpl.item; offs < size; ++offs, ++idx.item) { - if(n-- == 0) break; + if (0 == item_count--) + break; + state = (tracker == idx ? item_state::highlighted : item_state::normal); item_index.item = offs; @@ -2925,32 +3207,45 @@ namespace nana ++idx.cat; } - for(; i_categ != lister.cat_container().end(); ++i_categ, ++idx.cat) + if (item_count > 0) { - if(n-- == 0) break; - idx.item = 0; - - state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal); - - _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); - y += essence_->item_size; - - if(false == i_categ->expand) - continue; - - auto size = i_categ->items.size(); - index_pair item_pos{ idx.cat, 0 }; - for(decltype(size) pos = 0; pos < size; ++pos) + for (; i_categ != lister.cat_container().end(); ++i_categ, ++idx.cat) { - if(n-- == 0) break; - state = (idx == tracker ? item_state::highlighted : item_state::normal); + if (0 == item_count--) + break; - item_pos.item = pos; - item_pos.item = lister.absolute(item_pos); + idx.item = 0; - _m_draw_item(*i_categ, item_pos, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); + state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal); + + _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); y += essence_->item_size; - ++idx.item; + + if (false == i_categ->expand) + continue; + + if (item_count > 0) + { + auto size = i_categ->items.size(); + index_pair item_pos{ idx.cat, 0 }; + for (decltype(size) pos = 0; pos < size; ++pos) + { + if (0 == item_count--) + break; + + state = (idx == tracker ? item_state::highlighted : item_state::normal); + + item_pos.item = pos; + item_pos.item = lister.absolute(item_pos); + + _m_draw_item(*i_categ, item_pos, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); + y += essence_->item_size; + if (y >= rect.bottom()) + break; + + ++idx.item; + } + } } } @@ -3009,6 +3304,14 @@ namespace nana { auto & item = cat.items[item_pos.item]; + std::vector model_cells; + if (cat.model_ptr) + { + model_cells = cat.model_ptr->container()->to_cells(item_pos.item); + } + + auto & cells = (cat.model_ptr ? model_cells : item.cells); + if (item.flags.selected) // fetch the "def" colors bgcolor = essence_->scheme_ptr->item_selected; else if (!item.bgcolor.invisible()) @@ -3125,9 +3428,9 @@ namespace nana inline_wdg->indicator->attach(item_pos, inline_wdg); //To reduce the memory usage, the cells may not be allocated - if (item.cells.size() > column_pos) + if (cells.size() > column_pos) { - auto & text = item.cells[column_pos].text; + auto & text = cells[column_pos].text; if (text != inline_wdg->text) { inline_wdg->text = text; @@ -3144,10 +3447,11 @@ namespace nana } } - if (item.cells.size() > column_pos) // process only if the cell is visible + if (cells.size() > column_pos) // process only if the cell is visible { auto cell_txtcolor = fgcolor; - auto & m_cell = item.cells[column_pos]; + auto & m_cell = cells[column_pos]; + nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need @@ -3167,7 +3471,7 @@ namespace nana { graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text, cell_txtcolor); // draw full text of the cell index (column) - if (static_cast(ts.width) > static_cast(header.pixels) - (content_pos + item_xpos)) // it was an excess + if ((ts.width + content_pos) > header.pixels) // it was an excess { //The text is painted over the next subitem // here beging the ... int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->suspension_width); @@ -3187,9 +3491,7 @@ namespace nana } } } - graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast(essence_->item_size) - 1 }, static_cast(0xEBF4F9)); - } item_xpos += static_cast(header.pixels); @@ -3296,17 +3598,20 @@ namespace nana void trigger::attached(widget_reference widget, graph_reference graph) { + essence_->listbox_ptr = static_cast(&widget); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); essence_->graph = &graph; typeface_changed(graph); essence_->lister.bind(essence_, widget); widget.bgcolor(colors::white); + } void trigger::detached() { essence_->graph = nullptr; + essence_->listbox_ptr = nullptr; } void trigger::typeface_changed(graph_reference graph) @@ -3549,16 +3854,18 @@ namespace nana } } - void trigger::dbl_click(graph_reference graph, const arg_mouse&) + void trigger::dbl_click(graph_reference graph, const arg_mouse& arg) { - if (essence_->pointer_where.first == essence_t::parts::header) - if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) + //double click the splitter to automatically adjust the column width + if ((essence_->pointer_where.first == essence_t::parts::header) && (cursor::size_we == essence_->lister.wd_ptr()->cursor())) + { + if (essence_->update_column_width(drawer_header_->item_spliter())) { - //adjust the width of column to its content. - if (essence_->auto_width(drawer_header_->item_spliter() )) - essence_->update(); - return; + refresh(graph); + API::lazy_refresh(); } + return; + } if (essence_->pointer_where.first != essence_t::parts::lister) return; @@ -3572,25 +3879,24 @@ namespace nana if (!item_pos.is_category()) //being the npos of item.second is a category return; - arg_category ai(cat_proxy(essence_, item_pos.cat)); - lister.wd_ptr()->events().category_dbl_click.emit(ai); + arg_listbox_category arg_cat(cat_proxy(essence_, item_pos.cat)); + lister.wd_ptr()->events().category_dbl_click.emit(arg_cat); - if(!ai.category_change_blocked()) - { - bool do_expand = (lister.expand(item_pos.cat) == false); - lister.expand(item_pos.cat, do_expand); + if (!arg_cat.category_change_blocked()){ + bool do_expand = (lister.expand(item_pos.cat) == false); + lister.expand(item_pos.cat, do_expand); - if(false == do_expand) - { - auto last = lister.last(); - size_type n = essence_->number_of_lister_items(false); - if (lister.backward(last, n, last)) - offset_y = last; - } - essence_->adjust_scroll_life(); - refresh(graph); - API::lazy_refresh(); - } + if(false == do_expand) + { + auto last = lister.last(); + size_type n = essence_->number_of_lister_items(false); + if (lister.backward(last, n, last)) + offset_y = last; + } + essence_->adjust_scroll_life(); + refresh(graph); + API::lazy_refresh(); + } } } @@ -3605,8 +3911,8 @@ namespace nana { bool up = false; - if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) - return ; + if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) + return ; switch(arg.key) { @@ -3618,7 +3924,7 @@ namespace nana case L' ': { selection s; - bool ck = ! essence_->lister.item_selected_all_checked(s); + bool ck = ! essence_->lister.item_selected(s); for(auto i : s) item_proxy(essence_, i).check(ck); } @@ -3704,11 +4010,9 @@ namespace nana : ess_(ess), pos_(pos) { + //get the cat of the item specified by pos if (ess) - { - auto i = ess_->lister.get(pos.cat); - cat_ = &(*i); // what is pos is a cat? - } + cat_ = &(*ess->lister.get(pos.cat)); } /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() @@ -3769,8 +4073,6 @@ namespace nana else if (ess_->lister.last_selected_abs == pos_) ess_->lister.last_selected_abs.set_both(npos); - ess_->update(); - ess_->update(); return *this; } @@ -3832,6 +4134,14 @@ namespace nana std::string item_proxy::text(size_type col) const { + if (cat_->model_ptr) + { + auto cells = cat_->model_ptr->container()->to_cells(pos_.item); + if (col < cells.size()) + return cells[col].text; + + return{}; + } return ess_->lister.get_cells(cat_, pos_.item).at(col).text; } @@ -3988,6 +4298,14 @@ namespace nana } } + model_guard cat_proxy::model() + { + if (!cat_->model_ptr) + throw std::runtime_error("nana::listbox has not a model for the category"); + + return{ cat_->model_ptr.get() }; + } + void cat_proxy::append(std::initializer_list arg) { const auto items = columns(); @@ -4072,8 +4390,26 @@ namespace nana { internal_scope_guard lock; + ess_->lister.throw_if_immutable_model(pos_); + + cat_->sorted.push_back(cat_->items.size()); - cat_->items.emplace_back(std::move(s)); + + if (cat_->model_ptr) + { + auto pos = cat_->model_ptr->container()->size(); + cat_->model_ptr->container()->emplace_back(); + auto cells = cat_->model_ptr->container()->to_cells(pos); + if (cells.size()) + cells.front().text.swap(s); + else + cells.emplace_back(std::move(s)); + + cat_->model_ptr->container()->assign(pos, cells); + cat_->items.emplace_back(); + } + else + cat_->items.emplace_back(std::move(s)); auto wd = ess_->lister.wd_ptr(); if(wd && !(API::empty_window(wd->handle()))) @@ -4265,6 +4601,37 @@ namespace nana } } + void cat_proxy::_m_try_append_model(const_virtual_pointer& dptr) + { + if (!cat_->model_ptr) + { + //Throws when appends an object to a listbox which should have a model. + throw std::runtime_error("nana::listbox hasn't a model"); + } + + ess_->lister.throw_if_immutable_model(cat_->model_ptr.get()); + + + auto pos = cat_->model_ptr->container()->size(); + if (cat_->model_ptr->container()->push_back(dptr)) + { + cat_->sorted.push_back(cat_->items.size()); + cat_->items.emplace_back(); + + auto wd = ess_->lister.wd_ptr(); + if (wd && !(API::empty_window(wd->handle()))) + { + auto & m = cat_->items.back(); + m.bgcolor = wd->bgcolor(); + m.fgcolor = wd->fgcolor(); + } + } + else + { + throw std::invalid_argument("nana::listbox, the type of operand object is mismatched with model container value_type"); + } + } + void cat_proxy::_m_cat_by_pos() { if (pos_ >= ess_->lister.size_categ()) @@ -4280,10 +4647,30 @@ namespace nana //A fix for auto_draw, to make sure the inline widget set() issued after value() and value_ptr() are actually set. //Fixed by leobackes(pr#86) - void cat_proxy::_m_update() { + void cat_proxy::_m_update() + { ess_->update(); } + void cat_proxy::_m_reset_model(model_interface* p) + { + if (ess_->listbox_ptr) + { + cat_->model_ptr.reset(p); + cat_->items.clear(); + cat_->sorted.clear(); + + cat_->items.resize(cat_->model_ptr->container()->size()); + for (std::size_t pos = 0; pos < cat_->items.size(); ++pos) + cat_->sorted.push_back(pos); + + ess_->lister.sort(); + + ess_->adjust_scroll_life(); + API::refresh_window(ess_->listbox_ptr->handle()); + } + } + //class cat_proxy //end class cat_proxy @@ -4298,17 +4685,17 @@ namespace nana //Implementation of arg_category //Contributed by leobackes(pr#97) - arg_category::arg_category ( const nana::drawerbase::listbox::cat_proxy& cat ) noexcept + arg_listbox_category::arg_listbox_category(const nana::drawerbase::listbox::cat_proxy& cat) noexcept : category(cat), block_change_(false) { } - void arg_category::block_category_change() const noexcept + void arg_listbox_category::block_category_change() const noexcept { block_change_ = true; } - bool arg_category::category_change_blocked() const noexcept + bool arg_listbox_category::category_change_blocked() const noexcept { return block_change_; } @@ -4391,10 +4778,11 @@ namespace nana ess.update(); return *this; } + unsigned listbox::auto_width(size_type pos, unsigned max) { - auto & ess = _m_ess(); - unsigned max_w = ess.auto_width(pos, max); + auto & ess = _m_ess(); + unsigned max_w = ess.update_column_width(pos, max); ess.update(); return max_w; } @@ -4673,11 +5061,11 @@ namespace nana return !_m_ess().lister.active_sort(!freeze); } - auto listbox::selected() const -> selection // change to: selection selected(); + auto listbox::selected() const -> selection { selection s; _m_ess().lister.item_selected(s); // absolute positions, no relative to display - return std::move(s); + return s; } void listbox::show_header(bool sh) @@ -4740,7 +5128,7 @@ namespace nana return _m_ess().lister.anyobj(index_pair{cat, index}, allocate_if_empty); } - drawerbase::listbox::category_t* listbox::_m_at_key(std::shared_ptr ptr) + drawerbase::listbox::category_t* listbox::_m_at_key(std::shared_ptr& ptr) { auto & ess = _m_ess(); From e4adb22fa2b57a90e968bd9c8d83924421b0da70 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 9 Apr 2016 05:06:30 +0800 Subject: [PATCH 134/309] fix a GCC compiler error --- include/nana/gui/widgets/listbox.hpp | 12 ++++++------ source/gui/widgets/listbox.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index e54b7415..eb6b31d3 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -74,7 +74,7 @@ namespace nana } template - const typename std::remove_const::type *get() + const typename std::remove_const::type *get() const { using value_type = typename std::remove_const::type; auto target = dynamic_cast*>(intern_); @@ -129,7 +129,7 @@ namespace nana virtual void assign(std::size_t pos, const std::vector& cells) = 0; virtual std::vector to_cells(std::size_t pos) const = 0; - virtual bool push_back(const_virtual_pointer&) = 0; + virtual bool push_back(const const_virtual_pointer&) = 0; virtual void * pointer() = 0; virtual const void* pointer() const = 0; @@ -214,7 +214,7 @@ namespace nana return translator_.to_cell(container_.at(pos)); } - bool push_back(const_virtual_pointer& dptr) override + bool push_back(const const_virtual_pointer& dptr) override { auto value = dptr.get(); if (value) @@ -303,7 +303,7 @@ namespace nana return translator_.to_cell(container_.at(pos)); } - bool push_back(const_virtual_pointer& dptr) override + bool push_back(const const_virtual_pointer& dptr) override { auto value = dptr.get(); if (value) @@ -385,7 +385,7 @@ namespace nana return ctrans_(container_.at(pos)); } - bool push_back(const_virtual_pointer& dptr) override + bool push_back(const const_virtual_pointer& dptr) override { throw std::runtime_error("nana::listbox disallow to remove items because of immutable model"); } @@ -997,7 +997,7 @@ namespace nana void inline_factory(size_type column, pat::cloneable> factory); private: void _m_append(std::vector && cells); - void _m_try_append_model(const_virtual_pointer&); + void _m_try_append_model(const const_virtual_pointer&); void _m_cat_by_pos(); void _m_update(); void _m_reset_model(model_interface*); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 0ff2ff24..058dc61c 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -4601,7 +4601,7 @@ namespace nana } } - void cat_proxy::_m_try_append_model(const_virtual_pointer& dptr) + void cat_proxy::_m_try_append_model(const const_virtual_pointer& dptr) { if (!cat_->model_ptr) { From 88b9149f54580fdc32bff21d5f3b2ccb23012e99 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 10 Apr 2016 14:38:44 +0800 Subject: [PATCH 135/309] remove bedrock::emit_drawer() --- include/nana/gui/detail/bedrock.hpp | 1 - source/gui/detail/bedrock_posix.cpp | 37 +++++--------------------- source/gui/detail/bedrock_windows.cpp | 38 +++++++-------------------- 3 files changed, 16 insertions(+), 60 deletions(-) diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index e29c1758..7af9eb4e 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -87,7 +87,6 @@ namespace detail void manage_form_loader(core_window_t*, bool insert_or_remove); public: bool emit(event_code, core_window_t*, const event_arg&, bool ask_update, thread_context*); - bool emit_drawer(event_code, core_window_t*, const event_arg&, thread_context*); private: void _m_emit_core(event_code, core_window_t*, bool draw_only, const event_arg&); void _m_event_filter(event_code, core_window_t*, thread_context*); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index d5b9a282..2fe3b4ba 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -398,29 +398,6 @@ namespace detail return true; } - bool bedrock::emit_drawer(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, thread_context* thrd) - { - if(wd_manager().available(wd) == false) - return false; - - core_window_t * prev_wd; - if(thrd) - { - prev_wd = thrd->event_window; - thrd->event_window = wd; - _m_event_filter(evt_code, wd, thrd); - } - - if(wd->other.upd_state == core_window_t::update_state::none) - wd->other.upd_state = core_window_t::update_state::lazy; - - _m_emit_core(evt_code, wd, true, arg); - - if(thrd) thrd->event_window = prev_wd; - return true; - - } - void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt) { arg.window_handle = reinterpret_cast(wd); @@ -554,7 +531,7 @@ namespace detail } template - void emit_drawer(void(::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) + void draw_invoker(void(::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) { if(bedrock::instance().wd_manager().available(wd) == false) return; @@ -790,7 +767,7 @@ namespace detail { //call the drawer mouse up event for restoring the surface graphics msgwnd->flags.action = mouse_action::normal; - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); brock.wd_manager().do_lazy_refresh(msgwnd, false); } } @@ -848,7 +825,7 @@ namespace detail msgwnd->flags.action = mouse_action::over; click_arg.window_handle = reinterpret_cast(msgwnd); - emit_drawer(&drawer::click, msgwnd, click_arg, &context); + draw_invoker(&drawer::click, msgwnd, click_arg, &context); } } @@ -862,7 +839,7 @@ namespace detail auto evt_ptr = retain.get(); arg.evt_code = event_code::mouse_up; - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); if(click_arg.window_handle) evt_ptr->click.emit(click_arg); @@ -1076,7 +1053,7 @@ namespace detail pressed_wd_space = msgwnd; auto retain = msgwnd->together.events_ptr; - emit_drawer(&drawer::mouse_down, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_down, msgwnd, arg, &context); wd_manager.do_lazy_refresh(msgwnd, false); } } @@ -1168,7 +1145,7 @@ namespace detail brock.get_key_state(arg); msgwnd->together.events_ptr->key_char.emit(arg); if(arg.ignore == false && wd_manager.available(msgwnd)) - brock.emit_drawer(event_code::key_char, msgwnd, arg, &context); + draw_invoker(&drawer::key_char, msgwnd, arg, &context); } if(brock.set_keyboard_shortkey(false)) @@ -1224,7 +1201,7 @@ namespace detail arg.pos.y = 0; arg.window_handle = reinterpret_cast(msgwnd); - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); brock.wd_manager().do_lazy_refresh(msgwnd, false); } pressed_wd_space = nullptr; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 8b3cb978..37ec28a0 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -756,7 +756,7 @@ namespace detail } template - void emit_drawer(void (::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) + void draw_invoker(void (::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd) { if (bedrock::instance().wd_manager().available(wd) == false) return; @@ -990,7 +990,7 @@ namespace detail msgwnd->flags.action = mouse_action::normal; arg.evt_code = event_code::mouse_up; - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); brock.wd_manager().do_lazy_refresh(msgwnd, false); } } @@ -1031,7 +1031,7 @@ namespace detail if ((::nana::mouse::left_button == arg.button) && (pressed_wd == msgwnd)) { click_arg.window_handle = reinterpret_cast(msgwnd); - emit_drawer(&drawer::click, msgwnd, click_arg, &context); + draw_invoker(&drawer::click, msgwnd, click_arg, &context); } } @@ -1039,7 +1039,7 @@ namespace detail if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled) { arg.evt_code = event_code::mouse_up; - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); if (click_arg.window_handle) retain->click.emit(click_arg); @@ -1169,7 +1169,8 @@ namespace detail arg_wheel arg; arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); assign_arg(arg, scrolled_wd, pmdec); - brock.emit_drawer(event_code::mouse_wheel, scrolled_wd, arg, &context); + + draw_invoker(&drawer::mouse_wheel, scrolled_wd, arg, &context); brock.wd_manager().do_lazy_refresh(scrolled_wd, false); } } @@ -1450,7 +1451,7 @@ namespace detail pressed_wd_space = msgwnd; auto retain = msgwnd->together.events_ptr; - emit_drawer(&drawer::mouse_down, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_down, msgwnd, arg, &context); wd_manager.do_lazy_refresh(msgwnd, false); } } @@ -1496,7 +1497,7 @@ namespace detail msgwnd->together.events_ptr->key_char.emit(arg); if ((false == arg.ignore) && wd_manager.available(msgwnd)) - brock.emit_drawer(event_code::key_char, msgwnd, arg, &context); + draw_invoker(&drawer::key_char, msgwnd, arg, &context); wd_manager.do_lazy_refresh(msgwnd, false); } @@ -1536,7 +1537,7 @@ namespace detail arg.pos.y = 0; arg.window_handle = reinterpret_cast(msgwnd); - emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); brock.wd_manager().do_lazy_refresh(msgwnd, false); } pressed_wd_space = nullptr; @@ -1793,27 +1794,6 @@ namespace detail return true; } - bool bedrock::emit_drawer(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, thread_context* thrd) - { - if (bedrock_object.wd_manager().available(wd) == false) - return false; - - core_window_t* prev_event_wd; - if (thrd) - { - prev_event_wd = thrd->event_window; - thrd->event_window = wd; - } - - if (wd->other.upd_state == core_window_t::update_state::none) - wd->other.upd_state = core_window_t::update_state::lazy; - - _m_emit_core(evt_code, wd, true, arg); - - if (thrd) thrd->event_window = prev_event_wd; - return true; - } - const wchar_t* translate(cursor id) { const wchar_t* name = IDC_ARROW; From 07b5b195455ea1db402619861737dabab7696f86 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 10 Apr 2016 15:23:44 +0800 Subject: [PATCH 136/309] improve stability of event --- include/nana/gui/detail/events_operation.hpp | 5 --- include/nana/gui/detail/general_events.hpp | 11 ++++- include/nana/gui/widgets/categorize.hpp | 2 +- include/nana/gui/widgets/scroll.hpp | 2 +- include/nana/gui/widgets/tabbar.hpp | 6 +-- source/gui/detail/bedrock_pi.cpp | 46 ++++++++++---------- source/gui/detail/bedrock_posix.cpp | 10 ++--- source/gui/detail/bedrock_windows.cpp | 38 +++++++++------- source/gui/detail/events_operation.cpp | 17 ++------ source/gui/detail/window_manager.cpp | 9 ++-- source/gui/notifier.cpp | 10 ++--- source/gui/programming_interface.cpp | 9 ++-- source/gui/timer.cpp | 2 +- source/gui/widgets/checkbox.cpp | 4 +- source/gui/widgets/combox.cpp | 4 +- source/gui/widgets/date_chooser.cpp | 2 +- source/gui/widgets/listbox.cpp | 24 +++++----- source/gui/widgets/slider.cpp | 2 +- source/gui/widgets/spinbox.cpp | 2 +- source/gui/widgets/tabbar.cpp | 4 +- source/gui/widgets/textbox.cpp | 6 +-- source/gui/widgets/toolbar.cpp | 8 ++-- source/gui/widgets/treebox.cpp | 16 +++---- 23 files changed, 118 insertions(+), 121 deletions(-) diff --git a/include/nana/gui/detail/events_operation.hpp b/include/nana/gui/detail/events_operation.hpp index 025ef5b1..e28b9af3 100644 --- a/include/nana/gui/detail/events_operation.hpp +++ b/include/nana/gui/detail/events_operation.hpp @@ -3,8 +3,6 @@ #include #include -#include -#include #if defined(STD_THREAD_NOT_SUPPORTED) #include @@ -19,15 +17,12 @@ namespace nana class events_operation { public: - void make(window, const std::shared_ptr &); - void umake(window); void register_evt(event_handle); void cancel(event_handle); void erase(event_handle); private: std::recursive_mutex mutex_; std::unordered_set handles_; - std::unordered_map> evt_table_; }; }//end namespace detail }//end namespace nana diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index c49cab98..8986ee73 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -23,8 +23,8 @@ namespace nana { namespace detail { + bool check_window(window); void events_operation_register(event_handle); - void events_operation_cancel(event_handle); class event_interface { @@ -161,7 +161,7 @@ namespace nana return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), true), in_front); } - void emit(arg_reference& arg) + void emit(arg_reference& arg, window window_handle) { internal_scope_guard lock; if (nullptr == dockers_) @@ -181,6 +181,10 @@ namespace nana continue; static_cast(*i)->invoke(arg); + + if (window_handle && (!detail::check_window(window_handle))) + break; + if (arg.propagation_stopped()) { for (++i; i != end; ++i) @@ -189,6 +193,9 @@ namespace nana continue; static_cast(*i)->invoke(arg); + + if (window_handle && (!detail::check_window(window_handle))) + break; } break; } diff --git a/include/nana/gui/widgets/categorize.hpp b/include/nana/gui/widgets/categorize.hpp index 3b8f5b3c..d2a19141 100644 --- a/include/nana/gui/widgets/categorize.hpp +++ b/include/nana/gui/widgets/categorize.hpp @@ -66,7 +66,7 @@ namespace nana T null_val; arg_categorize arg(widget_, vp ? *vp : null_val); - widget_.events().selected.emit(arg); + widget_.events().selected.emit(arg, widget_.handle()); } private: ::nana::categorize & widget_; diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 96d1b023..1cf5bb83 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -314,7 +314,7 @@ namespace nana private: void _m_emit_value_changed() { - widget_->events().value_changed.emit({ widget_->handle() }); + widget_->events().value_changed.emit({ widget_->handle() }, widget_->handle()); } void _m_tick() diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index b7a88789..ac009ee7 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -111,14 +111,14 @@ namespace nana if(pos != npos) { drawer_trigger_.at_no_bound_check(pos) = T(); - tabbar_.events().added.emit(arg_tabbar({ tabbar_, tabbar_[pos] })); + tabbar_.events().added.emit(arg_tabbar({ tabbar_, tabbar_[pos] }), tabbar_); } } void activated(std::size_t pos) override { if(pos != npos) - tabbar_.events().activated.emit(arg_tabbar({ tabbar_, tabbar_[pos]})); + tabbar_.events().activated.emit(arg_tabbar({ tabbar_, tabbar_[pos]}), tabbar_); } bool removed(std::size_t pos, bool & close_attach) override @@ -126,7 +126,7 @@ namespace nana if (pos != npos) { ::nana::arg_tabbar_removed arg(tabbar_, tabbar_[pos]); - tabbar_.events().removed.emit(arg); + tabbar_.events().removed.emit(arg, tabbar_); close_attach = arg.close_attach_window; return arg.remove; } diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 7c7472bb..e8166cf6 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -51,16 +51,16 @@ namespace nana namespace detail { + bool check_window(window wd) + { + return bedrock::instance().wd_manager().available(reinterpret_cast(wd)); + } + void events_operation_register(event_handle evt) { bedrock::instance().evt_operation().register_evt(evt); } - void events_operation_cancel(event_handle evt) - { - bedrock::instance().evt_operation().cancel(evt); - } - class bedrock::flag_guard { public: @@ -213,21 +213,21 @@ namespace nana auto retain = wd->together.events_ptr; auto evts_ptr = retain.get(); - switch (evt_code) { case event_code::click: { auto arg = dynamic_cast(&event_arg); - if (nullptr == arg) - return; + if (arg) { - //enable refreshing flag, this is a RAII class for exception-safe - flag_guard fguard(this, wd); - wd->drawer.click(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.click(*arg); + } + if (!draw_only) + evts_ptr->click.emit(*arg, reinterpret_cast(wd)); } - if (!draw_only) - evts_ptr->click.emit(*arg); } break; case event_code::dbl_click: @@ -281,7 +281,7 @@ namespace nana } if (!draw_only) - evt_addr->emit(*arg); + evt_addr->emit(*arg, reinterpret_cast(wd)); break; } case event_code::mouse_wheel: @@ -296,7 +296,7 @@ namespace nana } if (!draw_only) - evts_ptr->mouse_wheel.emit(*arg); + evts_ptr->mouse_wheel.emit(*arg, reinterpret_cast(wd)); } break; } @@ -340,7 +340,7 @@ namespace nana } if (!draw_only) - evt_addr->emit(*arg); + evt_addr->emit(*arg, reinterpret_cast(wd)); break; } case event_code::expose: @@ -348,7 +348,7 @@ namespace nana { auto arg = dynamic_cast(&event_arg); if (arg) - evts_ptr->expose.emit(*arg); + evts_ptr->expose.emit(*arg, reinterpret_cast(wd)); } break; case event_code::focus: @@ -362,7 +362,7 @@ namespace nana wd->drawer.focus(*arg); } if (!draw_only) - evts_ptr->focus.emit(*arg); + evts_ptr->focus.emit(*arg, reinterpret_cast(wd)); } break; } @@ -377,7 +377,7 @@ namespace nana wd->drawer.move(*arg); } if (!draw_only) - evts_ptr->move.emit(*arg); + evts_ptr->move.emit(*arg, reinterpret_cast(wd)); } break; } @@ -392,7 +392,7 @@ namespace nana wd->drawer.resizing(*arg); } if (!draw_only) - evts_ptr->resizing.emit(*arg); + evts_ptr->resizing.emit(*arg, reinterpret_cast(wd)); } break; } @@ -407,7 +407,7 @@ namespace nana wd->drawer.resized(*arg); } if (!draw_only) - evts_ptr->resized.emit(*arg); + evts_ptr->resized.emit(*arg, reinterpret_cast(wd)); } break; } @@ -419,7 +419,7 @@ namespace nana { auto evt_root = dynamic_cast(evts_ptr); if (evt_root) - evt_root->unload.emit(*arg); + evt_root->unload.emit(*arg, reinterpret_cast(wd)); } } break; @@ -428,7 +428,7 @@ namespace nana { auto arg = dynamic_cast(&event_arg); if (arg) - evts_ptr->destroy.emit(*arg); + evts_ptr->destroy.emit(*arg, reinterpret_cast(wd)); } break; default: diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 2fe3b4ba..071623ee 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -520,7 +520,7 @@ namespace detail delete msg.u.mouse_drop.files; arg.pos.x = msg.u.mouse_drop.x - msgwd->pos_root.x; arg.pos.y = msg.u.mouse_drop.y - msgwd->pos_root.y; - msgwd->together.events_ptr->mouse_dropfiles.emit(arg); + msgwd->together.events_ptr->mouse_dropfiles.emit(arg, reinterpret_cast(msgwd)); brock.wd_manager().do_lazy_refresh(msgwd, false); } break; @@ -842,16 +842,16 @@ namespace detail draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); if(click_arg.window_handle) - evt_ptr->click.emit(click_arg); + evt_ptr->click.emit(click_arg, reinterpret_cast(msgwnd)); if (brock.wd_manager().available(msgwnd)) { arg.evt_code = event_code::mouse_up; - evt_ptr->mouse_up.emit(arg); + evt_ptr->mouse_up.emit(arg, reinterpret_cast(msgwnd)); } } else if(click_arg.window_handle) - msgwnd->together.events_ptr->click.emit(click_arg); + msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast(msgwnd)); brock.wd_manager().do_lazy_refresh(msgwnd, false); } @@ -1143,7 +1143,7 @@ namespace detail arg.evt_code = event_code::key_char; arg.window_handle = reinterpret_cast(msgwnd); brock.get_key_state(arg); - msgwnd->together.events_ptr->key_char.emit(arg); + msgwnd->together.events_ptr->key_char.emit(arg, reinterpret_cast(msgwnd)); if(arg.ignore == false && wd_manager.available(msgwnd)) draw_invoker(&drawer::key_char, msgwnd, arg, &context); } diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 37ec28a0..949d34ae 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -931,10 +931,7 @@ namespace detail arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); if (brock.emit(arg.evt_code, msgwnd, arg, true, &context)) - { - if (brock.wd_manager().available(msgwnd)) - pressed_wd = msgwnd; - } + pressed_wd = msgwnd; } break; case WM_NCLBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_NCRBUTTONDOWN: @@ -1042,16 +1039,16 @@ namespace detail draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); if (click_arg.window_handle) - retain->click.emit(click_arg); + retain->click.emit(click_arg, reinterpret_cast(msgwnd)); if (brock.wd_manager().available(msgwnd)) { arg.evt_code = event_code::mouse_up; - retain->mouse_up.emit(arg); + retain->mouse_up.emit(arg, reinterpret_cast(msgwnd)); } } else if (click_arg.window_handle) - retain->click.emit(click_arg); + retain->click.emit(click_arg, reinterpret_cast(msgwnd)); brock.wd_manager().do_lazy_refresh(msgwnd, false); } @@ -1119,8 +1116,11 @@ namespace detail brock.emit(event_code::mouse_enter, msgwnd, arg, true, &context); } - arg.evt_code = event_code::mouse_move; - brock.emit(event_code::mouse_move, msgwnd, arg, true, &context); + if (hovered_wd) + { + arg.evt_code = event_code::mouse_move; + brock.emit(event_code::mouse_move, msgwnd, arg, true, &context); + } track.hwndTrack = native_window; restrict::track_mouse_event(&track); } @@ -1223,7 +1223,7 @@ namespace detail brock.wd_manager().calc_window_point(msgwnd, dropfiles.pos); dropfiles.window_handle = reinterpret_cast(msgwnd); - msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles); + msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast(msgwnd)); brock.wd_manager().do_lazy_refresh(msgwnd, false); } } @@ -1495,7 +1495,7 @@ namespace detail brock.get_key_state(arg); arg.ignore = false; - msgwnd->together.events_ptr->key_char.emit(arg); + msgwnd->together.events_ptr->key_char.emit(arg, reinterpret_cast(msgwnd)); if ((false == arg.ignore) && wd_manager.available(msgwnd)) draw_invoker(&drawer::key_char, msgwnd, arg, &context); @@ -1785,13 +1785,19 @@ namespace detail _m_emit_core(evt_code, wd, false, arg); - if (ask_update) - wd_manager().do_lazy_refresh(wd, false); - else if (wd_manager().available(wd)) - wd->other.upd_state = basic_window::update_state::none; + bool good_wd = false; + if (wd_manager().available(wd)) + { + if (ask_update) + wd_manager().do_lazy_refresh(wd, false); + else + wd->other.upd_state = basic_window::update_state::none; + + good_wd = true; + } if (thrd) thrd->event_window = prev_event_wd; - return true; + return good_wd; } const wchar_t* translate(cursor id) diff --git a/source/gui/detail/events_operation.cpp b/source/gui/detail/events_operation.cpp index bff546ca..bcafd688 100644 --- a/source/gui/detail/events_operation.cpp +++ b/source/gui/detail/events_operation.cpp @@ -1,4 +1,5 @@ #include +#include namespace nana { @@ -7,18 +8,6 @@ namespace nana //class events_operation using lock_guard = std::lock_guard; - void events_operation::make(window wd, const std::shared_ptr& sp) - { - lock_guard lock(mutex_); - evt_table_[wd] = sp; - } - - void events_operation::umake(window wd) - { - lock_guard lock(mutex_); - evt_table_.erase(wd); - } - void events_operation::register_evt(event_handle evt) { lock_guard lock(mutex_); @@ -72,9 +61,11 @@ namespace nana internal_scope_guard lock; if (dockers_) { + auto & evt_operation = bedrock::instance().evt_operation(); + for (auto p : *dockers_) { - detail::events_operation_cancel(reinterpret_cast(p)); + evt_operation.cancel(reinterpret_cast(p)); delete p; } dockers_->clear(); diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index fa81d30d..5e1ee247 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -86,13 +86,12 @@ namespace detail private: std::vector table_; }; - //class window_manager + //class window_manager struct window_handle_deleter { void operator()(basic_window* wd) const { - bedrock::instance().evt_operation().umake(reinterpret_cast(wd)); delete wd; } }; @@ -399,7 +398,7 @@ namespace detail if (wd->flags.destroying) return; - if(wd->other.category == category::root_tag::value) + if(category::flags::root == wd->other.category) { auto &brock = bedrock::instance(); arg_unload arg; @@ -844,10 +843,10 @@ namespace detail //Thread-Safe Required! std::lock_guard lock(mutex_); - //It's not worthy to redraw if visible is false if (false == impl_->wd_register.available(wd)) return false; + //It's not worthy to redraw if visible is false if(wd->visible && (!wd->is_draw_through())) { if (wd->visible_parents()) @@ -1573,7 +1572,7 @@ namespace detail wd->drawer.detached(); wd->widget_notifier->destroy(); - if(wd->other.category == category::frame_tag::value) + if(category::flags::frame == wd->other.category) { //The frame widget does not have an owner, and close their element windows without activating owner. //close the frame container window, it's a native window. diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 4e98e037..3aa9cca9 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -169,19 +169,19 @@ namespace nana switch (arg.evt_code) { case event_code::mouse_down: - evt_ptr->mouse_down.emit(arg); + evt_ptr->mouse_down.emit(arg, nullptr); break; case event_code::mouse_up: - evt_ptr->mouse_up.emit(arg); + evt_ptr->mouse_up.emit(arg, nullptr); break; case event_code::mouse_leave: - evt_ptr->mouse_leave.emit(arg); + evt_ptr->mouse_leave.emit(arg, nullptr); break; case event_code::mouse_move: - evt_ptr->mouse_move.emit(arg); + evt_ptr->mouse_move.emit(arg, nullptr); break; case event_code::dbl_click: - evt_ptr->dbl_click.emit(arg); + evt_ptr->dbl_click.emit(arg, nullptr); break; default: break; diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index c645de9a..a13e81cd 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -184,12 +184,11 @@ namespace API { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; - if (restrict::wd_manager().available(iwd) && iwd->set_events(gep)) - { - restrict::bedrock.evt_operation().make(wd, gep); - return true; - } + + if (restrict::wd_manager().available(iwd)) + iwd->set_events(gep); return false; + } void set_scheme(window wd, widget_colors* wdg_colors) diff --git a/source/gui/timer.cpp b/source/gui/timer.cpp index 58a6700e..589d0107 100644 --- a/source/gui/timer.cpp +++ b/source/gui/timer.cpp @@ -135,7 +135,7 @@ namespace nana void emit(const arg_elapse& arg) { - evt_elapse_.emit(arg); + evt_elapse_.emit(arg, nullptr); } private: const timer_identifier timer_; diff --git a/source/gui/widgets/checkbox.cpp b/source/gui/widgets/checkbox.cpp index 4a14a7fc..a99d02f4 100644 --- a/source/gui/widgets/checkbox.cpp +++ b/source/gui/widgets/checkbox.cpp @@ -94,7 +94,7 @@ namespace nana{ namespace drawerbase { impl_->crook.reverse(); arg_checkbox arg{ static_cast(impl_->widget_ptr) }; - API::events(impl_->widget_ptr->handle()).checked.emit(arg); + API::events(impl_->widget_ptr->handle()).checked.emit(arg, impl_->widget_ptr->handle()); } refresh(graph); API::lazy_refresh(); @@ -172,7 +172,7 @@ namespace nana{ namespace drawerbase API::refresh_window(handle()); arg_checkbox arg(this); - this->events().checked.emit(arg); + this->events().checked.emit(arg, this->handle()); } } diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index 6d803e18..ed39ba8e 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -41,7 +41,7 @@ namespace nana void text_changed() override { - widget_.events().text_changed.emit(::nana::arg_combox{ widget_ }); + widget_.events().text_changed.emit(::nana::arg_combox{ widget_ }, widget_); } private: ::nana::combox & widget_; @@ -355,7 +355,7 @@ namespace nana _m_draw_push_button(widget_->enabled()); _m_draw_image(); - widget_->events().selected.emit(::nana::arg_combox(*widget_)); + widget_->events().selected.emit(::nana::arg_combox(*widget_), widget_->handle()); } } diff --git a/source/gui/widgets/date_chooser.cpp b/source/gui/widgets/date_chooser.cpp index 817f8acf..3c8a1fb6 100644 --- a/source/gui/widgets/date_chooser.cpp +++ b/source/gui/widgets/date_chooser.cpp @@ -480,7 +480,7 @@ namespace nana chose_ = true; arg_datechooser evt_arg{ static_cast(API::get_widget(window_handle)) }; - API::events(window_handle).date_changed.emit(evt_arg); + API::events(window_handle).date_changed.emit(evt_arg, window_handle); } bool chose() const diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 96b423e3..007615cd 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1208,7 +1208,7 @@ namespace nana m.flags.checked = ck; arg_listbox arg{ item_proxy{ess_, pos}, ck}; - wd_ptr()->events().checked.emit(arg); + wd_ptr()->events().checked.emit(arg, wd_ptr()->handle()); } ++pos.item; } @@ -1279,7 +1279,7 @@ namespace nana m.flags.selected = sel; arg_listbox arg{ item_proxy(ess_, i), sel }; - wd_ptr()->events().selected.emit(arg); + wd_ptr()->events().selected.emit(arg, wd_ptr()->handle()); if (m.flags.selected) last_selected_abs = i; @@ -1371,12 +1371,12 @@ namespace nana if (for_selection) { m.flags.selected = false; - widget_->events().selected.emit(arg); + widget_->events().selected.emit(arg, widget_->handle()); } else { m.flags.checked = false; - widget_->events().checked.emit(arg); + widget_->events().checked.emit(arg, widget_->handle()); } }; @@ -1454,12 +1454,12 @@ namespace nana if (for_selection) { m.flags.selected = false; - widget_->events().selected.emit(arg); + widget_->events().selected.emit(arg, widget_->handle()); } else { m.flags.checked = false; - widget_->events().checked.emit(arg); + widget_->events().checked.emit(arg, widget_->handle()); } }; @@ -1554,7 +1554,7 @@ namespace nana m.flags.checked = ck; arg_listbox arg{ item_proxy(ess_, index_pair(cat, index)), ck}; - wd_ptr()->events().checked.emit(arg); + wd_ptr()->events().checked.emit(arg, widget_->handle()); changed = true; } @@ -3456,7 +3456,7 @@ namespace nana index_pair last_selected(item_pos.cat, lister.absolute(item_pos)); arg_listbox arg{item_proxy{essence_, last_selected}, sel}; - lister.wd_ptr()->events().selected.emit(arg); + lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle()); if (item_ptr->flags.selected) { @@ -3478,7 +3478,7 @@ namespace nana index_pair abs_pos{ item_pos.cat, lister.absolute(item_pos) }; arg_listbox arg{ item_proxy{ essence_, abs_pos }, item_ptr->flags.checked }; - lister.wd_ptr()->events().checked.emit(arg); + lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle()); if (item_ptr->flags.checked) lister.cancel_others_if_single_enabled(false, abs_pos); @@ -3572,7 +3572,7 @@ namespace nana return; arg_listbox_category arg_cat(cat_proxy(essence_, item_pos.cat)); - lister.wd_ptr()->events().category_dbl_click.emit(arg_cat); + lister.wd_ptr()->events().category_dbl_click.emit(arg_cat, lister.wd_ptr()->handle()); if (!arg_cat.category_change_blocked()){ bool do_expand = (lister.expand(item_pos.cat) == false); @@ -3741,7 +3741,7 @@ namespace nana { m.flags.checked = ck; arg_listbox arg{*this, ck}; - ess_->lister.wd_ptr()->events().checked.emit(arg); + ess_->lister.wd_ptr()->events().checked.emit(arg, ess_->lister.wd_ptr()->handle()); ess_->update(); } return *this; @@ -3760,7 +3760,7 @@ namespace nana m.flags.selected = s; // actually change selection arg_listbox arg{*this, s}; - ess_->lister.wd_ptr()->events().selected.emit(arg); + ess_->lister.wd_ptr()->events().selected.emit(arg, ess_->lister.wd_ptr()->handle()); if (m.flags.selected) { diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index 72fb50ca..45fbd122 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -385,7 +385,7 @@ namespace nana private: void _m_emit_value_changed() const { - other_.widget->events().value_changed.emit(::nana::arg_slider{ *other_.widget }); + other_.widget->events().value_changed.emit(::nana::arg_slider{ *other_.widget }, other_.widget->handle()); } nana::rectangle _m_bar_area() const diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 880fa7f1..90397d41 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -38,7 +38,7 @@ namespace nana void text_changed() override { - widget_.events().text_changed.emit(::nana::arg_spinbox{ widget_ }); + widget_.events().text_changed.emit(::nana::arg_spinbox{ widget_ }, widget_.handle()); } private: ::nana::spinbox & widget_; diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index 8aa7037e..796fe2af 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -1562,7 +1562,7 @@ namespace nana API::lazy_refresh(); event_arg arg; - model_->widget_ptr()->events().selected.emit(arg); + model_->widget_ptr()->events().selected.emit(arg, model_->widget_ptr()->handle()); } } //end class driver @@ -1701,7 +1701,7 @@ namespace nana if (selection_changed && (active_pos != npos)) { event_arg arg; - events().selected.emit(arg); + events().selected.emit(arg, handle()); } } //end class tabbar diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 3567d87e..f2a168ef 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -30,18 +30,18 @@ namespace drawerbase { void event_agent::first_change() { - widget_.events().first_change.emit(::nana::arg_textbox{ widget_, text_position_ }); + widget_.events().first_change.emit(::nana::arg_textbox{ widget_, text_position_ }, widget_); } void event_agent::text_changed() { - widget_.events().text_changed.emit(::nana::arg_textbox{ widget_, text_position_ }); + widget_.events().text_changed.emit(::nana::arg_textbox{ widget_, text_position_ }, widget_); } void event_agent::text_exposed(const std::vector& text_pos) { ::nana::arg_textbox arg(widget_, text_pos); - widget_.events().text_exposed.emit(arg); + widget_.events().text_exposed.emit(arg, widget_); } //end class event_agent diff --git a/source/gui/widgets/toolbar.cpp b/source/gui/widgets/toolbar.cpp index 6cf81234..728e5f2f 100644 --- a/source/gui/widgets/toolbar.cpp +++ b/source/gui/widgets/toolbar.cpp @@ -308,7 +308,7 @@ namespace nana if (impl_->which != npos && container.at(impl_->which)->enable) { ::nana::arg_toolbar arg{ *widget_, impl_->which }; - widget_->events().leave.emit(arg); + widget_->events().leave.emit(arg, widget_->handle()); } impl_->which = which; @@ -322,7 +322,7 @@ namespace nana if (impl_->state == item_renderer::state_t::highlighted) { ::nana::arg_toolbar arg{ *widget_, which }; - widget_->events().enter.emit(arg); + widget_->events().enter.emit(arg, widget_->handle()); } } @@ -346,7 +346,7 @@ namespace nana if (which != npos && impl_->items.at(which)->enable) { ::nana::arg_toolbar arg{ *widget_, which }; - widget_->events().leave.emit(arg); + widget_->events().leave.emit(arg, widget_->handle()); } } impl_->tooltip.close(); @@ -371,7 +371,7 @@ namespace nana if(impl_->which == which) { ::nana::arg_toolbar arg{ *widget_, which }; - widget_->events().selected.emit(arg); + widget_->events().selected.emit(arg, widget_->handle()); impl_->state = item_renderer::state_t::highlighted; } diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 73913ba3..3f3b55ee 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -496,7 +496,7 @@ namespace nana { data.stop_drawing = true; item_proxy iprx(data.trigger_ptr, node); - data.widget_ptr->events().checked.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, (checkstate::unchecked != cs) }); + data.widget_ptr->events().checked.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, (checkstate::unchecked != cs) }, data.widget_ptr->handle()); data.stop_drawing = false; } return true; @@ -512,14 +512,14 @@ namespace nana if (node_state.selected) { item_proxy iprx(data.trigger_ptr, node_state.selected); - data.widget_ptr->events().selected.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, false }); + data.widget_ptr->events().selected.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, false }, data.widget_ptr->handle()); } node_state.selected = node; if (node) { item_proxy iprx(data.trigger_ptr, node_state.selected); - data.widget_ptr->events().selected.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, true }); + data.widget_ptr->events().selected.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, true }, data.widget_ptr->handle()); } data.stop_drawing = false; return true; @@ -544,7 +544,7 @@ namespace nana data.stop_drawing = true; //attr.ext_event.expand(data.widget_ptr->handle(), item_proxy(data.trigger_ptr, node), value); item_proxy iprx(data.trigger_ptr, node); - data.widget_ptr->events().expanded.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, value }); + data.widget_ptr->events().expanded.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, value }, data.widget_ptr->handle()); data.stop_drawing = false; } return true; @@ -682,7 +682,7 @@ namespace nana if (node_state.pointed) { item_proxy iprx(data.trigger_ptr, node_state.pointed); - data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, false }); + data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, false }, data.widget_ptr->handle()); if (nl.node() != node_state.pointed) close_tooltip_window(); @@ -691,7 +691,7 @@ namespace nana node_state.pointed = nl.node(); item_proxy iprx(data.trigger_ptr, node_state.pointed); - data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, true }); + data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, true }, data.widget_ptr->handle()); redraw = (node_state.comp_pointed != component::end); @@ -709,7 +709,7 @@ namespace nana redraw = true; node_state.comp_pointed = component::end; item_proxy iprx(data.trigger_ptr, node_state.pointed); - data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, false }); + data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, false }, data.widget_ptr->handle()); close_tooltip_window(); node_state.pointed = nullptr; @@ -1995,7 +1995,7 @@ namespace nana if (impl_->node_state.pointed && (!impl_->node_state.tooltip)) { item_proxy iprx(impl_->data.trigger_ptr, impl_->node_state.pointed); - impl_->data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *impl_->data.widget_ptr, iprx, false }); + impl_->data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *impl_->data.widget_ptr, iprx, false }, impl_->data.widget_ptr->handle()); impl_->node_state.pointed = nullptr; impl_->draw(false); API::lazy_refresh(); From edfa397ddcd6cc1e8e52b0aa2b91695fbcf3c883 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 10 Apr 2016 17:09:42 +0800 Subject: [PATCH 137/309] bedrock has some minor changes --- include/nana/gui/detail/bedrock.hpp | 1 + source/gui/detail/bedrock_pi.cpp | 35 +++++++++++++++++++++++++++ source/gui/detail/bedrock_posix.cpp | 28 +++------------------ source/gui/detail/bedrock_windows.cpp | 31 +++--------------------- source/gui/widgets/date_chooser.cpp | 10 +------- 5 files changed, 43 insertions(+), 62 deletions(-) diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 7af9eb4e..92328361 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -71,6 +71,7 @@ namespace detail void event_expose(core_window_t *, bool exposed); void event_move(core_window_t*, int x, int y); bool event_msleave(core_window_t*); + void event_focus_changed(core_window_t* root_wd, native_window_type receiver, bool getting); void thread_context_destroy(core_window_t*); void thread_context_lazy_refresh(); void update_cursor(core_window_t*); diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index e8166cf6..09a5f555 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -176,6 +176,41 @@ namespace nana return false; } + //The wd must be a root window + void bedrock::event_focus_changed(core_window_t* root_wd, native_window_type receiver, bool getting) + { + auto focused = root_wd->other.attribute.root->focus; + + arg_focus arg; + arg.window_handle = reinterpret_cast(focused); + arg.getting = getting; + arg.receiver = receiver; + + if (getting) + { + if (root_wd->flags.enabled && root_wd->flags.take_active) + { + if (focused && focused->together.caret) + focused->together.caret->set_active(false); + + if (!emit(event_code::focus, focused, arg, true, get_thread_context())) + this->wd_manager().set_focus(root_wd, true, arg_focus::reason::general); + } + } + else + { + if (root_wd->other.attribute.root->focus) + { + if (emit(event_code::focus, focused, arg, true, get_thread_context())) + { + if (focused->together.caret) + focused->together.caret->set_active(false); + } + close_menu_if_focus_other_window(receiver); + } + } + } + void bedrock::update_cursor(core_window_t * wd) { internal_scope_guard isg; diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 071623ee..45818349 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -668,37 +668,15 @@ namespace detail hovered_wd = nullptr; break; case FocusIn: - if(msgwnd->flags.enabled && msgwnd->flags.take_active) - { - auto focus = msgwnd->other.attribute.root->focus; - if(focus && focus->together.caret) - focus->together.caret->set_active(true); - - arg_focus arg; - arg.window_handle = reinterpret_cast(focus); - arg.receiver = native_window; - arg.getting = true; - if(!brock.emit(event_code::focus, focus, arg, true, &context)) - brock.wd_manager().set_focus(msgwnd, true, arg_focus::reason::general); - } + brock.event_focus_changed(msgwnd, native_window, true); break; case FocusOut: - if(msgwnd->other.attribute.root->focus && native_interface::is_window(msgwnd->root)) + if(native_interface::is_window(msgwnd->root)) { nana::point pos = native_interface::cursor_position(); auto recv = native_interface::find_window(pos.x, pos.y); - auto focus = msgwnd->other.attribute.root->focus; - arg_focus arg; - arg.window_handle = reinterpret_cast(focus); - arg.getting = false; - arg.receiver = recv; - if(brock.emit(event_code::focus, focus, arg, true, &context)) - { - if(focus->together.caret) - focus->together.caret->set_active(false); - } - brock.close_menu_if_focus_other_window(recv); + brock.event_focus_changed(msgwnd, recv, false); } break; case ConfigureNotify: diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 949d34ae..143b00ef 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -873,37 +873,12 @@ namespace detail def_window_proc = true; break; case WM_SETFOCUS: - if(msgwnd->flags.enabled && msgwnd->flags.take_active) - { - auto focus = msgwnd->other.attribute.root->focus; - - if(focus && focus->together.caret) - focus->together.caret->set_active(true); - - arg_focus arg; - assign_arg(arg, focus, native_window, true); - if (!brock.emit(event_code::focus, focus, arg, true, &context)) - brock.wd_manager().set_focus(msgwnd, true, arg_focus::reason::general); - } + brock.event_focus_changed(msgwnd, native_window, true); def_window_proc = true; break; case WM_KILLFOCUS: - if(msgwnd->other.attribute.root->focus) - { - auto focus = msgwnd->other.attribute.root->focus; - - arg_focus arg; - assign_arg(arg, focus, reinterpret_cast(wParam), false); - if(brock.emit(event_code::focus, focus, arg, true, &context)) - { - if(focus->together.caret) - focus->together.caret->set_active(false); - } - - //wParam indicates a handle of window that receives the focus. - brock.close_menu_if_focus_other_window(reinterpret_cast(wParam)); - } - + //wParam indicates a handle of window that receives the focus. + brock.event_focus_changed(msgwnd, reinterpret_cast(wParam), false); def_window_proc = true; break; case WM_MOUSEACTIVATE: diff --git a/source/gui/widgets/date_chooser.cpp b/source/gui/widgets/date_chooser.cpp index 3c8a1fb6..42b3de72 100644 --- a/source/gui/widgets/date_chooser.cpp +++ b/source/gui/widgets/date_chooser.cpp @@ -388,13 +388,7 @@ namespace nana if (trace_.empty_logic_pos()) return 0; - int lines = 7, rows = 7; //for page::date - - if (page_mode::month == page) - { - lines = 3; - rows = 4; - } + const int rows = (page_mode::month == page ? 4 : 7); int n = trace_.logic_pos.y * rows + trace_.logic_pos.x + 1; if (page_mode::date == page) @@ -635,8 +629,6 @@ namespace nana void _m_draw_ex_days(graph_reference graph, const upoint& begin_logic_pos, bool before) { int x = nana::date::day_of_week(view_month_.year, view_month_.month, 1); - int y = (x ? 1 : 2); - int year = view_month_.year; if (before) { From ca1fce932a69cc68e3d4a69f5906f9599ddbc70b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 12 Apr 2016 22:17:07 +0800 Subject: [PATCH 138/309] minor changes --- include/nana/detail/win32/platform_spec.hpp | 2 +- include/nana/gui/detail/bedrock.hpp | 9 +- include/nana/gui/detail/bedrock_pi_data.hpp | 10 ++ source/gui/detail/bedrock_pi.cpp | 109 ++++++++++++ source/gui/detail/bedrock_posix.cpp | 151 +--------------- source/gui/detail/bedrock_windows.cpp | 185 +++----------------- source/gui/detail/window_manager.cpp | 10 +- 7 files changed, 158 insertions(+), 318 deletions(-) diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index dc6329fe..9e868e0b 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -68,7 +68,7 @@ namespace detail tray = 0x501, async_activate, async_set_focus, - map_thread_root_buffer, + remote_flush_surface, remote_thread_destroy_window, remote_thread_move_window, operate_caret, //wParam: 1=Destroy, 2=SetPos diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 92328361..88973217 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -14,7 +14,6 @@ #define NANA_GUI_DETAIL_BEDROCK_HPP #include "general_events.hpp" #include "color_schemes.hpp" -#include "internal_scope_guard.hpp" namespace nana { @@ -41,14 +40,13 @@ namespace detail ~bedrock(); void pump_event(window, bool is_modal); - void map_thread_root_buffer(core_window_t*, bool forced, const rectangle* update_area = nullptr); + void flush_surface(core_window_t*, bool forced, const rectangle* update_area = nullptr); static int inc_window(unsigned tid = 0); thread_context* open_thread_context(unsigned tid = 0); thread_context* get_thread_context(unsigned tid = 0); void remove_thread_context(unsigned tid = 0); static bedrock& instance(); - ::nana::category::flags category(core_window_t*); core_window_t* focus(); void set_menubar_taken(core_window_t*); @@ -62,8 +60,9 @@ namespace detail void erase_menu(bool try_destroy); void get_key_state(arg_keyboard&); - bool set_keyboard_shortkey(bool yes); - bool whether_keyboard_shortkey() const; + + bool shortkey_occurred(bool status); + bool shortkey_occurred() const; element_store& get_element_store() const; void map_through_widgets(core_window_t*, native_drawable_type); diff --git a/include/nana/gui/detail/bedrock_pi_data.hpp b/include/nana/gui/detail/bedrock_pi_data.hpp index 3154a6b3..309a7930 100644 --- a/include/nana/gui/detail/bedrock_pi_data.hpp +++ b/include/nana/gui/detail/bedrock_pi_data.hpp @@ -17,6 +17,16 @@ namespace nana events_operation evt_operation; window_manager wd_manager; std::set auto_form_set; + bool shortkey_occurred{ false }; + + struct menu_rep + { + core_window_t* taken_window{ nullptr }; + bool delay_restore{ false }; + native_window_type window{ nullptr }; + native_window_type owner{ nullptr }; + bool has_keyboard{ false }; + }menu; }; } } diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 09a5f555..928c422a 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -233,6 +233,115 @@ namespace nana } } + void bedrock::set_menubar_taken(core_window_t* wd) + { + auto pre = pi_data_->menu.taken_window; + pi_data_->menu.taken_window = wd; + + //assigning of a nullptr taken window is to restore the focus of pre taken + //don't restore the focus if pre is a menu. + if ((!wd) && pre && (pre->root != get_menu())) + { + internal_scope_guard lock; + wd_manager().set_focus(pre, false, arg_focus::reason::general); + wd_manager().update(pre, true, false); + } + } + + //0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying + void bedrock::delay_restore(int state) + { + switch (state) + { + case 0: //Enable + break; + case 1: //Cancel + break; + case 2: //Restore if key released + //restores the focus when menu is closed by pressing keyboard + if ((!pi_data_->menu.window) && pi_data_->menu.delay_restore) + set_menubar_taken(nullptr); + break; + case 3: //Restores if destroying + //when the menu is destroying, restores the focus if delay restore is not declared + if (!pi_data_->menu.delay_restore) + set_menubar_taken(nullptr); + } + + pi_data_->menu.delay_restore = (0 == state); + } + + bool bedrock::close_menu_if_focus_other_window(native_window_type wd) + { + if (pi_data_->menu.window && (pi_data_->menu.window != wd)) + { + wd = native_interface::get_owner_window(wd); + while (wd) + { + if (wd != pi_data_->menu.window) + wd = native_interface::get_owner_window(wd); + else + return false; + } + erase_menu(true); + return true; + } + return false; + } + + void bedrock::set_menu(native_window_type menu_wd, bool has_keyboard) + { + if(menu_wd && pi_data_->menu.window != menu_wd) + { + erase_menu(true); + + pi_data_->menu.window = menu_wd; + pi_data_->menu.owner = native_interface::get_owner_window(menu_wd); + pi_data_->menu.has_keyboard = has_keyboard; + } + } + + native_window_type bedrock::get_menu(native_window_type owner, bool is_keyboard_condition) + { + if ((pi_data_->menu.owner == nullptr) || + (owner && (pi_data_->menu.owner == owner)) + ) + { + return (is_keyboard_condition ? (pi_data_->menu.has_keyboard ? pi_data_->menu.window : nullptr) : pi_data_->menu.window); + } + + return 0; + } + + native_window_type bedrock::get_menu() + { + return pi_data_->menu.window; + } + + void bedrock::erase_menu(bool try_destroy) + { + if (pi_data_->menu.window) + { + if (try_destroy) + native_interface::close_window(pi_data_->menu.window); + + pi_data_->menu.window = pi_data_->menu.owner = nullptr; + pi_data_->menu.has_keyboard = false; + } + } + + bool bedrock::shortkey_occurred(bool status) + { + auto last_status = pi_data_->shortkey_occurred; + pi_data_->shortkey_occurred = status; + return last_status; + } + + bool bedrock::shortkey_occurred() const + { + return pi_data_->shortkey_occurred; + } + widget_colors& bedrock::get_scheme_template(scheme_factory_interface&& factory) { return pi_data_->scheme.scheme_template(std::move(factory)); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 45818349..624fa042 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -97,27 +97,6 @@ namespace detail thread_context *object{ nullptr }; }tcontext; }cache; - - struct menu_tag - { - core_window_t* taken_window{ nullptr }; - bool delay_restore{ false }; - native_window_type window{ nullptr }; - native_window_type owner{ nullptr }; - bool has_keyboard{ false }; - }menu; - - struct keyboard_tracking_state_tag - { - keyboard_tracking_state_tag() - :has_shortkey_occured(false), has_keyup(true), alt(0) - {} - - bool has_shortkey_occured; - bool has_keyup; - - unsigned long alt : 2; - }keyboard_tracking_state; }; void timer_proc(unsigned); @@ -153,9 +132,9 @@ namespace detail delete impl_; } - void bedrock::map_thread_root_buffer(core_window_t*, bool forced, const rectangle*) + void bedrock::flush_surface(core_window_t* wd, bool forced, const rectangle* update_area) { - //GUI in X11 is thread-independent, so no implementation. + wd->drawer.map(reinterpret_cast(wd), forced, update_area); } //inc_window @@ -229,118 +208,12 @@ namespace detail return bedrock_object; } - category::flags bedrock::category(bedrock::core_window_t* wd) - { - if(wd) - { - internal_scope_guard lock; - if(wd_manager().available(wd)) - return wd->other.category; - } - return category::flags::super; - } - bedrock::core_window_t* bedrock::focus() { core_window_t* wd = wd_manager().root(native_interface::get_focus_window()); return (wd ? wd->other.attribute.root->focus : 0); } - void bedrock::set_menubar_taken(core_window_t* wd) - { - auto pre = impl_->menu.taken_window; - impl_->menu.taken_window = wd; - - //assigning of a nullptr taken window is to restore the focus of pre taken - if ((!wd) && pre) - { - internal_scope_guard lock; - wd_manager().set_focus(pre, false, arg_focus::reason::general); - wd_manager().update(pre, true, false); - } - } - - //0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying - void bedrock::delay_restore(int state) - { - switch (state) - { - case 0: //Enable - break; - case 1: //Cancel - break; - case 2: //Restore if key released - //restores the focus when menu is closed by pressing keyboard - if ((!impl_->menu.window) && impl_->menu.delay_restore) - set_menubar_taken(nullptr); - break; - case 3: //Restores if destroying - //when the menu is destroying, restores the focus if delay restore is not declared - if (!impl_->menu.delay_restore) - set_menubar_taken(nullptr); - } - - impl_->menu.delay_restore = (0 == state); - } - - bool bedrock::close_menu_if_focus_other_window(native_window_type wd) - { - if(impl_->menu.window && (impl_->menu.window != wd)) - { - wd = native_interface::get_owner_window(wd); - while(wd) - { - if(wd != impl_->menu.window) - wd = native_interface::get_owner_window(wd); - else - return false; - } - erase_menu(true); - return true; - } - return false; - } - - void bedrock::set_menu(native_window_type menu_window, bool has_keyboard) - { - if(menu_window && impl_->menu.window != menu_window) - { - erase_menu(true); - impl_->menu.window = menu_window; - impl_->menu.owner = native_interface::get_owner_window(menu_window); - impl_->menu.has_keyboard = has_keyboard; - } - } - - native_window_type bedrock::get_menu(native_window_type owner, bool is_keyboard_condition) - { - if( (impl_->menu.owner == nullptr) || - (owner && (impl_->menu.owner == owner)) - ) - { - return ( is_keyboard_condition ? (impl_->menu.has_keyboard ? impl_->menu.window : nullptr) : impl_->menu.window); - } - - return 0; - } - - native_window_type bedrock::get_menu() - { - return impl_->menu.window; - } - - void bedrock::erase_menu(bool try_destroy) - { - if (impl_->menu.window) - { - if (try_destroy) - native_interface::close_window(impl_->menu.window); - - impl_->menu.window = impl_->menu.owner = nullptr; - impl_->menu.has_keyboard = false; - } - } - void bedrock::get_key_state(arg_keyboard& arg) { XKeyEvent xkey; @@ -349,18 +222,6 @@ namespace detail arg.shift = (xkey.state & ShiftMask); } - bool bedrock::set_keyboard_shortkey(bool yes) - { - bool ret = impl_->keyboard_tracking_state.has_shortkey_occured; - impl_->keyboard_tracking_state.has_shortkey_occured = yes; - return ret; - } - - bool bedrock::whether_keyboard_shortkey() const - { - return impl_->keyboard_tracking_state.has_shortkey_occured; - } - element_store& bedrock::get_element_store() const { return impl_->estore; @@ -1038,7 +899,7 @@ namespace detail else if(keyboard::alt == os_code) { context.is_alt_pressed = true; - if (brock.whether_keyboard_shortkey() == false) + if (brock.shortkey_occurred() == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if (msgwnd) @@ -1109,7 +970,7 @@ namespace detail { arg.ctrl = arg.shift = false; arg.evt_code = event_code::shortkey; - brock.set_keyboard_shortkey(true); + brock.shortkey_occurred(true); auto shr_wd = wd_manager.find_shortkey(native_window, arg.key); if(shr_wd) { @@ -1126,7 +987,7 @@ namespace detail draw_invoker(&drawer::key_char, msgwnd, arg, &context); } - if(brock.set_keyboard_shortkey(false)) + if(brock.shortkey_occurred(false)) context.is_alt_pressed = false; } break; @@ -1204,7 +1065,7 @@ namespace detail else { context.is_alt_pressed = false; - if (brock.set_keyboard_shortkey(false) == false) + if (brock.shortkey_occurred(false) == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if (msgwnd) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 143b00ef..d0bb0d82 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -177,26 +177,6 @@ namespace detail thread_context *object{ nullptr }; }tcontext; }cache; - - struct menu_tag - { - core_window_t* taken_window{ nullptr }; - bool delay_restore{ false }; - native_window_type window{ nullptr }; - native_window_type owner{ nullptr }; - bool has_keyboard{false}; - }menu; - - struct keyboard_tracking_state_tag - { - keyboard_tracking_state_tag() - :alt(0) - {} - - bool has_shortkey_occured = false; - bool has_keyup = true; - unsigned long alt : 2; - }keyboard_tracking_state; }; //class bedrock defines a static object itself to implement a static singleton @@ -325,14 +305,28 @@ namespace detail return bedrock_object; } - void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced, const rectangle* update_area) + void bedrock::flush_surface(core_window_t* wd, bool forced, const rectangle* update_area) { - auto stru = reinterpret_cast(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread))); - if (stru) + if (nana::system::this_thread_id() != wd->thread_id) { - if (FALSE == ::PostMessage(reinterpret_cast(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast(wd), reinterpret_cast(stru))) - ::HeapFree(::GetProcessHeap(), 0, stru); + auto stru = reinterpret_cast(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread))); + if (stru) + { + stru->forced = forced; + stru->ignore_update_area = true; + + if (update_area) + { + stru->ignore_update_area = false; + stru->update_area = *update_area; + } + + if (FALSE == ::PostMessage(reinterpret_cast(wd->root), nana::detail::messages::remote_flush_surface, reinterpret_cast(wd), reinterpret_cast(stru))) + ::HeapFree(::GetProcessHeap(), 0, stru); + } } + else + wd->drawer.map(reinterpret_cast(wd), forced, update_area); } void interior_helper_for_menu(MSG& msg, native_window_type menu_window) @@ -544,14 +538,6 @@ namespace detail } } - void assign_arg(arg_focus& arg, basic_window* wd, native_window_type recv, bool getting) - { - arg.window_handle = reinterpret_cast(wd); - arg.receiver = recv; - arg.getting = getting; - arg.focus_reason = arg_focus::reason::general; - } - void assign_arg(arg_wheel& arg, basic_window* wd, const parameter_decoder& pmdec) { arg.window_handle = reinterpret_cast(wd); @@ -602,7 +588,7 @@ namespace detail break; } return true; - case nana::detail::messages::map_thread_root_buffer: + case nana::detail::messages::remote_flush_surface: { auto stru = reinterpret_cast(lParam); bedrock.wd_manager().map(reinterpret_cast(wParam), stru->forced, (stru->ignore_update_area ? nullptr : &stru->update_area)); @@ -858,10 +844,9 @@ namespace detail } break; case WM_SHOWWINDOW: - if (msgwnd->visible && (wParam == FALSE)) - brock.event_expose(msgwnd, false); - else if ((!msgwnd->visible) && (wParam != FALSE)) - brock.event_expose(msgwnd, true); + if (msgwnd->visible == (FALSE == wParam)) + brock.event_expose(msgwnd, !msgwnd->visible); + def_window_proc = true; break; case WM_WINDOWPOSCHANGED: @@ -1312,7 +1297,7 @@ namespace detail break; case WM_SYSCHAR: def_window_proc = true; - brock.set_keyboard_shortkey(true); + brock.shortkey_occurred(true); msgwnd = brock.wd_manager().find_shortkey(native_window, static_cast(wParam)); if(msgwnd) { @@ -1328,7 +1313,7 @@ namespace detail break; case WM_SYSKEYDOWN: def_window_proc = true; - if (brock.whether_keyboard_shortkey() == false) + if (brock.shortkey_occurred() == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if (msgwnd) @@ -1350,7 +1335,7 @@ namespace detail break; case WM_SYSKEYUP: def_window_proc = true; - if(brock.set_keyboard_shortkey(false) == false) + if (brock.shortkey_occurred(false) == false) { msgwnd = msgwnd->root_widget->other.attribute.root->menubar; if(msgwnd) @@ -1531,7 +1516,7 @@ namespace detail } } else - brock.set_keyboard_shortkey(false); + brock.shortkey_occurred(false); //Do delay restore if key is not arrow_left/right/up/down, otherwise //A menubar will be restored if the item is empty(not have a menu item) @@ -1591,132 +1576,18 @@ namespace detail return ::DefWindowProc(root_window, message, wParam, lParam); } - ::nana::category::flags bedrock::category(core_window_t* wd) - { - internal_scope_guard lock; - return (wd_manager().available(wd) ? wd->other.category : ::nana::category::flags::super); - } - auto bedrock::focus() ->core_window_t* { core_window_t* wd = wd_manager().root(native_interface::get_focus_window()); return (wd ? wd->other.attribute.root->focus : nullptr); } - void bedrock::set_menubar_taken(core_window_t* wd) - { - auto pre = impl_->menu.taken_window; - impl_->menu.taken_window = wd; - - //assigning of a nullptr taken window is to restore the focus of pre taken - //don't restore the focus if pre is a menu. - if ((!wd) && pre && (pre->root != get_menu())) - { - internal_scope_guard lock; - wd_manager().set_focus(pre, false, arg_focus::reason::general); - wd_manager().update(pre, true, false); - } - } - - //0:Enable delay, 1:Cancel, 2:Restores, 3: Restores when menu is destroying - void bedrock::delay_restore(int state) - { - switch (state) - { - case 0: //Enable - break; - case 1: //Cancel - break; - case 2: //Restore if key released - //restores the focus when menu is closed by pressing keyboard - if ((!impl_->menu.window) && impl_->menu.delay_restore) - set_menubar_taken(nullptr); - break; - case 3: //Restores if destroying - //when the menu is destroying, restores the focus if delay restore is not declared - if (!impl_->menu.delay_restore) - set_menubar_taken(nullptr); - } - - impl_->menu.delay_restore = (0 == state); - } - - bool bedrock::close_menu_if_focus_other_window(native_window_type wd) - { - if(impl_->menu.window && (impl_->menu.window != wd)) - { - wd = native_interface::get_owner_window(wd); - while(wd) - { - if(wd != impl_->menu.window) - wd = native_interface::get_owner_window(wd); - else - return false; - } - erase_menu(true); - return true; - } - return false; - } - - void bedrock::set_menu(native_window_type menu_wd, bool has_keyboard) - { - if(menu_wd && impl_->menu.window != menu_wd) - { - erase_menu(true); - - impl_->menu.window = menu_wd; - impl_->menu.owner = native_interface::get_owner_window(menu_wd); - impl_->menu.has_keyboard = has_keyboard; - } - } - - native_window_type bedrock::get_menu(native_window_type owner, bool is_keyboard_condition) - { - if( (impl_->menu.owner == nullptr) || - (owner && (impl_->menu.owner == owner)) - ) - { - return ((!is_keyboard_condition) || impl_->menu.has_keyboard ? impl_->menu.window : nullptr); - } - return nullptr; - } - - native_window_type bedrock::get_menu() - { - return impl_->menu.window; - } - - void bedrock::erase_menu(bool try_destroy) - { - if (impl_->menu.window) - { - if (try_destroy) - native_interface::close_window(impl_->menu.window); - - impl_->menu.window = impl_->menu.owner = nullptr; - impl_->menu.has_keyboard = false; - } - } - void bedrock::get_key_state(arg_keyboard& kb) { kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 0x80)); kb.shift = (0 != (::GetKeyState(VK_SHIFT) & 0x80)); } - bool bedrock::set_keyboard_shortkey(bool yes) - { - bool ret = impl_->keyboard_tracking_state.has_shortkey_occured; - impl_->keyboard_tracking_state.has_shortkey_occured = yes; - return ret; - } - - bool bedrock::whether_keyboard_shortkey() const - { - return impl_->keyboard_tracking_state.has_shortkey_occured; - } - element_store& bedrock::get_element_store() const { return impl_->estore; @@ -1724,7 +1595,6 @@ namespace detail void bedrock::map_through_widgets(core_window_t* wd, native_drawable_type drawable) { -#if defined(NANA_WINDOWS) auto graph_context = reinterpret_cast(wd->root_graph->handle()->context); for (auto child : wd->children) @@ -1739,7 +1609,6 @@ namespace detail else if (::nana::category::flags::lite_widget == child->other.category) map_through_widgets(child, drawable); } -#endif } bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 5e1ee247..39e88c87 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -777,15 +777,7 @@ namespace detail parent = parent->parent; } - //Copy the root buffer that wd specified into DeviceContext -#if defined(NANA_LINUX) || defined(NANA_MACOS) - wd->drawer.map(reinterpret_cast(wd), forced, update_area); -#elif defined(NANA_WINDOWS) - if(nana::system::this_thread_id() == wd->thread_id) - wd->drawer.map(reinterpret_cast(wd), forced, update_area); - else - bedrock::instance().map_thread_root_buffer(wd, forced, update_area); -#endif + bedrock::instance().flush_surface(wd, forced, update_area); } } From e8225fad602e333166ca32f238b819de44435565 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 12 Apr 2016 22:42:26 +0800 Subject: [PATCH 139/309] missing conversion for non-Windows platform --- source/charset.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/charset.cpp b/source/charset.cpp index 42fc386a..225cba40 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1162,12 +1162,21 @@ namespace nana { switch(encoding) { +#if defined(NANA_WINDOWS) case unicode::utf8: return utf16_to_utf8(wcstr); case unicode::utf32: return utf16_to_utf32(wcstr); case unicode::utf16: return wcstr; +#else //POSIX + case unicode::utf8: + return utf32_to_utf8(wcstr); + case unicode::utf16: + return utf32_to_utf16(wcstr); + case unicode::utf32: + return wcstr; +#endif } } return {}; From bdd3806aa4f7d46c78375a342e0821866dc6dcf7 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 12 Apr 2016 23:09:39 +0800 Subject: [PATCH 140/309] add workaround for lack support of C++11 feature --- include/nana/deploy.hpp | 7 +++++++ source/deploy.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index f031c66d..342adfe7 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -121,6 +121,13 @@ namespace nana using std::runtime_error::runtime_error; +#if defined(_MSC_VER) +# if (_MSC_VER < 1900) + //A workaround for lack support of C++11 inheriting constructors for VC2013 + explicit utf8_Error(const std::string& msg); +# endif +#endif + void emit(); }; diff --git a/source/deploy.cpp b/source/deploy.cpp index eb79b86a..3e6dfcf7 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -513,6 +513,17 @@ namespace nana return true; } + //class utf8_Error + +#if defined(_MSC_VER) +# if (_MSC_VER < 1900) + //A workaround for lack support of C++11 inheriting constructors for VC2013 + utf8_Error::utf8_Error(const std::string& msg) + : std::runtime_error(msg) + {} +# endif +#endif + void utf8_Error::emit() { if (use_throw) @@ -522,6 +533,7 @@ namespace nana //bool utf8_Error::use_throw{true}; bool utf8_Error::use_throw{ false }; + //end class utf8_Error void throw_not_utf8(const std::string& text) { From 6a5623f0980c6963c9ff00825c903b22c84aa287 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 15 Apr 2016 20:38:35 +0800 Subject: [PATCH 141/309] fix menu shortkey underline issue --- source/gui/widgets/menu.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 53930ae4..e132f7b5 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -398,24 +398,28 @@ namespace nana //Draw text, the text is transformed from orignal for hotkey character wchar_t hotkey; std::string::size_type hotkey_pos; - auto text = to_wstring(API::transform_shortkey_text(m.text, hotkey, &hotkey_pos)); + auto text = API::transform_shortkey_text(m.text, hotkey, &hotkey_pos); if (m.image.empty() == false) renderer->item_image(graph, nana::point(item_r.x + 5, item_r.y + static_cast(item_h_px - image_px) / 2 - 1), image_px, m.image); - renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), to_utf8(text), strpixels, attr); + renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr); if (hotkey) { m.hotkey = hotkey; if (m.flags.enabled) { - unsigned off_w = (hotkey_pos ? graph.text_extent_size(text, static_cast(hotkey_pos)).width : 0); - nana::size hotkey_size = graph.text_extent_size(text.c_str() + hotkey_pos, 1); - int x = item_r.x + 40 + off_w; - int y = item_r.y + text_top_off + hotkey_size.height; + auto off_px = (hotkey_pos ? graph.text_extent_size(text.c_str(), hotkey_pos).width : 0); + auto hotkey_px = graph.text_extent_size(text.c_str() + hotkey_pos, 1).width; - graph_->line({ x, y }, { x + static_cast(hotkey_size.width) - 1, y }, colors::black); + unsigned ascent, descent, inleading; + graph.text_metrics(ascent, descent, inleading); + + int x = item_r.x + 40 + off_px; + int y = item_r.y + text_top_off + ascent + 1; + + graph_->line({ x, y }, { x + static_cast(hotkey_px)-1, y }, colors::black); } } @@ -582,9 +586,12 @@ namespace nana } else if(m.flags.enabled) { - std::move(fn_close_tree_)(); - item_proxy ip(index, m); - m.functor.operator()(ip); + fn_close_tree_(); + if (m.functor) + { + item_proxy ip(index, m); + m.functor.operator()(ip); + } return 1; } } From 67431865c9a9918de9fb87782c423297764c6c9b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 15 Apr 2016 22:22:40 +0800 Subject: [PATCH 142/309] fix text_editor text selection issue --- .../gui/widgets/skeletons/text_editor.hpp | 5 +- source/gui/widgets/skeletons/text_editor.cpp | 68 ++++++++++++------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 46a023fd..c26fbb45 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -220,7 +220,7 @@ namespace nana{ namespace widgets void set_end_caret(); bool hit_text_area(const point&) const; - bool hit_select_area(nana::upoint pos) const; + bool hit_select_area(nana::upoint pos, bool ignore_when_select_all) const; bool move_select(); bool mask(wchar_t); @@ -355,10 +355,9 @@ namespace nana{ namespace widgets struct selection { - enum mode_selection_t{mode_no_selected, mode_mouse_selected, mode_method_selected}; + enum mode_selection_t{mode_no_selected, mode_mouse_selected, mode_method_selected, mode_move_selected}; mode_selection_t mode_selection; - bool dragged; nana::upoint a, b; }select_; diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 79731abf..2ec36439 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1290,7 +1290,6 @@ namespace nana{ namespace widgets text_area_.scroll_pixels = 16; text_area_.hscroll = text_area_.vscroll = 0; select_.mode_selection = selection::mode_no_selected; - select_.dragged = false; API::create_caret(wd, 1, line_height()); API::bgcolor(wd, colors::white); @@ -1646,13 +1645,10 @@ namespace nana{ namespace widgets if(left_button) { - auto caret_pos_before = caret(); mouse_caret(scrpos); - if(select_.mode_selection != selection::mode_no_selected) + if (selection::mode_mouse_selected == select_.mode_selection || selection::mode_method_selected == select_.mode_selection) set_end_caret(); - else if ((!select_.dragged) && (caret_pos_before != caret())) - select_.dragged = true; text_area_.border_renderer(graph_, _m_bgcolor()); return true; @@ -1672,26 +1668,34 @@ namespace nana{ namespace widgets API::capture_window(window_, true); text_area_.captured = true; - //Set caret pos by screen point and get the caret pos. - mouse_caret(arg.pos); - if (arg.shift) + + if (this->hit_select_area(behavior_->screen_to_caret(arg.pos), true)) { - if (points_.shift_begin_caret != points_.caret) - { - select_.a = points_.shift_begin_caret; - select_.b = points_.caret; - } + select_.mode_selection = selection::mode_move_selected; } else { - if (!select(false)) + //Set caret pos by screen point and get the caret pos. + mouse_caret(arg.pos); + if (arg.shift) { - select_.a = points_.caret; //Set begin caret - set_end_caret(); + if (points_.shift_begin_caret != points_.caret) + { + select_.a = points_.shift_begin_caret; + select_.b = points_.caret; + } } - points_.shift_begin_caret = points_.caret; + else + { + if (!select(false)) + { + select_.a = points_.caret; //Set begin caret + set_end_caret(); + } + points_.shift_begin_caret = points_.caret; + } + select_.mode_selection = selection::mode_mouse_selected; } - select_.mode_selection = selection::mode_mouse_selected; } text_area_.border_renderer(graph_, _m_bgcolor()); @@ -1699,19 +1703,19 @@ namespace nana{ namespace widgets } else if (event_code::mouse_up == arg.evt_code) { - auto is_prev_no_selected = (select_.mode_selection == selection::mode_no_selected); + bool updated = false; if (select_.mode_selection == selection::mode_mouse_selected) { select_.mode_selection = selection::mode_no_selected; set_end_caret(); } - else if (is_prev_no_selected) + else if (selection::mode_move_selected == select_.mode_selection) { - if ((!select_.dragged) || (!move_select())) + if (!move_select()) select(false); + updated = true; } - select_.dragged = false; API::capture_window(window_, false); text_area_.captured = false; @@ -1720,8 +1724,7 @@ namespace nana{ namespace widgets text_area_.border_renderer(graph_, _m_bgcolor()); - //Redraw if is_prev_no_selected is true - return is_prev_no_selected; + return updated; } return false; } @@ -1861,11 +1864,21 @@ namespace nana{ namespace widgets return ((text_area_.area.x <= pos.x && pos.x < _m_end_pos(true)) && (text_area_.area.y <= pos.y && pos.y < _m_end_pos(false))); } - bool text_editor::hit_select_area(nana::upoint pos) const + bool text_editor::hit_select_area(nana::upoint pos, bool ignore_when_select_all) const { nana::upoint a, b; if(_m_get_sort_select_points(a, b)) { + if (ignore_when_select_all) + { + if (a.x == 0 && a.y == 0 && (b.y + 1) == static_cast(textbase_.lines())) + { + //is select all + if (b.x == static_cast(textbase_.getline(b.y).size())) + return false; + } + } + if((pos.y > a.y || (pos.y == a.y && pos.x >= a.x)) && ((pos.y < b.y) || (pos.y == b.y && pos.x < b.x))) return true; } @@ -1874,7 +1887,10 @@ namespace nana{ namespace widgets bool text_editor::move_select() { - if(hit_select_area(points_.caret) || (select_.b == points_.caret)) + if (! attributes_.editable) + return false; + + if(hit_select_area(points_.caret, true) || (select_.b == points_.caret)) { points_.caret = select_.b; From afa253f92467ac3a4eb45a0b3e4f757cf62356d0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 17 Apr 2016 06:06:33 +0800 Subject: [PATCH 143/309] capture_window is deprecated in favor of set_capture/release_capture --- include/nana/gui/detail/window_manager.hpp | 8 ++-- include/nana/gui/programming_interface.hpp | 49 ++++++++++++++++---- include/nana/gui/widgets/scroll.hpp | 4 +- include/nana/gui/widgets/widget.hpp | 9 ++++ source/gui/detail/bedrock_pi.cpp | 2 +- source/gui/detail/window_manager.cpp | 38 +++++---------- source/gui/dragger.cpp | 10 ++-- source/gui/place.cpp | 5 +- source/gui/place_parts.hpp | 11 +++-- source/gui/programming_interface.cpp | 11 ++--- source/gui/widgets/button.cpp | 5 +- source/gui/widgets/float_listbox.cpp | 4 +- source/gui/widgets/listbox.cpp | 5 +- source/gui/widgets/skeletons/text_editor.cpp | 5 +- source/gui/widgets/slider.cpp | 5 +- source/gui/widgets/spinbox.cpp | 5 +- source/gui/widgets/widget.cpp | 10 ++++ 17 files changed, 114 insertions(+), 72 deletions(-) diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index 965be995..d3468483 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -104,13 +104,13 @@ namespace detail //destroy_handle //@brief: Delete window handle, the handle type must be a root and a frame. + + // Deletes a window whose category type is a root type or a frame type. void destroy_handle(core_window_t*); void default_icon(const paint::image& _small_icon, const paint::image& big_icon); void icon(core_window_t*, const paint::image& small_icon, const paint::image& big_icon); - //show - //@brief: show or hide a window bool show(core_window_t* wd, bool visible); core_window_t* find_window(native_window_type root, int x, int y); @@ -139,10 +139,10 @@ namespace detail core_window_t* set_focus(core_window_t*, bool root_has_been_focused, arg_focus::reason); core_window_t* capture_redirect(core_window_t*); - void capture_ignore_children(bool ignore); + bool capture_window_entered(int root_x, int root_y, bool& prev); core_window_t * capture_window() const; - core_window_t* capture_window(core_window_t*, bool value); + void capture_window(core_window_t*, bool capture, bool ignore_children_if_captured); void enable_tabstop(core_window_t*); core_window_t* tabstop(core_window_t*, bool forward) const; //forward means move to next in logic. diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 03138a04..85196997 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -268,10 +268,13 @@ namespace API */ void lazy_refresh(); - /** @brief: calls refresh() of a widget's drawer. if currently state is lazy_refresh, Nana.GUI may paste the drawing on the window after an event processing. - * @param window: specify a window to be refreshed. + + /// Refresh the window and display it immediately calling the refresh function of its drawer_trigger. + /* + * The drawer::refresh() will be called. If the currently state is lazy_refrsh, the window is delayed to update the graphics until an event is finished. + * @param window_handle A handle to the window to be refreshed. */ - void refresh_window(window); ///< Refreshs the window and display it immediately calling the refresh method of its drawer_trigger.. + void refresh_window(window window_handle); void refresh_window_tree(window); ///< Refreshs the specified window and all its children windows, then display it immediately void update_window(window); ///< Copies the off-screen buffer to the screen for immediate display. @@ -294,8 +297,20 @@ namespace API void focus_window(window); window capture_window(); - window capture_window(window, bool); ///< Enables or disables the window to grab the mouse input - void capture_ignore_children(bool ignore); ///< Enables or disables the captured window whether redirects the mouse input to its children if the mouse is over its children. + + /// Enables a window to grab the mouse input. + /** + * @param window_handle A handle to a window to grab the mouse input. + * @param ignore_children Indicates whether to redirect the mouse input to its children if the mouse pointer is over its children. + */ + void set_capture(window window_handle, bool ignore_children); + + /// Disable a window to grab the mouse input. + /** + * @param window handle A handle to a window to release grab of mouse input. + */ + void release_capture(window window_handle); + void modal_window(window); ///< Blocks the routine til the specified window is closed. void wait_for(window); @@ -316,10 +331,25 @@ namespace API void caret_visible(window, bool is_show); bool caret_visible(window); - void tabstop(window); ///< Sets the window that owns the tabstop. - /// treu: The focus is not to be changed when Tab key is pressed, and a key_char event with tab will be generated. - void eat_tabstop(window, bool); - window move_tabstop(window, bool next); ///< Sets the focus to the window which tabstop is near to the specified window. + /// Enables that the user can give input focus to the specified window using TAB key. + void tabstop(window); + + /// Enables or disables a window to receive a key_char event for pressing TAB key. + /* + * @param window_handle A handle to the window to catch TAB key through key_char event. + * @param enable Indicates whether to enable or disable catch of TAB key. If this parameter is *true*, the window is + * received a key_char when pressing TAB key, and the input focus is not changed. If this parameter is *false*, the + * input focus is changed to the next tabstop window. + */ + void eat_tabstop(window window_handle, bool enable); + + /// Sets the input focus to the window which the tabstop is near to the specified window. + /* + * @param window_handle A handle to the window. + * @param forward Indicates whether forward or backward window to be given the input focus. + * @return A handle to the window which to be given the input focus. + */ + window move_tabstop(window window_handle, bool forward); /// Sets the window active state. If a window active state is false, the window will not obtain the focus when a mouse clicks on it wich will be obteined by take_if_has_active_false. void take_active(window, bool has_active, window take_if_has_active_false); @@ -349,6 +379,7 @@ namespace API void at_safe_place(window, std::function); }//end namespace API + }//end namespace nana #endif diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 1cf5bb83..00107b5f 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -262,7 +262,7 @@ namespace nana timer_.start(); break; case buttons::scroll: - API::capture_window(widget_->handle(), true); + widget_->set_capture(true); metrics_.scroll_mouse_offset = (Vertical ? arg.pos.y : arg.pos.x) - metrics_.scroll_pos; break; case buttons::forward: @@ -286,7 +286,7 @@ namespace nana { timer_.stop(); - API::capture_window(widget_->handle(), false); + widget_->release_capture(); metrics_.pressed = false; metrics_.what = drawer_.what(graph, arg.pos); diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index cfc174f7..14b6f2bd 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -78,6 +78,15 @@ namespace nana nana::size size() const; void size(const nana::size&); + + /// Enables the widget to grab the mouse input. + /* + * @param ignore_children Indicates whether to redirect the mouse input to its children if the mouse pointer is over its children. + */ + void set_capture(bool ignore_children); + + /// Disables the widget to grab the mouse input. + void release_capture(); point pos() const; void move(int x, int y); diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 928c422a..d705261c 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -310,7 +310,7 @@ namespace nana return (is_keyboard_condition ? (pi_data_->menu.has_keyboard ? pi_data_->menu.window : nullptr) : pi_data_->menu.window); } - return 0; + return nullptr; } native_window_type bedrock::get_menu() diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 39e88c87..29e7b97a 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -455,8 +455,6 @@ namespace detail update(parent, false, false, &update_area); } - //destroy_handle - //@brief: Delete window handle, the handle type must be a root and a frame. void window_manager::destroy_handle(core_window_t* wd) { //Thread-Safe Required! @@ -975,7 +973,7 @@ namespace detail //A fix by Katsuhisa Yuasa //The menubar token window will be redirected to the prev focus window when the new //focus window is a menubar. - //The focus window will be restore to the prev focus which losts the focus becuase of + //The focus window will be restored to the prev focus which losts the focus becuase of //memberbar. if (prev_focus && (wd == wd->root_widget->other.attribute.root->menubar)) wd = prev_focus; @@ -998,11 +996,6 @@ namespace detail return attr_.capture.window; } - void window_manager::capture_ignore_children(bool ignore) - { - attr_.capture.ignore_children = ignore; - } - bool window_manager::capture_window_entered(int root_x, int root_y, bool& prev) { if(attr_.capture.window) @@ -1023,19 +1016,15 @@ namespace detail return attr_.capture.window; } - //capture_window - //@brief: set a window that always captures the mouse event if it is not in the range of window - //@return: this function dose return the previous captured window. If the wnd set captured twice, - // the return value is NULL - window_manager::core_window_t* window_manager::capture_window(core_window_t* wd, bool value) + void window_manager::capture_window(core_window_t* wd, bool captured, bool ignore_children) { if (!this->available(wd)) - return nullptr; + return; nana::point pos = native_interface::cursor_position(); auto & attr_cap = attr_.capture.history; - if(value) + if (captured) { if(wd != attr_.capture.window) { @@ -1045,19 +1034,17 @@ namespace detail if (impl_->wd_register.available(wd)) { wd->flags.captured = true; - native_interface::capture_window(wd->root, value); - auto prev = attr_.capture.window; - if(prev && (prev != wd)) - attr_cap.emplace_back(prev, attr_.capture.ignore_children); + native_interface::capture_window(wd->root, captured); + + if (attr_.capture.window) + attr_cap.emplace_back(attr_.capture.window, attr_.capture.ignore_children); attr_.capture.window = wd; - attr_.capture.ignore_children = true; + attr_.capture.ignore_children = ignore_children; native_interface::calc_window_point(wd->root, pos); attr_.capture.inside = _m_effective(wd, pos); - return prev; } } - return attr_.capture.window; } else if(wd == attr_.capture.window) { @@ -1092,10 +1079,7 @@ namespace detail break; } } - - return attr_.capture.window; } - return wd; } //enable_tabstop @@ -1356,7 +1340,7 @@ namespace detail if (established) { if (check_tree(wd, attr_.capture.window)) - capture_window(attr_.capture.window, false); + capture_window(attr_.capture.window, false, false); //The 3rd parameter is ignored if (root_attr->focus && check_tree(wd, root_attr->focus)) root_attr->focus = nullptr; @@ -1369,7 +1353,7 @@ namespace detail else { if (wd == attr_.capture.window) - capture_window(attr_.capture.window, false); + capture_window(attr_.capture.window, false, false); //The 3rd parameter is ignored. if (root_attr->focus == wd) root_attr->focus = nullptr; diff --git a/source/gui/dragger.cpp b/source/gui/dragger.cpp index 43a56ba2..459d9833 100644 --- a/source/gui/dragger.cpp +++ b/source/gui/dragger.cpp @@ -47,7 +47,7 @@ namespace nana API::umake_event(t.over); API::umake_event(t.release); API::umake_event(t.destroy); - API::capture_window(t.wd, false); + API::release_capture(t.wd); } } @@ -87,7 +87,8 @@ namespace nana { case event_code::mouse_down: dragging_ = true; - API::capture_window(arg.window_handle, true); + API::set_capture(arg.window_handle, true); + origin_ = API::cursor_position(); for (auto & t : targets_) { @@ -133,7 +134,8 @@ namespace nana } break; case event_code::mouse_up: - API::capture_window(arg.window_handle, false); + API::release_capture(arg.window_handle); + dragging_ = false; break; default: @@ -151,7 +153,7 @@ namespace nana if (i->wd == arg.window_handle) { triggers_.erase(i); - API::capture_window(arg.window_handle, false); + API::release_capture(arg.window_handle); return; } } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index d0796c90..48ba39bc 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -1775,7 +1775,8 @@ namespace nana bool is_vert = _m_is_vert(dir_); - API::capture_window(this->handle(), true); + this->set_capture(true); + auto basepos = API::cursor_position(); base_pos_.x = (is_vert ? basepos.y : basepos.x); @@ -1838,7 +1839,7 @@ namespace nana dock_dv_->collocate(wd); } else - API::capture_window(this->handle(), false); //release mouse button + this->release_capture(); }; auto & evt = this->events(); diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 1d21d600..8cd0e418 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -240,7 +240,7 @@ namespace nana moves_.started = true; moves_.start_pos = API::cursor_position(); moves_.start_container_pos = (floating() ? container_->pos() : this->pos()); - API::capture_window(caption_, true); + caption_.set_capture(true); } } else if (event_code::mouse_move == arg.evt_code) @@ -266,7 +266,7 @@ namespace nana if ((::nana::mouse::left_button == arg.button) && moves_.started) { moves_.started = false; - API::capture_window(caption_, false); + caption_.release_capture(); notifier_->notify_move_stopped(); } } @@ -345,7 +345,7 @@ namespace nana if (container_) return; - API::capture_window(caption_, false); + caption_.release_capture(); rectangle r{ pos() + move_pos, size() }; container_.reset(new form(host_window_, r.pare_off(-1), form::appear::bald())); @@ -364,14 +364,15 @@ namespace nana }); container_->show(); - API::capture_window(caption_, true); + caption_.set_capture(true); notifier_->notify_float(); } void dock() { - API::capture_window(caption_, false); + caption_.release_capture(); + API::set_parent_window(handle(), host_window_); container_.reset(); notifier_->notify_dock(); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index a13e81cd..75f34ebe 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -937,16 +937,15 @@ namespace API return reinterpret_cast(restrict::wd_manager().capture_window()); } - window capture_window(window wd, bool value) + void set_capture(window wd, bool ignore_children) { - return reinterpret_cast( - restrict::wd_manager().capture_window(reinterpret_cast(wd), value) - ); + restrict::wd_manager().capture_window(reinterpret_cast(wd), true, ignore_children); } - void capture_ignore_children(bool ignore) + void release_capture(window wd) { - restrict::wd_manager().capture_ignore_children(ignore); + //The 3rd parameter is useless when the 2nd parameter is false. + restrict::wd_manager().capture_window(reinterpret_cast(wd), false, false); } void modal_window(window wd) diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index 1b7aa835..ec0b6e85 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -321,11 +321,12 @@ namespace nana{ namespace drawerbase attr_.e_state = element_state::pressed; attr_.keep_pressed = true; - API::capture_window(*wdg_, true); + wdg_->set_capture(true); } else { - API::capture_window(*wdg_, false); + wdg_->release_capture(); + attr_.keep_pressed = false; if (attr_.enable_pushed && (false == attr_.pushed)) { diff --git a/source/gui/widgets/float_listbox.cpp b/source/gui/widgets/float_listbox.cpp index d2591ac0..c51c8342 100644 --- a/source/gui/widgets/float_listbox.cpp +++ b/source/gui/widgets/float_listbox.cpp @@ -469,8 +469,8 @@ namespace nana float_listbox::float_listbox(window wd, const rectangle & r, bool is_ignore_first_mouse_up) :base_type(wd, false, r, appear::bald()) { - API::capture_window(handle(), true); - API::capture_ignore_children(false); + this->set_capture(false); + API::take_active(handle(), false, parent()); auto & impl = get_drawer_trigger().get_drawer_impl(); impl.clear_state(); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 007615cd..030283ad 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3343,7 +3343,8 @@ namespace nana nana::point pos = arg.pos; essence_->widget_to_header(pos); drawer_header_->grab(pos, true); - API::capture_window(essence_->lister.wd_ptr()->handle(), true); + essence_->lister.wd_ptr()->set_capture(true); + update = 2; } } @@ -3535,7 +3536,7 @@ namespace nana drawer_header_->grab(pos, false); refresh(graph); API::lazy_refresh(); - API::capture_window(essence_->lister.wd_ptr()->handle(), false); + essence_->lister.wd_ptr()->release_capture(); } } diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 3c372903..747e29a9 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1719,7 +1719,7 @@ namespace nana{ namespace widgets if (::nana::mouse::left_button == arg.button) { - API::capture_window(window_, true); + API::set_capture(window_, true); text_area_.captured = true; //Set caret pos by screen point and get the caret pos. @@ -1764,7 +1764,8 @@ namespace nana{ namespace widgets } select_.dragged = false; - API::capture_window(window_, false); + API::release_capture(window_); + text_area_.captured = false; if (hit_text_area(arg.pos) == false) API::window_cursor(window_, nana::cursor::arrow); diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index 45fbd122..38ba84e7 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -263,14 +263,15 @@ namespace nana slider_state_.trace = slider_state_.TraceCapture; slider_state_.snap_pos = static_cast(attr_.pos); slider_state_.refpos = pos; - API::capture_window(other_.wd, true); + API::set_capture(other_.wd, true); } bool release_slider() { if(slider_state_.trace == slider_state_.TraceCapture) { - API::capture_window(other_.wd, false); + API::release_capture(other_.wd); + if(other_.wd != API::find_window(API::cursor_position())) { slider_state_.trace = slider_state_.TraceNone; diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 90397d41..427dc47d 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -351,7 +351,8 @@ namespace nana { if (!pressed) { - API::capture_window(editor_->window_handle(), false); + API::release_capture(editor_->window_handle()); + timer_.stop(); timer_.interval(600); } @@ -361,7 +362,7 @@ namespace nana //Spins the value when mouse button is released if (pressed) { - API::capture_window(editor_->window_handle(), true); + API::set_capture(editor_->window_handle(), true); range_->spin(buttons::increase == spin_stated_); reset_text(); timer_.start(); diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index 1169e59e..ac50687b 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -183,6 +183,16 @@ namespace nana _m_size(sz); } + void widget::set_capture(bool ignore_children) + { + API::set_capture(*this, ignore_children); + } + + void widget::release_capture() + { + API::release_capture(*this); + } + nana::point widget::pos() const { return API::window_position(handle()); From 42990b867005b8395e170873406ba3d4c706e63a Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 17 Apr 2016 17:46:19 +0800 Subject: [PATCH 144/309] move lazy_refresh() from namespace API to API::dev --- include/nana/gui/programming_interface.hpp | 31 ++++++++++++---------- include/nana/gui/widgets/scroll.hpp | 14 +++++----- source/gui/place_parts.hpp | 8 +++--- source/gui/programming_interface.cpp | 12 ++++----- source/gui/widgets/button.cpp | 8 +++--- source/gui/widgets/categorize.cpp | 8 +++--- source/gui/widgets/checkbox.cpp | 8 +++--- source/gui/widgets/combox.cpp | 16 +++++------ source/gui/widgets/date_chooser.cpp | 8 +++--- source/gui/widgets/float_listbox.cpp | 2 +- source/gui/widgets/listbox.cpp | 20 +++++++------- source/gui/widgets/menu.cpp | 2 +- source/gui/widgets/menubar.cpp | 16 +++++------ source/gui/widgets/slider.cpp | 10 +++---- source/gui/widgets/spinbox.cpp | 18 ++++++------- source/gui/widgets/tabbar.cpp | 14 +++++----- source/gui/widgets/textbox.cpp | 20 +++++++------- source/gui/widgets/toolbar.cpp | 8 +++--- source/gui/widgets/treebox.cpp | 18 ++++++------- 19 files changed, 121 insertions(+), 120 deletions(-) diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 85196997..195b430b 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -88,10 +88,20 @@ namespace API void set_menubar(window wd, bool attach); void enable_space_click(window, bool enable); + + /// Refreshs a widget surface + /* + * This function will copy the drawer surface into system window after the event process finished. + */ + void lazy_refresh(); }//end namespace dev - - widget* get_widget(window); + /// Returns the widget pointer of the specified window. + /* + * @param window_handle A handle to a window owning the widget. + * @return A widget pointer. + */ + widget* get_widget(window window_handle); namespace detail { @@ -258,17 +268,6 @@ namespace API void window_enabled(window, bool); bool window_enabled(window); - /** @brief A widget drawer draws the widget surface in answering an event. - * - * This function will tell the drawer to copy the graphics into window after event answering. - * Tells Nana.GUI to copy the buffer of event window to screen after the event is processed. - * This function only works for a drawer_trigger, when a drawer_trigger receives an event, - * after drawing, a drawer_trigger should call lazy_refresh to tell the Nana.GUI to refresh - * the window to the screen after the event process finished. - */ - void lazy_refresh(); - - /// Refresh the window and display it immediately calling the refresh function of its drawer_trigger. /* * The drawer::refresh() will be called. If the currently state is lazy_refrsh, the window is delayed to update the graphics until an event is finished. @@ -296,6 +295,7 @@ namespace API /// Sets the keyboard focus for a specified window. void focus_window(window); + /// Returns a window which has grabbed the mouse input. window capture_window(); /// Enables a window to grab the mouse input. @@ -311,7 +311,10 @@ namespace API */ void release_capture(window window_handle); - void modal_window(window); ///< Blocks the routine til the specified window is closed. + /// Blocks the execution and other windows' messages until the specified window is closed. + void modal_window(window); + + /// Blocks the execution until the specified window is closesd. void wait_for(window); color fgcolor(window); diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 00107b5f..3a260c85 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -205,14 +205,14 @@ namespace nana void resized(graph_reference graph, const ::nana::arg_resized&) override { drawer_.draw(graph, metrics_.what); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_enter(graph_reference graph, const ::nana::arg_mouse& arg) override { metrics_.what = drawer_.what(graph, arg.pos); drawer_.draw(graph, metrics_.what); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_move(graph_reference graph, const ::nana::arg_mouse& arg) override @@ -238,7 +238,7 @@ namespace nana if (redraw) { drawer_.draw(graph, metrics_.what); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -278,7 +278,7 @@ namespace nana break; } drawer_.draw(graph, metrics_.what); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -291,7 +291,7 @@ namespace nana metrics_.pressed = false; metrics_.what = drawer_.what(graph, arg.pos); drawer_.draw(graph, metrics_.what); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_leave(graph_reference graph, const arg_mouse&) override @@ -300,7 +300,7 @@ namespace nana metrics_.what = buttons::none; drawer_.draw(graph, buttons::none); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_wheel(graph_reference graph, const arg_wheel& arg) override @@ -308,7 +308,7 @@ namespace nana if (make_step(arg.upwards == false, 3)) { drawer_.draw(graph, metrics_.what); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } private: diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 8cd0e418..6d8843fc 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -109,14 +109,14 @@ namespace nana x_pointed_ = _m_button_area().is_hit(arg.pos); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_leave(graph_reference graph, const arg_mouse&) override { x_pointed_ = false; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_down(graph_reference graph, const arg_mouse&) override @@ -127,7 +127,7 @@ namespace nana x_state_ = ::nana::mouse_action::pressed; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void mouse_up(graph_reference graph, const arg_mouse&) override @@ -137,7 +137,7 @@ namespace nana x_state_ = ::nana::mouse_action::over; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); close_fn_(); } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 75f34ebe..8e9e8edb 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -314,6 +314,11 @@ namespace API if (restrict::wd_manager().available(iwd)) iwd->flags.space_click_enabled = enable; } + + void lazy_refresh() + { + restrict::bedrock.thread_context_lazy_refresh(); + } }//end namespace dev @@ -824,13 +829,6 @@ namespace API return (restrict::wd_manager().available(iwd) ? iwd->flags.enabled : false); } - //lazy_refresh: - //@brief: A widget drawer draws the widget surface in answering an event. This function will tell the drawer to copy the graphics into window after event answering. - void lazy_refresh() - { - restrict::bedrock.thread_context_lazy_refresh(); - } - //refresh_window //@brief: Refresh the window and display it immediately. void refresh_window(window wd) diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index ec0b6e85..ac50d47d 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -134,7 +134,7 @@ namespace nana{ namespace drawerbase { attr_.e_state = (attr_.pushed || attr_.keep_pressed ? element_state::pressed : element_state::hovered); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::mouse_leave(graph_reference graph, const arg_mouse&) @@ -144,7 +144,7 @@ namespace nana{ namespace drawerbase attr_.e_state = element_state::normal; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) @@ -185,7 +185,7 @@ namespace nana{ namespace drawerbase { attr_.focused = arg.getting; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::_m_draw_title(graph_reference graph, bool enabled) @@ -343,7 +343,7 @@ namespace nana{ namespace drawerbase } refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::emit_click() diff --git a/source/gui/widgets/categorize.cpp b/source/gui/widgets/categorize.cpp index 230369c8..a79073d4 100644 --- a/source/gui/widgets/categorize.cpp +++ b/source/gui/widgets/categorize.cpp @@ -881,7 +881,7 @@ namespace nana { scheme_->mouse_pressed(); scheme_->draw(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } } @@ -894,7 +894,7 @@ namespace nana { scheme_->mouse_release(); scheme_->draw(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } } @@ -904,7 +904,7 @@ namespace nana if(scheme_->locate(arg.pos.x, arg.pos.y) && API::window_enabled(scheme_->window_handle())) { scheme_->draw(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -913,7 +913,7 @@ namespace nana if(API::window_enabled(scheme_->window_handle()) && (scheme_->is_list_shown() == false) && scheme_->erase_locate()) { scheme_->draw(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } //end class trigger diff --git a/source/gui/widgets/checkbox.cpp b/source/gui/widgets/checkbox.cpp index a99d02f4..7e567044 100644 --- a/source/gui/widgets/checkbox.cpp +++ b/source/gui/widgets/checkbox.cpp @@ -85,7 +85,7 @@ namespace nana{ namespace drawerbase void drawer::mouse_down(graph_reference graph, const arg_mouse&) { refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_up(graph_reference graph, const arg_mouse&) @@ -97,19 +97,19 @@ namespace nana{ namespace drawerbase API::events(impl_->widget_ptr->handle()).checked.emit(arg, impl_->widget_ptr->handle()); } refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_enter(graph_reference graph, const arg_mouse&) { refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_leave(graph_reference graph, const arg_mouse&) { refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } drawer::implement * drawer::impl() const diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index ed39ba8e..dfa911d0 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -586,7 +586,7 @@ namespace nana { drawer_->draw(); drawer_->editor()->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -596,7 +596,7 @@ namespace nana if(drawer_->widget_ptr()->enabled()) { drawer_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -607,7 +607,7 @@ namespace nana if(drawer_->widget_ptr()->enabled()) { drawer_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -625,7 +625,7 @@ namespace nana if(editor->attr().editable) editor->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -636,7 +636,7 @@ namespace nana drawer_->editor()->mouse_pressed(arg); drawer_->set_button_state(element_state::hovered, false); drawer_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -651,7 +651,7 @@ namespace nana { drawer_->draw(); drawer_->editor()->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } } @@ -711,13 +711,13 @@ namespace nana if (call_other_keys) drawer_->editor()->respond_key(arg); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::key_char(graph_reference graph, const arg_keyboard& arg) { if (drawer_->editor()->respond_char(arg)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } //end class trigger diff --git a/source/gui/widgets/date_chooser.cpp b/source/gui/widgets/date_chooser.cpp index 42b3de72..0085f30b 100644 --- a/source/gui/widgets/date_chooser.cpp +++ b/source/gui/widgets/date_chooser.cpp @@ -797,7 +797,7 @@ namespace nana if (model_->set_where(pos) || (model::where::textarea == pos)) { model_->render(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -806,7 +806,7 @@ namespace nana if (model_->set_where(model::where::none)) { model_->render(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -882,7 +882,7 @@ namespace nana if (!transformed) model_->render(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -894,7 +894,7 @@ namespace nana if (!redrawn) refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } //end class trigger diff --git a/source/gui/widgets/float_listbox.cpp b/source/gui/widgets/float_listbox.cpp index c51c8342..34c5a03f 100644 --- a/source/gui/widgets/float_listbox.cpp +++ b/source/gui/widgets/float_listbox.cpp @@ -443,7 +443,7 @@ namespace nana if(drawer_->set_mouse(graph, arg.pos.x, arg.pos.y)) { drawer_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 030283ad..88bfe21f 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3392,7 +3392,7 @@ namespace nana if (2 == update) refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -3409,7 +3409,7 @@ namespace nana } refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -3504,7 +3504,7 @@ namespace nana if(update) { _m_draw_border(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -3525,7 +3525,7 @@ namespace nana { essence_->trace_item_dpl({0,0}); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } } @@ -3535,7 +3535,7 @@ namespace nana essence_->widget_to_header(pos); drawer_header_->grab(pos, false); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); essence_->lister.wd_ptr()->release_capture(); } } @@ -3546,7 +3546,7 @@ namespace nana { refresh(graph); essence_->adjust_scroll_value(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -3588,7 +3588,7 @@ namespace nana } essence_->adjust_scroll_life(); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } } @@ -3597,7 +3597,7 @@ namespace nana { essence_->adjust_scroll_life(); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::key_press(graph_reference graph, const arg_keyboard& arg) @@ -3670,7 +3670,7 @@ namespace nana return; } refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::key_char(graph_reference graph, const arg_keyboard& arg) @@ -3688,7 +3688,7 @@ namespace nana case keyboard::select_all : essence_->lister.select_for_all(true); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); break; default: diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 53930ae4..02a5b551 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -350,7 +350,7 @@ namespace nana if(track_mouse(arg.pos)) { refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } diff --git a/source/gui/widgets/menubar.cpp b/source/gui/widgets/menubar.cpp index 459b61fb..65a08292 100644 --- a/source/gui/widgets/menubar.cpp +++ b/source/gui/widgets/menubar.cpp @@ -253,7 +253,7 @@ namespace nana { _m_popup_menu(); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } state_.mouse_pos = arg.pos; @@ -281,7 +281,7 @@ namespace nana _m_total_close(); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::mouse_up(graph_reference graph, const arg_mouse&) @@ -298,7 +298,7 @@ namespace nana state_.behavior = state_.behavior_none; _m_total_close(); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -312,7 +312,7 @@ namespace nana _m_close_menu(); state_.active = npos; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -407,7 +407,7 @@ namespace nana } refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::key_release(graph_reference graph, const arg_keyboard& arg) @@ -429,7 +429,7 @@ namespace nana state_.menu_active = false; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -449,7 +449,7 @@ namespace nana state_.menu->goto_next(true); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); state_.behavior = state_.behavior_menu; } } @@ -477,7 +477,7 @@ namespace nana { state_.active = index; refresh(*graph_); - API::lazy_refresh(); + API::dev::lazy_refresh(); if(_m_popup_menu()) state_.menu->goto_next(true); diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index 38ba84e7..abb7dfe8 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -626,7 +626,7 @@ namespace nana if(mkdir) { impl_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } } @@ -637,7 +637,7 @@ namespace nana if(mkdraw) { impl_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -660,7 +660,7 @@ namespace nana if(mkdraw) { impl_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -669,7 +669,7 @@ namespace nana if(impl_->reset_adorn()) { impl_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -677,7 +677,7 @@ namespace nana { impl_->resize(); impl_->draw(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } //end class trigger }//end namespace slider diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 427dc47d..477b1bd1 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -524,38 +524,38 @@ namespace nana impl_->reset_text(); impl_->render(); impl_->editor()->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_wheel(graph_reference, const arg_wheel& arg) { impl_->mouse_wheel(arg.upwards); impl_->editor()->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_down(graph_reference, const arg_mouse& arg) { if (impl_->mouse_button(arg, true)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_up(graph_reference, const arg_mouse& arg) { if (impl_->mouse_button(arg, false)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_move(graph_reference, const arg_mouse& arg) { if (impl_->mouse_move(arg.left_button, arg.pos)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_leave(graph_reference, const arg_mouse&) { impl_->render(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::key_press(graph_reference, const arg_keyboard& arg) @@ -564,7 +564,7 @@ namespace nana { impl_->editor()->reset_caret(); impl_->draw_spins(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -575,7 +575,7 @@ namespace nana if (!impl_->value(to_utf8(impl_->editor()->text()))) impl_->draw_spins(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -584,7 +584,7 @@ namespace nana impl_->reset_text_area(); impl_->render(); impl_->editor()->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } }//end namespace drawerbase diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index 796fe2af..a8e0cc5b 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -1255,7 +1255,7 @@ namespace nana if(false == layouter_->active_by_trace()) layouter_->toolbox_answer(arg); layouter_->render(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1266,7 +1266,7 @@ namespace nana if(rd) { layouter_->render(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1275,7 +1275,7 @@ namespace nana if(layouter_->trace(arg.pos.x, arg.pos.y)) { layouter_->render(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1284,7 +1284,7 @@ namespace nana if(layouter_->leave()) { layouter_->render(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } //end class trigger @@ -1535,7 +1535,7 @@ namespace nana return; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void driver::mouse_leave(graph_reference graph, const arg_mouse&) @@ -1544,7 +1544,7 @@ namespace nana return; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void driver::mouse_down(graph_reference graph, const arg_mouse&) @@ -1559,7 +1559,7 @@ namespace nana model_->show_attached_window(); refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); event_arg arg; model_->widget_ptr()->events().selected.emit(arg, model_->widget_ptr()->handle()); diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index f2a168ef..4b5da90f 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -97,7 +97,7 @@ namespace drawerbase { if (!editor_->focus_changed(arg)) refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_down(graph_reference, const arg_mouse& arg) @@ -105,20 +105,20 @@ namespace drawerbase { if (editor_->mouse_pressed(arg)) { editor_->render(true); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } void drawer::mouse_move(graph_reference, const arg_mouse& arg) { if(editor_->mouse_move(arg.left_button, arg.pos)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_up(graph_reference graph, const arg_mouse& arg) { if(editor_->mouse_pressed(arg)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_wheel(graph_reference, const arg_wheel& arg) @@ -126,20 +126,20 @@ namespace drawerbase { if(editor_->scroll(arg.upwards, true)) { editor_->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } void drawer::mouse_enter(graph_reference, const arg_mouse&) { if(editor_->mouse_enter(true)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::mouse_leave(graph_reference, const arg_mouse&) { if(editor_->mouse_enter(false)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::key_press(graph_reference, const arg_keyboard& arg) @@ -147,14 +147,14 @@ namespace drawerbase { if(editor_->respond_key(arg)) { editor_->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } void drawer::key_char(graph_reference, const arg_keyboard& arg) { if (editor_->respond_char(arg)) - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::resized(graph_reference graph, const arg_resized& arg) @@ -162,7 +162,7 @@ namespace drawerbase { _m_text_area(arg.width, arg.height); refresh(graph); editor_->reset_caret(); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void drawer::typeface_changed(graph_reference graph) diff --git a/source/gui/widgets/toolbar.cpp b/source/gui/widgets/toolbar.cpp index 728e5f2f..94b5f888 100644 --- a/source/gui/widgets/toolbar.cpp +++ b/source/gui/widgets/toolbar.cpp @@ -317,7 +317,7 @@ namespace nana impl_->state = item_renderer::state_t::highlighted; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); if (impl_->state == item_renderer::state_t::highlighted) { @@ -341,7 +341,7 @@ namespace nana impl_->which = npos; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); if (which != npos && impl_->items.at(which)->enable) { @@ -359,7 +359,7 @@ namespace nana { impl_->state = item_renderer::state_t::selected; refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -382,7 +382,7 @@ namespace nana } refresh(graph); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 3f3b55ee..11b4508f 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1879,7 +1879,7 @@ namespace nana impl_->node_state.event_node = nl.node(); impl_->set_expanded(impl_->node_state.event_node, !impl_->node_state.event_node->value.second.expanded); impl_->draw(true); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1927,7 +1927,7 @@ namespace nana if(has_redraw) { impl_->draw(true); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1960,7 +1960,7 @@ namespace nana return; //Do not refresh impl_->draw(true); - API::lazy_refresh(); + API::dev::lazy_refresh(); } void trigger::mouse_move(graph_reference, const arg_mouse& arg) @@ -1968,7 +1968,7 @@ namespace nana if(impl_->track_mouse(arg.pos.x, arg.pos.y)) { impl_->draw(false); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1986,7 +1986,7 @@ namespace nana impl_->track_mouse(arg.pos.x, arg.pos.y); impl_->draw(false); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -1998,14 +1998,14 @@ namespace nana impl_->data.widget_ptr->events().hovered.emit(::nana::arg_treebox{ *impl_->data.widget_ptr, iprx, false }, impl_->data.widget_ptr->handle()); impl_->node_state.pointed = nullptr; impl_->draw(false); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } void trigger::resized(graph_reference, const arg_resized&) { impl_->draw(false); - API::lazy_refresh(); + API::dev::lazy_refresh(); impl_->show_scroll(); if(!impl_->shape.scroll.empty()) { @@ -2120,7 +2120,7 @@ namespace nana if(redraw) { impl_->draw(scroll); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } @@ -2150,7 +2150,7 @@ namespace nana if (do_refresh) { impl_->draw(do_refresh & 1); - API::lazy_refresh(); + API::dev::lazy_refresh(); } } //end class trigger From 3dbe94cd6c25ba0825882f5ebe5dcb92064c1a3c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 18 Apr 2016 20:38:55 +0800 Subject: [PATCH 145/309] fix a bug that text_editor undo for move text --- source/gui/widgets/skeletons/text_editor.cpp | 49 ++++++++++++++------ 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 66367622..02639fc1 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -39,8 +39,10 @@ namespace nana{ namespace widgets void set_selected_text() { - if (editor_._m_get_sort_select_points(sel_a_, sel_b_)) - editor_._m_make_select_string(selected_text_); + //sel_a_ and sel_b_ are not sorted, sel_b_ keeps the caret position. + sel_a_ = editor_.select_.a; + sel_b_ = editor_.select_.b; + editor_._m_make_select_string(selected_text_); } void set_caret_pos() @@ -217,14 +219,26 @@ namespace nana{ namespace widgets editor_.select_.a = sel_a_; editor_.select_.b = sel_b_; editor_.points_.caret = pos_; + editor_._m_move_select(false); } else { editor_.select_.a = dest_a_; editor_.select_.b = dest_b_; - editor_.points_.caret = sel_a_; + editor_.points_.caret = (sel_a_ < sel_b_ ? sel_a_ : sel_b_); + + std::wstring text; + editor_._m_make_select_string(text); + + editor_._m_erase_select(); + editor_._m_put(text); + + editor_.select_.a = sel_a_; + editor_.select_.b = sel_b_; + + editor_.points_.caret = sel_b_; + editor_.reset_caret(); } - editor_._m_move_select(false); } void set_destination(const nana::upoint& dest_a, const nana::upoint& dest_b) @@ -3013,13 +3027,16 @@ namespace nana{ namespace widgets auto undo_ptr = std::unique_ptr(new undo_move_text(*this)); undo_ptr->set_selected_text(); + //Determines whether the caret is at left or at right. The select_.b indicates the caret position when finish selection + const bool at_left = (select_.b < select_.a); + nana::upoint a, b; _m_get_sort_select_points(a, b); if (caret.y < a.y || (caret.y == a.y && caret.x < a.x)) {//forward - _m_erase_select(); - undo_ptr->set_caret_pos(); + + _m_erase_select(); _m_put(text); select_.a = caret; @@ -3028,6 +3045,7 @@ namespace nana{ namespace widgets else if (b.y < caret.y || (caret.y == b.y && b.x < caret.x)) { undo_ptr->set_caret_pos(); + _m_put(text); _m_erase_select(); @@ -3037,13 +3055,17 @@ namespace nana{ namespace widgets } select_.b.x = b.x + (a.y == b.y ? (select_.a.x - a.x) : 0); + //restores the caret at the proper end. + if ((select_.b < select_.a) != at_left) + std::swap(select_.a, select_.b); + if (record_undo) { undo_ptr->set_destination(select_.a, select_.b); undo_.push(std::move(undo_ptr)); } - points_.caret = select_.a; + points_.caret = select_.b; reset_caret(); return true; } @@ -3400,16 +3422,17 @@ namespace nana{ namespace widgets if (select_.a == select_.b) return false; - if((select_.a.y > select_.b.y) || ((select_.a.y == select_.b.y) && (select_.a.x > select_.b.x))) - { - a = select_.b; - b = select_.a; - } - else + if (select_.a < select_.b) { a = select_.a; b = select_.b; } + else + { + a = select_.b; + b = select_.a; + } + return true; } From c512b2dad5374984c08cf0abb243bc6f4adde814 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 20 Apr 2016 02:07:38 +0800 Subject: [PATCH 146/309] improve window manager refresh process --- include/nana/gui/detail/basic_window.hpp | 3 ++ include/nana/gui/detail/effects_renderer.hpp | 19 ++++++- include/nana/gui/layout_utility.hpp | 2 +- .../gui/widgets/skeletons/text_editor.hpp | 4 +- source/gui/detail/basic_window.cpp | 8 +++ source/gui/detail/bedrock_pi.cpp | 7 ++- source/gui/detail/bedrock_posix.cpp | 26 +++++----- source/gui/detail/bedrock_windows.cpp | 24 ++++----- source/gui/detail/drawer.cpp | 8 ++- source/gui/detail/window_layout.cpp | 4 +- source/gui/detail/window_manager.cpp | 13 ++--- source/gui/layout_utility.cpp | 4 +- source/gui/widgets/skeletons/text_editor.cpp | 52 +++++++++---------- 13 files changed, 98 insertions(+), 76 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 22f51122..6c66b709 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -118,6 +118,8 @@ namespace detail bool is_draw_through() const; ///< Determines whether it is a draw-through window. basic_window * seek_non_lite_widget_ancestor() const; + + void set_action(mouse_action); public: /// Override event_holder bool set_events(const std::shared_ptr&) override; @@ -169,6 +171,7 @@ namespace detail unsigned Reserved :18; unsigned char tab; ///< indicate a window that can receive the keyboard TAB mouse_action action; + mouse_action action_before; }flags; struct diff --git a/include/nana/gui/detail/effects_renderer.hpp b/include/nana/gui/detail/effects_renderer.hpp index 0304fcb9..1a55e2ab 100644 --- a/include/nana/gui/detail/effects_renderer.hpp +++ b/include/nana/gui/detail/effects_renderer.hpp @@ -24,7 +24,7 @@ namespace nana{ return object; } - unsigned weight() const + constexpr unsigned weight() const { return 2; } @@ -122,9 +122,22 @@ namespace nana{ } } + rectangle wd_r{ wd->pos_root, wd->dimension }; + wd_r.pare_off(-static_cast(this->weight())); //Render for (auto & rd : rd_set) - _m_render_edge_nimbus(rd.second, rd.first); + { + auto other_wd = rd.second; + + if (other_wd != wd) + { + rectangle other_r{ other_wd->pos_root, other_wd->dimension }; + other_r.pare_off(-static_cast(this->weight())); + if (!overlapped(wd_r, other_r)) + continue; + } + _m_render_edge_nimbus(other_wd, rd.first); + } } private: static bool _m_edge_nimbus(core_window_t * focused_wd, core_window_t * wd) @@ -138,6 +151,8 @@ namespace nana{ void _m_render_edge_nimbus(core_window_t* wd, const nana::rectangle & visual) { + wd->flags.action_before = wd->flags.action; + auto r = visual; r.pare_off(-static_cast(weight())); rectangle good_r; diff --git a/include/nana/gui/layout_utility.hpp b/include/nana/gui/layout_utility.hpp index 51d4d4ea..56127aac 100644 --- a/include/nana/gui/layout_utility.hpp +++ b/include/nana/gui/layout_utility.hpp @@ -18,7 +18,7 @@ namespace nana { //overlap test if overlaped between r1 and r2 - bool overlap(const rectangle& r1, const rectangle& r2); + bool overlapped(const rectangle& r1, const rectangle& r2); // overlap, compute the overlap area between r1 and r2. the r is for root bool overlap(const rectangle& r1, const rectangle& r2, rectangle& r); diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 3b438e4e..0dad496e 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -256,7 +256,7 @@ namespace nana{ namespace widgets bool scroll(bool upwards, bool vertical); bool focus_changed(const arg_focus&); - bool mouse_enter(bool); + bool mouse_enter(bool entering); bool mouse_move(bool left_button, const point& screen_pos); bool mouse_pressed(const arg_mouse& arg); @@ -274,7 +274,7 @@ namespace nana{ namespace widgets ::nana::upoint _m_put(::std::wstring); ::nana::upoint _m_erase_select(); - bool _m_make_select_string(::std::wstring&) const; + ::std::wstring _m_make_select_string() const; static bool _m_resolve_text(const ::std::wstring&, std::vector> & lines); bool _m_cancel_select(int align); diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 693a9bf7..6e592a0e 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -346,6 +346,12 @@ namespace nana return anc; } + void basic_window::set_action(mouse_action act) + { + flags.action_before = flags.action; + flags.action = act; + } + void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r) { pos_owner = pos_root = r; @@ -390,6 +396,8 @@ namespace nana flags.fullscreen = false; flags.tab = nana::detail::tab_type::none; flags.action = mouse_action::normal; + flags.action_before = mouse_action::normal; + flags.refreshing = false; flags.destroying = false; flags.borderless = false; diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 22bd4498..e3fb1c6b 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -165,8 +165,7 @@ namespace nana arg.window_handle = reinterpret_cast(wd); arg.x = x; arg.y = y; - if (emit(event_code::move, wd, arg, false, get_thread_context())) - wd_manager().update(wd, false, true); + emit(event_code::move, wd, arg, true, get_thread_context()); } } @@ -174,7 +173,7 @@ namespace nana { if (wd_manager().available(hovered) && hovered->flags.enabled) { - hovered->flags.action = mouse_action::normal; + hovered->set_action(mouse_action::normal); arg_mouse arg; arg.evt_code = event_code::mouse_leave; @@ -203,7 +202,7 @@ namespace nana if (root_wd->flags.enabled && root_wd->flags.take_active) { if (focused && focused->together.caret) - focused->together.caret->set_active(false); + focused->together.caret->set_active(true); if (!emit(event_code::focus, focused, arg, true, get_thread_context())) this->wd_manager().set_focus(root_wd, true, arg_focus::reason::general); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 72e8b53f..af6a58c3 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -515,7 +515,8 @@ namespace detail if(msgwnd) { if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); + hovered_wd = msgwnd; arg_mouse arg; @@ -597,7 +598,8 @@ namespace detail context.event_window = msgwnd; pressed_wd = nullptr; - msgwnd->flags.action = mouse_action::pressed; + + msgwnd->set_action(mouse_action::pressed); arg_mouse arg; assign_arg(arg, msgwnd, ButtonPress, xevent); arg.evt_code = dbl_click ? event_code::dbl_click : event_code::mouse_down; @@ -610,7 +612,7 @@ namespace detail if (msgwnd->root != native_interface::get_focus_window()) { //call the drawer mouse up event for restoring the surface graphics - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); wd_manager.do_lazy_refresh(msgwnd, false); @@ -648,7 +650,7 @@ namespace detail if(nullptr == msgwnd) break; - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); if(msgwnd->flags.enabled) { auto retain = msgwnd->together.events_ptr; @@ -667,7 +669,7 @@ namespace detail { if((arg.button == ::nana::mouse::left_button) && hit) { - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); click_arg.window_handle = reinterpret_cast(msgwnd); draw_invoker(&drawer::click, msgwnd, click_arg, &context); @@ -678,7 +680,7 @@ namespace detail if(wd_manager.available(msgwnd) && msgwnd->flags.enabled) { if(hit) - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); auto retain = msgwnd->together.events_ptr; auto evt_ptr = retain.get(); @@ -740,7 +742,7 @@ namespace detail if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd)) { brock.event_msleave(hovered_wd); - hovered_wd->flags.action = mouse_action::normal; + hovered_wd->set_action(mouse_action::normal); hovered_wd = nullptr; //if msgwnd is neither a captured window nor a child of captured window, @@ -758,13 +760,13 @@ namespace detail if(prev_captured_inside) { evt_code = event_code::mouse_leave; - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); } else { evt_code = event_code::mouse_enter; if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); } arg_mouse arg; assign_arg(arg, msgwnd, message, xevent); @@ -779,7 +781,7 @@ namespace detail assign_arg(arg, msgwnd, message, xevent); if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); if (hovered_wd != msgwnd) { @@ -890,7 +892,7 @@ namespace detail arg.pos.y = 0; arg.window_handle = reinterpret_cast(msgwnd); - msgwnd->flags.action = mouse_action::pressed; + msgwnd->set_action(mouse_action::pressed); pressed_wd_space = msgwnd; auto retain = msgwnd->together.events_ptr; @@ -1023,7 +1025,7 @@ namespace detail { if(msgwnd == pressed_wd_space) { - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); arg_click click_arg; click_arg.mouse_args = nullptr; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 8e5f24da..098f7556 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -945,7 +945,7 @@ namespace detail arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); - msgwnd->flags.action = mouse_action::pressed; + msgwnd->set_action(mouse_action::pressed); auto retain = msgwnd->together.events_ptr; if (brock.emit(event_code::mouse_down, msgwnd, arg, true, &context)) @@ -959,7 +959,7 @@ namespace detail if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y)) { //call the drawer mouse up event for restoring the surface graphics - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); arg.evt_code = event_code::mouse_up; draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); @@ -983,7 +983,7 @@ namespace detail if(nullptr == msgwnd) break; - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); if(msgwnd->flags.enabled) { auto retain = msgwnd->together.events_ptr; @@ -999,7 +999,7 @@ namespace detail if (msgwnd->dimension.is_hit(arg.pos)) { - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); if ((::nana::mouse::left_button == arg.button) && (pressed_wd == msgwnd)) { click_arg.window_handle = reinterpret_cast(msgwnd); @@ -1038,7 +1038,7 @@ namespace detail if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd)) { brock.event_msleave(hovered_wd); - hovered_wd->flags.action = mouse_action::normal; + hovered_wd->set_action(mouse_action::normal); hovered_wd = nullptr; //if msgwnd is neither captured window nor the child of captured window, @@ -1057,15 +1057,15 @@ namespace detail if(prev_captured_inside) { evt_code = event_code::mouse_leave; - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); } else { evt_code = event_code::mouse_enter; if (pressed_wd == msgwnd) - msgwnd->flags.action = mouse_action::pressed; + msgwnd->set_action(mouse_action::pressed); else if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); } arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); @@ -1082,9 +1082,9 @@ namespace detail if (hovered_wd != msgwnd) { if (pressed_wd == msgwnd) - msgwnd->flags.action = mouse_action::pressed; + msgwnd->set_action(mouse_action::pressed); else if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->flags.action = mouse_action::over; + msgwnd->set_action(mouse_action::over); hovered_wd = msgwnd; arg.evt_code = event_code::mouse_enter; @@ -1419,7 +1419,7 @@ namespace detail arg.pos.y = 0; arg.window_handle = reinterpret_cast(msgwnd); - msgwnd->flags.action = mouse_action::pressed; + msgwnd->set_action(mouse_action::pressed); pressed_wd_space = msgwnd; auto retain = msgwnd->together.events_ptr; @@ -1490,7 +1490,7 @@ namespace detail { if (msgwnd == pressed_wd_space) { - msgwnd->flags.action = mouse_action::normal; + msgwnd->set_action(mouse_action::normal); arg_click click_arg; click_arg.mouse_args = nullptr; diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index 1cce7648..c7605538 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -245,9 +245,7 @@ namespace nana if(wd) { auto iwd = reinterpret_cast(wd); - auto caret_wd = iwd->root_widget->other.attribute.root->focus; - - bool owns_caret = (caret_wd && (caret_wd->together.caret) && (caret_wd->together.caret->visible())); + bool owns_caret = (iwd->together.caret) && (iwd->together.caret->visible()); //The caret in X11 is implemented by Nana, it is different from Windows' //the caret in X11 is asynchronous, it is hard to hide and show the caret @@ -256,7 +254,7 @@ namespace nana if(owns_caret) { #ifndef NANA_X11 - caret_wd->together.caret->visible(false); + iwd->together.caret->visible(false); #else owns_caret = nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, false); #endif @@ -267,7 +265,7 @@ namespace nana if(owns_caret) { #ifndef NANA_X11 - caret_wd->together.caret->visible(true); + iwd->together.caret->visible(true); #else nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, true); #endif diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 47fd3e06..509e3142 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -108,7 +108,7 @@ namespace nana { //Test if the root widget is overlapped the specified widget //the pos of root widget is (0, 0) - if (overlap(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false) + if (overlapped(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false) return false; } @@ -365,7 +365,7 @@ namespace nana for (auto wd : data_sect.effects_bground_windows) { if (wd == sigwd || !wd->displayed() || - (false == overlap(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd))) + (false == overlapped(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd))) continue; if (sigwd->parent == wd->parent) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 5714789f..441a5ec5 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -845,13 +845,13 @@ namespace detail { window_layer::paint(wd, false, refresh_tree); this->map(wd, force_copy_to_screen); - - wd->drawer.graphics.save_as_file("d:\\button.bmp"); - wd->root_graph->save_as_file("d:\\button_root.bmp"); } else if (effects::edge_nimbus::none != wd->effect.edge_nimbus) { - this->map(wd, true); + //The window is still mapped because of edge nimbus effect. + //Avoid duplicate copy if action state is not changed and the window is not focused. + if ((wd->flags.action != wd->flags.action_before) || (bedrock::instance().focus() == wd)) + this->map(wd, true); } } else @@ -1398,9 +1398,10 @@ namespace detail if (!established) { + using effect_renderer = detail::edge_nimbus_renderer; + //remove the window from edge nimbus effect when it is destroying - using edge_nimbus = detail::edge_nimbus_renderer; - edge_nimbus::instance().erase(wd); + effect_renderer::instance().erase(wd); } else if (pa_root_attr != root_attr) { diff --git a/source/gui/layout_utility.cpp b/source/gui/layout_utility.cpp index c81273b3..3afc6e62 100644 --- a/source/gui/layout_utility.cpp +++ b/source/gui/layout_utility.cpp @@ -16,7 +16,7 @@ namespace nana { //overlap test if overlaped between r1 and r2 - bool overlap(const rectangle& r1, const rectangle& r2) + bool overlapped(const rectangle& r1, const rectangle& r2) { if (r1.y + (long long)(r1.height) <= r2.y) return false; if(r1.y >= r2.y + (long long)(r2.height)) return false; @@ -30,7 +30,7 @@ namespace nana //overlap, compute the overlap area between r1 and r2. the rect is for root bool overlap(const rectangle& r1, const rectangle& r2, rectangle& r) { - if(overlap(r1, r2)) + if(overlapped(r1, r2)) { auto l1 = static_cast(r1.x) + r1.width; auto l2 = static_cast(r2.x) + r2.width; diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 02639fc1..90b4bdce 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -42,7 +42,6 @@ namespace nana{ namespace widgets //sel_a_ and sel_b_ are not sorted, sel_b_ keeps the caret position. sel_a_ = editor_.select_.a; sel_b_ = editor_.select_.b; - editor_._m_make_select_string(selected_text_); } void set_caret_pos() @@ -227,8 +226,7 @@ namespace nana{ namespace widgets editor_.select_.b = dest_b_; editor_.points_.caret = (sel_a_ < sel_b_ ? sel_a_ : sel_b_); - std::wstring text; - editor_._m_make_select_string(text); + const auto text = editor_._m_make_select_string(); editor_._m_erase_select(); editor_._m_put(text); @@ -1684,16 +1682,12 @@ namespace nana{ namespace widgets return renderred; } - bool text_editor::mouse_enter(bool enter) + bool text_editor::mouse_enter(bool entering) { - if((false == enter) && (false == text_area_.captured)) + if ((false == entering) && (false == text_area_.captured)) API::window_cursor(window_, nana::cursor::arrow); - if(API::focus_window() == window_) - return false; - - render(false); - return true; + return false; } bool text_editor::mouse_move(bool left_button, const point& scrpos) @@ -2131,9 +2125,9 @@ namespace nana{ namespace widgets void text_editor::copy() const { - std::wstring str; - if(_m_make_select_string(str)) - nana::system::dataexch().set(str); + auto text = _m_make_select_string(); + if (!text.empty()) + nana::system::dataexch().set(text); } void text_editor::cut() @@ -2845,27 +2839,29 @@ namespace nana{ namespace widgets return points_.caret; } - bool text_editor::_m_make_select_string(std::wstring& text) const + std::wstring text_editor::_m_make_select_string() const { + std::wstring text; + nana::upoint a, b; - if (!_m_get_sort_select_points(a, b)) - return false; - - if(a.y != b.y) + if (_m_get_sort_select_points(a, b)) { - text = textbase_.getline(a.y).substr(a.x); - text += L"\r\n"; - for(unsigned i = a.y + 1; i < b.y; ++i) + if (a.y != b.y) { - text += textbase_.getline(i); + text = textbase_.getline(a.y).substr(a.x); text += L"\r\n"; + for (unsigned i = a.y + 1; i < b.y; ++i) + { + text += textbase_.getline(i); + text += L"\r\n"; + } + text += textbase_.getline(b.y).substr(0, b.x); } - text += textbase_.getline(b.y).substr(0, b.x); + else + text = textbase_.getline(a.y).substr(a.x, b.x - a.x); } - else - text = textbase_.getline(a.y).substr(a.x, b.x - a.x); - return true; + return text; } std::size_t eat_endl(const wchar_t* str, std::size_t pos) @@ -3021,8 +3017,8 @@ namespace nana{ namespace widgets bool text_editor::_m_move_select(bool record_undo) { nana::upoint caret = points_.caret; - std::wstring text; - if (_m_make_select_string(text)) + const auto text = _m_make_select_string(); + if (!text.empty()) { auto undo_ptr = std::unique_ptr(new undo_move_text(*this)); undo_ptr->set_selected_text(); From aba060360603a9e57d02356db53b1f51c45738c8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 19 Apr 2016 00:16:36 +0200 Subject: [PATCH 147/309] 3 instead of 1 step by list wheel scroll --- source/gui/widgets/listbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 707eb339..3ff96ced 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2289,9 +2289,9 @@ namespace nana index_pair target; if(upwards == false) - lister.forward(scroll.offset_y_dpl, 1, target); + lister.forward(scroll.offset_y_dpl, 3, target); // scheme ?? else - lister.backward(scroll.offset_y_dpl, 1, target); + lister.backward(scroll.offset_y_dpl, 3, target); if (target == scroll.offset_y_dpl) return false; From 526c6bc6ba35bd6b704d17e1fcce4dd738426524 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 20 Apr 2016 01:52:25 +0200 Subject: [PATCH 148/309] still not merged with develop --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3e64fdb9..d7868e3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=1 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=1 --branch=hotfix-1.3 https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From be7376e21426108f3543056f95427ed5833910e8 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 21 Apr 2016 16:18:55 +0800 Subject: [PATCH 149/309] fix the 1st issue of #125 --- source/gui/widgets/listbox.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 058dc61c..f50f0ae4 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -421,19 +421,24 @@ namespace nana return *this; } - std::string to_string(const export_options& exp_opt) const + std::string to_string(const export_options& exp_opt, const std::vector* model_cells) const { std::string item_str; bool ignore_first = true; - for (size_type idx{}; idx < exp_opt.columns_order.size(); ++idx) + + for (auto col : exp_opt.columns_order) { if (ignore_first) ignore_first = false; else item_str += exp_opt.sep; - item_str += cells[exp_opt.columns_order[idx]].text; + //Use the model cells instead if model cells is avaiable + if (model_cells) + item_str += model_cells->operator[](col).text; + else + item_str += cells[col].text; } return item_str; @@ -2879,12 +2884,23 @@ namespace nana first=false; else list_str += (to_utf8(cat.text) + exp_opt.endl); + + std::vector model_cells; for (auto i : cat.sorted) { - auto& it= cat.items[i] ; - if(it.flags.selected || !exp_opt.only_selected_items) - list_str += (it.to_string(exp_opt) + exp_opt.endl); + auto& item = cat.items[i]; + if (item.flags.selected || !exp_opt.only_selected_items) + { + //Test if the category have a model set. + if (cat.model_ptr) + { + cat.model_ptr->container()->to_cells(i).swap(model_cells); + list_str += (item.to_string(exp_opt, &model_cells) + exp_opt.endl); + } + else + list_str += (item.to_string(exp_opt, nullptr) + exp_opt.endl); + } } } return list_str ; From 79f484dd2e54211950bf9cb5ac0d60bf02bca941 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 23 Apr 2016 03:15:11 +0800 Subject: [PATCH 150/309] fix an alpha blend algorithm issue --- include/nana/paint/detail/image_processor.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/nana/paint/detail/image_processor.hpp b/include/nana/paint/detail/image_processor.hpp index 7cdc1658..4051eb90 100644 --- a/include/nana/paint/detail/image_processor.hpp +++ b/include/nana/paint/detail/image_processor.hpp @@ -330,19 +330,21 @@ namespace detail } const pixel_argb_t * s_end = s_rgb + rest; + auto rest_d_rgb = d_rgb; for(auto i = s_rgb; i != s_end; ++i) { if(i->element.alpha_channel) { if(i->element.alpha_channel != 255) { - d_rgb[3].element.red = unsigned(d_rgb[3].element.red * (255 - i->element.alpha_channel) + i->element.red * i->element.alpha_channel) / 255; - d_rgb[3].element.green = unsigned(d_rgb[3].element.green * (255 - i->element.alpha_channel) + i->element.green * i->element.alpha_channel) / 255; - d_rgb[3].element.blue = unsigned(d_rgb[3].element.blue * (255 - i->element.alpha_channel) + i->element.blue * i->element.alpha_channel) / 255; + rest_d_rgb->element.red = unsigned(rest_d_rgb->element.red * (255 - i->element.alpha_channel) + i->element.red * i->element.alpha_channel) / 255; + rest_d_rgb->element.green = unsigned(rest_d_rgb->element.green * (255 - i->element.alpha_channel) + i->element.green * i->element.alpha_channel) / 255; + rest_d_rgb->element.blue = unsigned(rest_d_rgb->element.blue * (255 - i->element.alpha_channel) + i->element.blue * i->element.alpha_channel) / 255; } else - d_rgb[3] = *i; + *rest_d_rgb = *i; } + ++rest_d_rgb; } d_rgb = pixel_at(d_rgb, d_step_bytes); s_rgb = pixel_at(s_rgb, s_step_bytes); From 767c57d2b8b3f85f1267e6b900d145cbb89885b4 Mon Sep 17 00:00:00 2001 From: Leonardo Backes Vargas Date: Mon, 25 Apr 2016 09:38:45 -0300 Subject: [PATCH 151/309] Updates the place::dock_create to return the widget created by the factory function. --- include/nana/gui/place.hpp | 2 +- source/gui/place.cpp | 6 +++--- source/gui/place_parts.hpp | 17 +++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/include/nana/gui/place.hpp b/include/nana/gui/place.hpp index b10a8a18..2f5dc52c 100644 --- a/include/nana/gui/place.hpp +++ b/include/nana/gui/place.hpp @@ -141,7 +141,7 @@ namespace nana } place& dock(const std::string& dockname, std::string factory_name, std::function(window)> factory); - place& dock_create(const std::string& factory); + widget* dock_create(const std::string& factory); private: implement * impl_; }; diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 8f981475..01b70de1 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -2837,7 +2837,7 @@ namespace nana return *this; } - place& place::dock_create(const std::string& factory) + widget* place::dock_create(const std::string& factory) { auto i = impl_->dock_factoris.find(factory); if (i == impl_->dock_factoris.end()) @@ -2857,10 +2857,10 @@ namespace nana dock_ptr->dockarea->move(dock_ptr->attached->field_area); } - dock_ptr->dockarea->add_pane(i->second->factories[factory]); + return dock_ptr->dockarea->add_pane(i->second->factories[factory]); } - return *this; + return nullptr; } //end class place }//end namespace nana diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 3b0edceb..1c969884 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -97,7 +97,7 @@ namespace nana graph.rectangle(r, true, xclr); } - + r.x += (r.width - 16) / 2; r.y = (r.height - 16) / 2; @@ -278,13 +278,15 @@ namespace nana } - void add_pane(factory & fn) + widget* add_pane(factory & fn) { auto fn_ptr = &fn; - API::dev::affinity_execute(*this, [this, fn_ptr] + widget * w = nullptr; + API::dev::affinity_execute(*this, [this, fn_ptr, &w] { - _m_add_pane(*fn_ptr); + w=_m_add_pane(*fn_ptr); }); + return w; } void float_away(const ::nana::point& move_pos) @@ -330,7 +332,7 @@ namespace nana return (nullptr != container_); } private: - void _m_add_pane(factory & fn) + widget* _m_add_pane(factory & fn) { rectangle r{ point(), this->size() }; @@ -385,6 +387,7 @@ namespace nana } panels_.emplace_back(); + widget * w=wdg.get(); panels_.back().widget_ptr.swap(wdg); for (auto & pn : panels_) @@ -392,7 +395,9 @@ namespace nana if (pn.widget_ptr) pn.widget_ptr->move(r); } + return w; } + return nullptr; } private: window host_window_{nullptr}; @@ -693,4 +698,4 @@ namespace nana }//end namespace place_parts }//end namespace nana -#endif //NANA_GUI_PLACE_PARTS_HPP \ No newline at end of file +#endif //NANA_GUI_PLACE_PARTS_HPP From 28ec691485a68b009b991a54cb6afde6e0b648e4 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 10 May 2016 12:48:00 +0800 Subject: [PATCH 152/309] small changes --- source/gui/detail/bedrock_windows.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 7bd5d505..d6747a97 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -28,6 +26,9 @@ #include #include +#include +#include + #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x020A #endif From df68cfa3adbdbf04842f584698aa8b55e88c534a Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 10 May 2016 15:52:06 +0800 Subject: [PATCH 153/309] a bool param to determines whether the caret move to end of text --- .../nana/gui/detail/inner_fwd_implement.hpp | 14 +++---- .../gui/widgets/skeletons/text_editor.hpp | 10 ++++- include/nana/gui/widgets/textbox.hpp | 12 ++++-- source/gui/widgets/combox.cpp | 4 +- source/gui/widgets/skeletons/text_editor.cpp | 41 +++++++++++++------ source/gui/widgets/spinbox.cpp | 6 +-- source/gui/widgets/textbox.cpp | 9 ++-- 7 files changed, 61 insertions(+), 35 deletions(-) diff --git a/include/nana/gui/detail/inner_fwd_implement.hpp b/include/nana/gui/detail/inner_fwd_implement.hpp index 659bc9a9..a1bc1aaf 100644 --- a/include/nana/gui/detail/inner_fwd_implement.hpp +++ b/include/nana/gui/detail/inner_fwd_implement.hpp @@ -112,21 +112,19 @@ namespace nana{ struct root_misc { - typedef basic_window core_window_t; - - core_window_t * window; + basic_window * window; nana::paint::graphics root_graph; shortkey_container shortkeys; struct condition_rep { - bool ignore_tab{ false }; //ignore tab when the focus is changed by pressing tab. - core_window_t* pressed{nullptr}; //The handle to a window which has been pressed by pressing left button of mouse. - core_window_t* pressed_by_space{ nullptr }; //The handle to a window which has been pressed by pressing spacebar. - core_window_t* hovered{nullptr}; //the latest window that mouse moved + bool ignore_tab{ false }; //ignore tab when the focus is changed by TAB key. + basic_window* pressed{ nullptr }; //The handle to a window which has been pressed by mouse left button. + basic_window* pressed_by_space{ nullptr }; //The handle to a window which has been pressed by SPACEBAR key. + basic_window* hovered{ nullptr }; //the latest window that mouse moved }condition; - root_misc(core_window_t * wd, unsigned width, unsigned height) + root_misc(basic_window * wd, unsigned width, unsigned height) : window(wd), root_graph({ width, height }) {} diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 0dad496e..92b6a5ac 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -42,6 +42,12 @@ namespace nana{ namespace widgets using command = EnumCommand; using container = std::deque < std::unique_ptr> >; + void clear() + { + commands_.clear(); + pos_ = 0; + } + void max_steps(std::size_t maxs) { max_steps_ = maxs; @@ -58,7 +64,7 @@ namespace nana{ namespace widgets { enabled_ = enb; if (!enb) - commands_.clear(); + clear(); } bool enabled() const @@ -204,7 +210,7 @@ namespace nana{ namespace widgets unsigned screen_lines() const; bool getline(std::size_t pos, ::std::wstring&) const; - void text(std::wstring); + void text(std::wstring, bool end_caret); std::wstring text() const; /// Sets caret position through text coordinate. diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index e385b633..13b4eb9b 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -1,7 +1,7 @@ /** * A Textbox Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -138,8 +138,14 @@ namespace nana /// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line. textbox& indention(bool, std::function generator = {}); - //A workaround for reset, explicit default constructor syntax, because VC2013 incorrectly treats {} as {0}. - textbox& reset(const std::string& = std::string()); ///< discard the old text and set a new text + /// Discards the old text and set a new text. It also clears the filename/edited flags and undo command. + /// A workaround for reset, explicit default constructor syntax, because VC2013 incorrectly treats {} as {0}. + /* + * @param text A new text replaces the old text. + * @param end_caret Indicates whether to position the caret to the end of text. + * @return a reference of *this. + */ + textbox& reset(const std::string& text = std::string(), bool end_caret = true); ///< discard the old text and set a new text /// The file of last store operation. std::string filename() const; diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index 2e1d4546..374a9baa 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -351,7 +351,7 @@ namespace nana if (calc_where(*graph_, pos.x, pos.y)) state_.button_state = element_state::normal; - editor_->text(::nana::charset(items_[index]->item_text, ::nana::unicode::utf8)); + editor_->text(::nana::charset(items_[index]->item_text, ::nana::unicode::utf8), false); _m_draw_push_button(widget_->enabled()); _m_draw_image(); @@ -993,7 +993,7 @@ namespace nana auto editor = _m_impl().editor(); if (editor) - editor->text(to_wstring(str)); + editor->text(to_wstring(str), false); API::refresh_window(*this); } diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 90b4bdce..a1d9d1e2 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include namespace nana{ namespace widgets @@ -442,11 +441,8 @@ namespace nana{ namespace widgets editor_._m_get_scrollbar_size(); - auto x = points.caret.x; auto& lnstr = textbase.getline(points.caret.y); - - if (x > lnstr.size()) x = static_cast(lnstr.size()); - + const auto x = (points.caret.x > lnstr.size() ? static_cast(lnstr.size()) : points.caret.x); auto const text_w = editor_._m_pixels_by_char(lnstr, x); unsigned area_w = editor_._m_text_area().width; @@ -515,11 +511,12 @@ namespace nana{ namespace widgets const wchar_t* begin; const wchar_t* end; unsigned pixels; - - text_section() + /* + text_section() //deprecated { throw std::runtime_error("text_section default construction is forbidden."); } + */ text_section(const wchar_t* ptr, const wchar_t* endptr) : begin(ptr), end(endptr) @@ -1808,12 +1805,34 @@ namespace nana{ namespace widgets return true; } - void text_editor::text(std::wstring str) + void text_editor::text(std::wstring str, bool end_caret) { + undo_.clear(); + textbase_.erase_all(); _m_reset(); behavior_->pre_calc_lines(width_pixels()); - put(std::move(str)); + if (!end_caret) + { + auto undo_ptr = std::unique_ptr{ new undo_input_text(*this, str) }; + undo_ptr->set_caret_pos(); + + _m_put(std::move(str)); + + undo_.push(std::move(undo_ptr)); + + if (graph_) + { + behavior_->adjust_caret_into_screen(); + reset_caret(); + render(API::is_focus_ready(window_)); + _m_scrollbar(); + + points_.xpos = 0; + } + } + else + put(std::move(str)); } std::wstring text_editor::text() const @@ -2324,7 +2343,6 @@ namespace nana{ namespace widgets behavior_->adjust_caret_into_screen(); render(true); _m_scrollbar(); - } void text_editor::move_ns(bool to_north) @@ -2965,9 +2983,6 @@ namespace nana{ namespace widgets nana::size text_editor::_m_text_extent_size(const char_type* str, size_type n) const { - if (!graph_) - return{}; - if(mask_char_) { std::wstring maskstr; diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 4dc0dd70..a4105075 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -422,9 +422,9 @@ namespace nana return; if (API::is_focus_ready(editor_->window_handle())) - editor_->text(to_wstring(range_->value())); + editor_->text(to_wstring(range_->value()), false); else - editor_->text(to_wstring(modifier_.prefix + range_->value() + modifier_.suffix)); + editor_->text(to_wstring(modifier_.prefix + range_->value() + modifier_.suffix), false); _m_draw_spins(spin_stated_); } @@ -697,7 +697,7 @@ namespace nana auto editor = get_drawer_trigger().impl()->editor(); if (editor) { - editor->text(to_wstring(text)); + editor->text(to_wstring(text), false); API::refresh_window(*this); } } diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index adb1a93a..12f42872 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -254,13 +254,14 @@ namespace drawerbase { return *this; } - textbox& textbox::reset(const std::string& str) + textbox& textbox::reset(const std::string& str, bool end_caret) { internal_scope_guard lock; auto editor = get_drawer_trigger().editor(); if (editor) - { - editor->text(to_wstring(str)); + { + editor->text(to_wstring(str), end_caret); + editor->textbase().reset(); API::update_window(this->handle()); } @@ -622,7 +623,7 @@ namespace drawerbase { auto editor = get_drawer_trigger().editor(); if (editor) { - editor->text(to_wstring(str)); + editor->text(to_wstring(str), false); API::update_window(this->handle()); } } From 3069d998f04f0b84794f751ef7749d0b8765a307 Mon Sep 17 00:00:00 2001 From: Besh81 Date: Tue, 10 May 2016 18:10:53 +0200 Subject: [PATCH 154/309] textbox and combox behaviours textbox: when uneditable the caret is hide combox: when uneditable (default) - inherit the textbox behaviour - open the lister clicking the textbox area also --- source/gui/widgets/combox.cpp | 37 ++++++++++---------- source/gui/widgets/skeletons/text_editor.cpp | 13 +++++-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index c5df35f8..aec594ca 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -171,7 +171,7 @@ namespace nana if(editor_) { editor_->editable(enb); - + editor_->show_caret(enb); if (!enb) { editor_->ext_renderer().background = [this](graph_reference graph, const ::nana::rectangle&, const ::nana::color&) @@ -245,22 +245,23 @@ namespace nana void open_lister_if_push_button_positioned() { - if((nullptr == state_.lister) && !items_.empty() && (parts::push_button == state_.pointer_where)) - { - module_.items.clear(); - std::copy(items_.cbegin(), items_.cend(), std::back_inserter(module_.items)); - state_.lister = &form_loader()(widget_->handle(), nana::rectangle(0, widget_->size().height, widget_->size().width, 10), true); - state_.lister->renderer(item_renderer_); - state_.lister->set_module(module_, image_pixels_); - state_.item_index_before_selection = module_.index; - //The lister window closes by itself. I just take care about the destroy event. - //The event should be destroy rather than unload. Because the unload event is invoked while - //the lister is not closed, if popuping a message box, the lister will cover the message box. - state_.lister->events().destroy.connect_unignorable([this] + if(nullptr == state_.lister && !items_.empty()) + if((parts::push_button == state_.pointer_where && editor_->attr().editable) || !editor_->attr().editable) { - _m_lister_close_sig(); - }); - } + module_.items.clear(); + std::copy(items_.cbegin(), items_.cend(), std::back_inserter(module_.items)); + state_.lister = &form_loader()(widget_->handle(), nana::rectangle(0, widget_->size().height, widget_->size().width, 10), true); + state_.lister->renderer(item_renderer_); + state_.lister->set_module(module_, image_pixels_); + state_.item_index_before_selection = module_.index; + //The lister window closes by itself. I just take care about the destroy event. + //The event should be destroy rather than unload. Because the unload event is invoked while + //the lister is not closed, if popuping a message box, the lister will cover the message box. + state_.lister->events().destroy.connect_unignorable([this] + { + _m_lister_close_sig(); + }); + } } void scroll_items(bool upwards) @@ -622,8 +623,8 @@ namespace nana if(drawer_->widget_ptr()->enabled()) { auto * editor = drawer_->editor(); - if (!editor->mouse_pressed(arg)) - drawer_->open_lister_if_push_button_positioned(); + editor->mouse_pressed(arg); + drawer_->open_lister_if_push_button_positioned(); drawer_->draw(); if(editor->attr().editable) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index fc6086cc..21fa8cdc 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1639,11 +1639,14 @@ namespace nana{ namespace widgets bool text_editor::mouse_move(bool left_button, const point& scrpos) { cursor cur = cursor::iterm; - if ((!hit_text_area(scrpos)) && (!text_area_.captured)) + if(((!hit_text_area(scrpos)) && (!text_area_.captured)) || !attributes_.editable || !API::window_enabled(window_)) cur = cursor::arrow; API::window_cursor(window_, cur); + if(!attributes_.editable) + return false; + if(left_button) { auto caret_pos_before = caret(); @@ -1662,6 +1665,9 @@ namespace nana{ namespace widgets bool text_editor::mouse_pressed(const arg_mouse& arg) { + if(!attributes_.editable) + return false; + if (event_code::mouse_down == arg.evt_code) { if (!hit_text_area(arg.pos)) @@ -1790,6 +1796,9 @@ namespace nana{ namespace widgets reset_caret_pixels(); } + if(!attributes_.editable) + visible = false; + API::caret_visible(window_, visible); if(visible) @@ -3065,7 +3074,7 @@ namespace nana{ namespace widgets graph_.palette(false, scheme_->selection.get_color()); //The text is not selected or the whole line text is selected - if (!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y)) + if(!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y) || !attributes_.editable) { bool selected = (a.y < str_pos.y && str_pos.y < b.y); for (auto & ent : reordered) From 9f61e21c87243ed0a209b9a8fe487b6a3bdd9700 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 11 May 2016 07:41:59 +0800 Subject: [PATCH 155/309] guarantee consistent KeyRelease behavior on all supported platform. X will send a KeyRelease after KeyPress even though the key is still pressed. --- source/detail/x11/msg_dispatcher.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source/detail/x11/msg_dispatcher.hpp b/source/detail/x11/msg_dispatcher.hpp index 7ba64b4f..2f1688e0 100644 --- a/source/detail/x11/msg_dispatcher.hpp +++ b/source/detail/x11/msg_dispatcher.hpp @@ -1,6 +1,6 @@ /* * Message Dispatcher Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -164,7 +164,7 @@ namespace detail private: void _m_msg_driver() { - int fd_X11 = ConnectionNumber(display_); + const int fd_X11 = ConnectionNumber(display_); msg_packet_tag msg_pack; XEvent event; @@ -177,6 +177,18 @@ namespace detail if(pending) { ::XNextEvent(display_, &event); + + if(KeyRelease == event.type) + { + //Check whether the key is pressed, because X will send KeyRelease when pressing and + //holding a key if auto repeat is on. + char keymap[32]; + ::XQueryKeymap(display_, keymap); + + if(keymap[event.xkey.keycode / 8] & (1 << (event.xkey.keycode % 8))) + continue; + } + if(::XFilterEvent(&event, None)) continue; } From ceff7c0c278ff3802d432fff3b8271c1f8669deb Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 12 May 2016 23:33:23 +0800 Subject: [PATCH 156/309] throw right exception --- source/gui/detail/window_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 441a5ec5..0d173e0c 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -275,7 +275,7 @@ namespace detail if (impl_->wd_register.available(owner)) { if (owner->flags.destroying) - throw std::logic_error("the specified owner is destory"); + throw std::runtime_error("the specified owner is destory"); native = (category::flags::frame == owner->other.category ? owner->other.attribute.frame->container : owner->root_widget->root); From a30eef53ecb1df156b98dcb52f13062a3dd07856 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 12 May 2016 23:34:40 +0800 Subject: [PATCH 157/309] fix bug that menu_popuper doesn't popup a menu --- source/gui/widgets/menu.cpp | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index e132f7b5..7c585f3e 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -1370,24 +1370,8 @@ namespace nana return; } } - bool popup = false; - switch(mouse_) - { - case mouse::left_button: - popup = arg.left_button; - break; - case mouse::middle_button: - popup = arg.mid_button; - break; - case mouse::right_button: - popup = arg.right_button; - break; - case mouse::any_button: - popup = true; - default: - break; - } - if(popup) + + if((mouse::any_button == mouse_) || (mouse_ == arg.button)) mobj_.popup(owner_, pos_.x, pos_.y); } //end class From c3611ff2d29bd4730a73aa05951a946b0df5a405 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 19 May 2016 15:30:07 +0800 Subject: [PATCH 158/309] fix an issue that any_cast returns null if value type has cv-specifier --- include/nana/any.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nana/any.hpp b/include/nana/any.hpp index 491169fc..ed711146 100644 --- a/include/nana/any.hpp +++ b/include/nana/any.hpp @@ -150,7 +150,7 @@ namespace nana if (!operand) return nullptr; - auto holder = dynamic_cast*>(operand->content_); + auto holder = dynamic_cast::type>*>(operand->content_); return (holder ? &holder->value : nullptr); } From 9947d0c5114fe8db75c6700e7268228e1db1979e Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 02:48:00 +0800 Subject: [PATCH 159/309] remove conversion constructors of point,size and rectangle --- include/nana/basic_types.hpp | 123 +++++++++----- include/nana/gui/detail/effects_renderer.hpp | 2 +- source/basic_types.cpp | 163 ++++++------------- source/gui/detail/basic_window.cpp | 4 +- source/gui/detail/bedrock_windows.cpp | 6 +- source/gui/element.cpp | 4 +- source/gui/place_parts.hpp | 6 +- source/gui/programming_interface.cpp | 2 +- source/gui/widgets/categorize.cpp | 8 +- source/gui/widgets/treebox.cpp | 5 +- 10 files changed, 147 insertions(+), 176 deletions(-) diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index 4d13b6ec..adbf55da 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -84,7 +84,7 @@ namespace nana enum class mouse_action { - begin, normal = begin, over, pressed, end + begin, normal = begin, hovered, pressed, end }; enum class element_state @@ -337,6 +337,8 @@ namespace nana bool operator==(const color& other) const; bool operator!=(const color& other) const; + + friend color operator+(const color&, const color&); private: double r_{ 0.0 }; double g_{ 0.0 }; @@ -344,60 +346,91 @@ namespace nana double a_{ 0.0 }; //invisible }; - - struct rectangle; - - struct point + template + struct basic_point { - point(); - point(int x, int y); - point(const rectangle&); + //typedef-names + using value_type = T; - point& operator=(const rectangle&); - bool operator==(const point&) const; - bool operator!=(const point&) const; - bool operator<(const point&) const; - bool operator<=(const point&) const; - bool operator>(const point&) const; - bool operator>=(const point&) const; + //data member + value_type x{}; + value_type y{}; - point operator-(const point&) const; - point operator+(const point&) const; - point& operator-=(const point&); - point& operator+=(const point&); + //member functions + basic_point() = default; - int x; - int y; + basic_point(value_type x, value_type y) + : x{ x }, y{y} + {} + + bool operator==(const basic_point& other) const noexcept + { + return (x == other.x && y == other.y); + } + + bool operator!=(const basic_point& other) const noexcept + { + return (x != other.x || y != other.y); + } + + bool operator<(const basic_point& other) const noexcept + { + return ((y < other.y) || (y == other.y && x < other.x)); + } + + bool operator<=(const basic_point& other) const noexcept + { + return ((y < other.y) || (y == other.y && x <= other.x)); + } + + bool operator>(const basic_point& other) const noexcept + { + return ((y > other.y) || (y == other.y && x > other.x)); + } + + bool operator>=(const basic_point& other) const noexcept + { + return ((y > other.y) || (y == other.y && x >= other.x)); + } + + basic_point operator-(const basic_point& other) const noexcept + { + return{ x - other.x, y - other.y }; + } + + basic_point operator+(const basic_point& other) const noexcept + { + return{ x + other.x, y + other.y }; + } + + basic_point& operator-=(const basic_point& other) noexcept + { + x -= other.x; + y -= other.y; + return *this; + } + + basic_point& operator+=(const basic_point& other) noexcept + { + x += other.x; + y += other.y; + return *this; + } }; - struct upoint - { - typedef unsigned value_type; - - upoint(); - upoint(value_type x, value_type y); - bool operator==(const upoint&) const; - bool operator!=(const upoint&) const; - bool operator<(const upoint&) const; - bool operator<=(const upoint&) const; - bool operator>(const upoint&) const; - bool operator>=(const upoint&) const; - - value_type x; - value_type y; - }; + using point = basic_point; + using upoint = basic_point; struct size { using value_type = unsigned; size(); size(value_type width, value_type height); - size(const rectangle&); - - size& operator=(const rectangle&); bool empty() const; ///< true if width * height == 0 bool is_hit(const point&) const; ///< Assume it is a rectangle at (0,0), and check whether a specified position is in the rectange. + size& shift(); + bool operator==(const size& rhs) const; bool operator!=(const size& rhs) const; size operator+(const size&) const; @@ -419,8 +452,11 @@ namespace nana rectangle& operator=(const point&); rectangle& operator=(const size&); - rectangle& set_pos(const point&); - rectangle& set_size(const size&); + point position() const noexcept; + rectangle& position(const point&) noexcept; + + size dimension() const noexcept; + rectangle& dimension(const size&) noexcept; rectangle& pare_off(int pixels); ///(wd->effect.edge_nimbus) & static_cast(effects::edge_nimbus::active))) return true; - else if((static_cast(wd->effect.edge_nimbus) & static_cast(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::over)) + else if((static_cast(wd->effect.edge_nimbus) & static_cast(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered)) return true; return false; } diff --git a/source/basic_types.cpp b/source/basic_types.cpp index c8bd2c34..5820c3cf 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -528,124 +528,25 @@ namespace nana return (px_color().value != other.px_color().value); } + color operator+(const color& x, const color& y) + { + double a = x.a_ + y.a_; + auto r = static_cast(x.r_ + y.r_); + auto g = static_cast(x.g_ + y.g_); + auto b = static_cast(x.b_ + y.b_); + + return color{ + r > 255 ? 255 : r, + g > 255 ? 255 : g, + b > 255 ? 255 : b, + a > 1.0 ? 1.0 : a }; + } //end class color - //struct point - point::point():x(0), y(0){} - point::point(int x, int y):x(x), y(y){} - point::point(const rectangle& r) - : x(r.x), y(r.y) - {} - point& point::operator=(const rectangle& r) - { - x = r.x; - y = r.y; - return *this; - } - - bool point::operator==(const point& rhs) const - { - return ((x == rhs.x) && (y == rhs.y)); - } - - bool point::operator!=(const point& rhs) const - { - return ((x != rhs.x) || (y != rhs.y)); - } - - bool point::operator<(const point& rhs) const - { - return ((y < rhs.y) || (y == rhs.y && x < rhs.x)); - } - - bool point::operator<=(const point& rhs) const - { - return ((y < rhs.y) || (y == rhs.y && x <= rhs.x)); - } - - bool point::operator>(const point& rhs) const - { - return ((y > rhs.y) || (y == rhs.y && x > rhs.x)); - } - - bool point::operator>=(const point& rhs) const - { - return ((y > rhs.y) || (y == rhs.y && x >= rhs.x)); - } - - point point::operator-(const point& rhs) const - { - return{x - rhs.x, y - rhs.y}; - } - - point point::operator+(const point& rhs) const - { - return{ x + rhs.x, y + rhs.y }; - } - - point& point::operator-=(const point& rhs) - { - x -= rhs.x; - y -= rhs.y; - return *this; - } - - point& point::operator+=(const point& rhs) - { - x += rhs.x; - y += rhs.y; - return *this; - } - //end struct point - - //struct upoint - upoint::upoint():x(0), y(0){} - upoint::upoint(unsigned x, unsigned y):x(x), y(y){} - - bool upoint::operator==(const upoint& rhs) const - { - return ((x == rhs.x) && (y == rhs.y)); - } - - bool upoint::operator!=(const upoint& rhs) const - { - return ((x != rhs.x) || (y != rhs.y)); - } - - bool upoint::operator<(const upoint& rhs) const - { - return ((y < rhs.y) || (y == rhs.y && x < rhs.x)); - } - - bool upoint::operator<=(const upoint& rhs) const - { - return ((y < rhs.y) || (y == rhs.y && x <= rhs.x)); - } - - bool upoint::operator>(const upoint& rhs) const - { - return ((y > rhs.y) || (y == rhs.y && x > rhs.x)); - } - - bool upoint::operator>=(const upoint& rhs) const - { - return ((y > rhs.y) || (y == rhs.y && x >= rhs.x)); - } - //end struct upoint //struct size size::size():width(0), height(0){} size::size(value_type width, value_type height) : width(width), height(height){} - size::size(const rectangle& r) - : width(r.width), height(r.height) - {} - - size& size::operator=(const rectangle& r) - { - width = r.width; - height = r.height; - return *this; - } bool size::empty() const { @@ -657,6 +558,12 @@ namespace nana return (0 <= pos.x && pos.x < static_cast(width) && 0 <= pos.y && pos.y < static_cast(height)); } + size& size::shift() + { + std::swap(width, height); + return *this; + } + bool size::operator==(const size& rhs) const { return (width == rhs.width) && (height == rhs.height); @@ -714,19 +621,38 @@ namespace nana return *this; } - rectangle& rectangle::set_pos(const point& pos) + point rectangle::position() const { - x = pos.x; - y = pos.y; + return{ x, y }; + } + + rectangle& rectangle::position(const point& p) + { + x = p.x; + y = p.y; return *this; } + size rectangle::dimension() const + { + return{width, height}; + } + + rectangle& rectangle::dimension(const size& sz) + { + width = sz.width; + height = sz.height; + return *this; + } + + /* rectangle& rectangle::set_size(const size& sz) { width = sz.width; height = sz.height; return *this; } + */ rectangle& rectangle::pare_off(int pixels) { @@ -763,6 +689,13 @@ namespace nana { return (0 == width) || (0 == height); } + + rectangle& rectangle::shift() + { + std::swap(x, y); + std::swap(width, height); + return *this; + } //end struct rectangle //class rectangle_rotator diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 6e592a0e..5c149ec3 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -354,8 +354,8 @@ namespace nana void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r) { - pos_owner = pos_root = r; - dimension = r; + pos_owner = pos_root = r.position(); + dimension = r.dimension(); if (parent) pos_root += parent->pos_root; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 098f7556..b84549bd 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -999,7 +999,7 @@ namespace detail if (msgwnd->dimension.is_hit(arg.pos)) { - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); if ((::nana::mouse::left_button == arg.button) && (pressed_wd == msgwnd)) { click_arg.window_handle = reinterpret_cast(msgwnd); @@ -1065,7 +1065,7 @@ namespace detail if (pressed_wd == msgwnd) msgwnd->set_action(mouse_action::pressed); else if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); } arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); @@ -1084,7 +1084,7 @@ namespace detail if (pressed_wd == msgwnd) msgwnd->set_action(mouse_action::pressed); else if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); hovered_wd = msgwnd; arg.evt_code = event_code::mouse_enter; diff --git a/source/gui/element.cpp b/source/gui/element.cpp index e1f4b649..48adbbfc 100644 --- a/source/gui/element.cpp +++ b/source/gui/element.cpp @@ -1300,7 +1300,7 @@ namespace nana if (stretch_all_) { if (from_r.width == to_r.width && from_r.height == to_r.height) - method_->paste(from_r, dst, to_r); + method_->paste(from_r, dst, to_r.position()); else method_->stretch(from_r, dst, to_r); @@ -1392,7 +1392,7 @@ namespace nana if (top_) { src_r.height = top_; - method_->paste(src_r, dst, to_r); + method_->paste(src_r, dst, to_r.position()); } if (bottom_) { diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 1c969884..5f777e3b 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -135,7 +135,7 @@ namespace nana if (!x_pointed_) return; - x_state_ = ::nana::mouse_action::over; + x_state_ = ::nana::mouse_action::hovered; refresh(graph); API::dev::lazy_refresh(); @@ -387,7 +387,7 @@ namespace nana } panels_.emplace_back(); - widget * w=wdg.get(); + auto wdg = wdg.get(); panels_.back().widget_ptr.swap(wdg); for (auto & pn : panels_) @@ -395,7 +395,7 @@ namespace nana if (pn.widget_ptr) pn.widget_ptr->move(r); } - return w; + return wdg; } return nullptr; } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 6dcfc63a..133b8326 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -1358,7 +1358,7 @@ namespace API { case nana::mouse_action::normal: return (is_focused ? nana::element_state::focus_normal : nana::element_state::normal); - case nana::mouse_action::over: + case nana::mouse_action::hovered: return (is_focused ? nana::element_state::focus_hovered : nana::element_state::hovered); case nana::mouse_action::pressed: return nana::element_state::pressed; diff --git a/source/gui/widgets/categorize.cpp b/source/gui/widgets/categorize.cpp index a79073d4..cf29e267 100644 --- a/source/gui/widgets/categorize.cpp +++ b/source/gui/widgets/categorize.cpp @@ -89,7 +89,7 @@ namespace nana if(ui_el_.what == ui_el_.item_root) { - _m_item_bground(graph, r.x + 1, r.y, r.width - 2, r.height, (state == mouse_action::pressed ? mouse_action::pressed : mouse_action::over)); + _m_item_bground(graph, r.x + 1, r.y, r.width - 2, r.height, (state == mouse_action::pressed ? mouse_action::pressed : mouse_action::hovered)); graph.rectangle(r, false, static_cast(0x3C7FB1)); if(state == mouse_action::pressed) { @@ -114,8 +114,8 @@ namespace nana mouse_action state_arrow, state_name; if(mouse_action::pressed != state) { - state_arrow = (ui_el_.what == ui_el_.item_arrow ? mouse_action::over : mouse_action::normal); - state_name = (ui_el_.what == ui_el_.item_name ? mouse_action::over : mouse_action::normal); + state_arrow = (ui_el_.what == ui_el_.item_arrow ? mouse_action::hovered : mouse_action::normal); + state_name = (ui_el_.what == ui_el_.item_name ? mouse_action::hovered : mouse_action::normal); } else { @@ -170,7 +170,7 @@ namespace nana nana::color clr_top(static_cast(0xEAEAEA)), clr_bottom(static_cast(0xDCDCDC)); switch(state) { - case mouse_action::over: + case mouse_action::hovered: clr_top.from_rgb(0xdf, 0xf2, 0xfc); clr_bottom.from_rgb(0xa9, 0xda, 0xf5); break; diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 11b4508f..e319b54f 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1270,7 +1270,7 @@ namespace nana if(size.width > attr.area.width || size.height > attr.area.height) { nana::size fit_size; - nana::fit_zoom(size, attr.area, fit_size); + nana::fit_zoom(size, attr.area.dimension(), fit_size); attr.area.x += (attr.area.width - fit_size.width) / 2; attr.area.y += (attr.area.height - fit_size.height) / 2; @@ -1442,8 +1442,9 @@ namespace nana virtual bool comp_attribute(component_t comp, comp_attribute_t& attr) const override { attr.area = node_r_; - if(impl_->data.comp_placer->locate(comp, node_attr_, &attr.area)) + if (impl_->data.comp_placer->locate(comp, node_attr_, &attr.area)) { + attr.mouse_pointed = node_attr_.mouse_pointed; attr.area.x += pos_.x; attr.area.y += pos_.y; return true; From 6217232a31fe55319f88027950ea318f98ad26f0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 02:51:30 +0800 Subject: [PATCH 160/309] add a new member function of pixel_buffer for rotating image --- include/nana/paint/graphics.hpp | 4 +- include/nana/paint/pixel_buffer.hpp | 1 + source/paint/graphics.cpp | 23 +++ source/paint/pixel_buffer.cpp | 212 +++++++++++++++++++++++++--- 4 files changed, 216 insertions(+), 24 deletions(-) diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index 501d30fc..fec075ab 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -111,6 +111,7 @@ namespace nana void bitblt(const ::nana::rectangle& r_dst, const graphics& src); ///< Transfers the color data corresponding to r_dst from the src graphics to this graphics. void bitblt(const ::nana::rectangle& r_dst, const graphics& src, const point& p_src);///< Transfers the color data corresponding to r_dst from the src graphics at point p_src to this graphics. + void blend(const ::nana::rectangle& r, const ::nana::color&, double fade_rate); void blend(const ::nana::rectangle& s_r, graphics& dst, const point& d_pos, double fade_rate) const;///< blends with the dst object. void blur(const ::nana::rectangle& r, std::size_t radius); ///< Blur process. @@ -144,8 +145,6 @@ namespace nana unsigned bidi_string(const nana::point&, const wchar_t *, std::size_t len); unsigned bidi_string(const point& pos, const char*, std::size_t len); - void blend(const ::nana::rectangle& r, const ::nana::color&, double fade_rate); - void set_pixel(int x, int y, const ::nana::color&); void set_pixel(int x, int y); @@ -167,6 +166,7 @@ namespace nana void rectangle(const ::nana::rectangle&, bool solid); void rectangle(const ::nana::rectangle&, bool solid, const color&); void frame_rectangle(const ::nana::rectangle&, const color& left, const color& top, const color& right, const color& bottom); + void frame_rectangle(const ::nana::rectangle&, const color&, unsigned gap); void gradual_rectangle(const ::nana::rectangle&, const color& from, const color& to, bool vertical); void round_rectangle(const ::nana::rectangle&, unsigned radius_x, unsigned radius_y, const color&, bool solid, const color& color_if_solid); diff --git a/include/nana/paint/pixel_buffer.hpp b/include/nana/paint/pixel_buffer.hpp index 49d2fc4e..6b6a4994 100644 --- a/include/nana/paint/pixel_buffer.hpp +++ b/include/nana/paint/pixel_buffer.hpp @@ -75,6 +75,7 @@ namespace nana{ namespace paint void blend(const nana::rectangle& s_r, drawable_type dw_dst, const nana::point& d_pos, double fade_rate) const; void blur(const nana::rectangle& r, std::size_t radius); + pixel_buffer rotate(double angle, const color& extend_color); private: std::shared_ptr storage_; }; diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 57d8138f..15a29c52 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -1112,6 +1112,29 @@ namespace paint line_to({ r.x, r.y }, left_clr); } + void graphics::frame_rectangle(const ::nana::rectangle& r, const color& clr, unsigned gap) + { + palette(false, clr); + + if (r.width > gap * 2) + { + point left{ r.x + static_cast(gap), r.y }, right{ r.right() - static_cast(gap) - 1, r.y }; + line(left, right); + + left.y = right.y = r.bottom() - 1; + line(left, right); + } + + if (r.height > gap * 2) + { + point top{ r.x, r.y + static_cast(gap) }, bottom{ r.x, r.bottom() - static_cast(gap) - 1 }; + line(top, bottom); + + top.x = bottom.x = r.right() - 1; + line(top, bottom); + } + } + void graphics::gradual_rectangle(const ::nana::rectangle& rct, const ::nana::color& from, const ::nana::color& to, bool vertical) { #if defined(NANA_WINDOWS) diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index 574c8951..f2b438a1 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace nana{ namespace paint { @@ -47,11 +48,36 @@ namespace nana{ namespace paint struct pixel_buffer::pixel_buffer_storage : private nana::noncopyable { + pixel_buffer_storage& operator=(const pixel_buffer_storage&) = delete; + + bool _m_alloc() + { + if (pixel_size.empty()) + return false; + + std::unique_ptr pxbuf{ new pixel_color_t[pixel_size.width * pixel_size.height] }; +#if defined(NANA_X11) + auto & spec = nana::detail::platform_spec::instance(); + x11.image = ::XCreateImage(spec.open_display(), spec.screen_visual(), 32, ZPixmap, 0, reinterpret_cast(pxbuf.get()), pixel_size.width, pixel_size.height, 32, 0); + x11.attached = false; + if (!x11.image) + throw std::runtime_error("Nana.pixel_buffer: XCreateImage failed"); + + if (static_cast(bytes_per_line) != x11.image->bytes_per_line) + { + x11.image->data = nullptr; + XDestroyImage(x11.image); + throw std::runtime_error("Nana.pixel_buffer: Invalid pixel buffer context."); + } +#endif + raw_pixel_buffer = pxbuf.release(); + return true; + } public: const drawable_type drawable; //Attached handle const nana::rectangle valid_r; const nana::size pixel_size; - pixel_color_t * raw_pixel_buffer; + pixel_color_t * raw_pixel_buffer{ nullptr }; const std::size_t bytes_per_line; bool alpha_channel{false}; #if defined(NANA_X11) @@ -86,37 +112,31 @@ namespace nana{ namespace paint } }img_pro; + pixel_buffer_storage(const pixel_buffer_storage& other) : + drawable{ other.drawable }, + valid_r{ other.valid_r }, + pixel_size{ other.pixel_size }, + bytes_per_line{ other.bytes_per_line }, + alpha_channel{ other.alpha_channel }, + img_pro{ other.img_pro } + { + if (_m_alloc()) + std::memcpy(raw_pixel_buffer, other.raw_pixel_buffer, pixel_size.width * pixel_size.height); + } + pixel_buffer_storage(std::size_t width, std::size_t height) : drawable(nullptr), valid_r(0, 0, static_cast(width), static_cast(height)), pixel_size(static_cast(width), static_cast(height)), - raw_pixel_buffer(new pixel_color_t[width * height]), bytes_per_line(width * sizeof(pixel_color_t)) { -#if defined(NANA_X11) - nana::detail::platform_spec & spec = nana::detail::platform_spec::instance(); - x11.image = ::XCreateImage(spec.open_display(), spec.screen_visual(), 32, ZPixmap, 0, reinterpret_cast(raw_pixel_buffer), width, height, 32, 0); - x11.attached = false; - if(nullptr == x11.image) - { - delete [] raw_pixel_buffer; - throw std::runtime_error("Nana.pixel_buffer: XCreateImage failed"); - } - - if(static_cast(bytes_per_line) != x11.image->bytes_per_line) - { - x11.image->data = nullptr; - XDestroyImage(x11.image); - delete [] raw_pixel_buffer; - throw std::runtime_error("Nana.pixel_buffer: Invalid pixel buffer context."); - } -#endif + _m_alloc(); } pixel_buffer_storage(drawable_type drawable, const nana::rectangle& want_r) : drawable(drawable), valid_r(valid_rectangle(paint::detail::drawable_size(drawable), want_r)), - pixel_size(valid_r), + pixel_size(valid_r.dimension()), #if defined(NANA_WINDOWS) raw_pixel_buffer(reinterpret_cast(reinterpret_cast(drawable->pixbuf_ptr + valid_r.x) + drawable->bytes_per_line * valid_r.y)), bytes_per_line(drawable->bytes_per_line) @@ -362,7 +382,7 @@ namespace nana{ namespace paint XDestroyImage(img); } #endif - }; + };//end struct pixel_buffer_storage pixel_buffer::pixel_buffer(drawable_type drawable, const nana::rectangle& want_rectangle) { @@ -1105,5 +1125,153 @@ namespace nana{ namespace paint if (overlap(r, ::nana::rectangle{ this->size() }, good_r)) (*(sp->img_pro.blur))->process(*this, good_r, radius); } + + + //x' = x*cos(angle) - y*sin(angle) + //y' = y*cos(angle) - x*sin(angle) + class calc_rotate + { + enum class angles + { + none, half_pi, pi, triangle_pi + }; + public: + calc_rotate(double angle, const basic_point& origin): + specific_{ _m_spec(angle) }, + sin_a_{ std::sin(angle * degree_) }, + cos_a_{ std::cos(angle * degree_) }, + origin_{ origin } + { + } + + basic_point from(const point& p) + { + switch (specific_) + { + case angles::half_pi: + return{ p.y - origin_.y, origin_.x - p.x}; + case angles::pi: + return{ origin_.x - p.x, origin_.y - p.y}; + case angles::triangle_pi: + return{ origin_.y - p.y, p.x - origin_.x}; + default: + break; + } + + return{ + (p.x - origin_.x) * cos_a_ + (p.y - origin_.y) * sin_a_, + (p.y - origin_.y) * cos_a_ - (p.x - origin_.x) * sin_a_ + }; + } + + basic_point to(const point& p) + { + switch (specific_) + { + case angles::half_pi: + return{ origin_.y - p.y, p.x - origin_.x }; + case angles::pi: + return{ origin_.x - p.x, origin_.y - p.y }; + case angles::triangle_pi: + return{ p.y - origin_.y, origin_.x - p.x }; + default: + break; + } + + return{ + (p.x - origin_.x) * cos_a_ - (p.y - origin_.y) * sin_a_, + (p.y - origin_.y) * cos_a_ + (p.x - origin_.x) * sin_a_ + }; + } + private: + static angles _m_spec(double angle) + { + if (90.0 == angle) + return angles::half_pi; + else if (180.0 == angle) + return angles::pi; + else if (270.0 == angle) + return angles::triangle_pi; + + return angles::none; + } + private: + const angles specific_; + const double degree_{ std::acos(-1) / 180 }; + const double sin_a_; + const double cos_a_; + const basic_point origin_; + }; + + pixel_buffer pixel_buffer::rotate(double angle, const color& extend_color) + { + auto sp = storage_.get(); + if (!sp) + return{}; + + if (angle <= 0 || 360 <= angle) + { + return{*this}; + } + + const basic_point origin{ (sp->pixel_size.width - 1) / 2.0, (sp->pixel_size.height - 1) / 2.0 }; + calc_rotate point_rotate{ angle, origin }; + + nana::size size_rotated{ sp->pixel_size }; + + if (90 == angle || 270 == angle) + { + size_rotated.shift(); + } + else + { + point pw, ph; + if (angle < 180) + { + ph.x = static_cast(sp->pixel_size.width); + } + else if (angle > 180) + { + pw.x = static_cast(sp->pixel_size.width); + } + + size_rotated.width = static_cast(std::abs(point_rotate.from(pw).x) * 2) + 1; + size_rotated.height = static_cast(std::abs(point_rotate.from(ph).y) * 2) + 1; + } + + pixel_buffer rotated_pxbuf{ size_rotated.width, size_rotated.height }; + + const basic_point rotated_origin{ (size_rotated.width - 1) / 2.0, (size_rotated.height - 1) / 2.0 }; + + for (int y = 0; y < static_cast(size_rotated.height); ++y) + { + auto buf = rotated_pxbuf.raw_ptr(y); + + basic_point dest{ -rotated_origin.x, y - rotated_origin.y }; + dest = dest + origin; + + const int right_point = static_cast(dest.x) + static_cast(size_rotated.width); + + const int source_right = static_cast(sp->pixel_size.width); + const int source_bottom = static_cast(sp->pixel_size.height); + + for (point point_dest{ static_cast(dest.x), static_cast(dest.y) }; point_dest.x < right_point; ++point_dest.x) + { + auto point_source = point_rotate.to(point_dest) + origin; + + if (0 <= point_source.x && point_source.x <= static_cast(sp->pixel_size.width - 1) && 0 <= point_source.y && point_source.y <= static_cast(sp->pixel_size.height - 1)) + { + *buf = this->raw_ptr(static_cast(point_source.y))[static_cast(point_source.x)]; + } + else + *buf = extend_color.px_color(); + + ++buf; + } + } + + + return rotated_pxbuf; + } }//end namespace paint }//end namespace nana From 5e33bc643f352218fea86168eb885c7a69884135 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 04:31:33 +0800 Subject: [PATCH 161/309] impove slider --- include/nana/gui/widgets/slider.hpp | 86 +-- include/nana/gui/widgets/treebox.hpp | 4 +- source/gui/widgets/slider.cpp | 757 +++++++++++++++------------ 3 files changed, 481 insertions(+), 366 deletions(-) diff --git a/include/nana/gui/widgets/slider.hpp b/include/nana/gui/widgets/slider.hpp index 29adcf76..911accbd 100644 --- a/include/nana/gui/widgets/slider.hpp +++ b/include/nana/gui/widgets/slider.hpp @@ -44,65 +44,65 @@ namespace nana bilateral, forward, backward }; - class provider + + class renderer_interface { public: - virtual ~provider() = default; - virtual std::string adorn_trace(unsigned vmax, unsigned vadorn) const = 0; - }; + using graph_reference = ::nana::paint::graphics&; - class renderer - { - public: - typedef ::nana::paint::graphics & graph_reference; - - struct bar_t + struct data_bar { - bool horizontal; - nana::rectangle r; //the rectangle of bar. - unsigned border_size; //border_size of bar. + bool vert; ///< Indicates whether the slider is vertical. + ::nana::rectangle area; ///< Position and size of bar. + unsigned border_weight; ///< The border weight in pixels. }; - struct slider_t + struct data_slider { - bool horizontal; - int pos; - unsigned border; - unsigned scale; + bool vert; ///< Indicates whether the slider is vertical. + double pos; + unsigned border_weight; + unsigned weight; }; - struct adorn_t + struct data_adorn { - bool horizontal; - nana::point bound; + bool vert; ///< Indicates whether the slider is vertical. + ::nana::point bound; int fixedpos; unsigned block; - unsigned vcur_scale; //pixels of vcur scale. + unsigned vcur_scale; }; - virtual ~renderer() = default; + struct data_vernier + { + bool vert; ///< Indicates whether the slider is vertical. + int position; + int end_position; + unsigned knob_weight; + + std::string text; + }; + + virtual ~renderer_interface() = default; virtual void background(window, graph_reference, bool isglass) = 0; - virtual void adorn(window, graph_reference, const adorn_t&) = 0; - virtual void adorn_textbox(window, graph_reference, const ::std::string&, const nana::rectangle&) = 0; - virtual void bar(window, graph_reference, const bar_t&) = 0; - virtual void slider(window, graph_reference, const slider_t&) = 0; + virtual void adorn(window, graph_reference, const data_adorn&) = 0; + virtual void vernier(window, graph_reference, const data_vernier&) = 0; + virtual void bar(window, graph_reference, const data_bar&) = 0; + virtual void slider(window, graph_reference, mouse_action, const data_slider&) = 0; }; - class controller; - class trigger : public drawer_trigger { + class model; public: - typedef controller controller_t; - trigger(); ~trigger(); - controller_t* ctrl() const; + model* get_model() const; private: void attached(widget_reference, graph_reference) override; - void detached() override; void refresh(graph_reference) override; void mouse_down(graph_reference, const arg_mouse&) override; void mouse_up(graph_reference, const arg_mouse&) override; @@ -110,18 +110,19 @@ namespace nana void mouse_leave(graph_reference, const arg_mouse&) override; void resized(graph_reference, const arg_resized&) override; private: - controller_t * impl_; + model * model_ptr_; }; }//end namespace slider }//end namespace drawerbase + + /// A slider widget wich the user can drag for tracking \todo add scheme ? class slider : public widget_object { public: - typedef drawerbase::slider::renderer renderer; ///< The interface for user-defined renderer. - typedef drawerbase::slider::provider provider; ///< The interface for user-defined provider. - typedef drawerbase::slider::seekdir seekdir; ///< Defines the slider seek direction. + using renderer_interface = drawerbase::slider::renderer_interface; ///< The interface for customized renderer. + using seekdir = drawerbase::slider::seekdir; ///< Defines the slider seek direction. slider(); slider(window, bool visible); @@ -130,16 +131,17 @@ namespace nana void seek(seekdir); ///< Define the direction that user can seek by using mouse. void vertical(bool); bool vertical() const; - void vmax(unsigned); - unsigned vmax() const; + void maximum(unsigned); + unsigned maximum() const; void value(unsigned); unsigned value() const; unsigned move_step(bool forward); ///< Increase or decrease the value of slider. unsigned adorn() const; - pat::cloneable& ext_renderer(); ///< Refers to the current renderer that slider is using. - void ext_renderer(const pat::cloneable&); ///< Set the current renderer. - void ext_provider(const pat::cloneable&); + const pat::cloneable& renderer(); ///< Refers to the current renderer that slider is using. + void renderer(const pat::cloneable&); ///< Set the current renderer. + + void vernier(std::function provider); void transparent(bool); bool transparent() const; }; diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp index 69477824..ae5e03b1 100644 --- a/include/nana/gui/widgets/treebox.hpp +++ b/include/nana/gui/widgets/treebox.hpp @@ -72,9 +72,7 @@ namespace nana typedef compset_interface::item_attribute_t item_attribute_t; typedef compset_interface::comp_attribute_t comp_attribute_t; - virtual ~renderer_interface() - {} - + virtual ~renderer_interface() = default; virtual void set_color(const nana::color& bgcolor, const nana::color& fgcolor) = 0; virtual void bground(graph_reference, const compset_interface *) const = 0; diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index abb7dfe8..7cda9e61 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -13,91 +13,271 @@ namespace nana { class interior_renderer - : public renderer + : public renderer_interface { private: - virtual void background(window wd, graph_reference graph, bool isglass) + void background(window wd, graph_reference graph, bool isglass) override { if(!isglass) graph.rectangle(true, API::bgcolor(wd)); } - virtual void bar(window, graph_reference graph, const bar_t& bi) + void bar(window, graph_reference graph, const data_bar& data) override { - //draw border - ::nana::color lt(0x83, 0x90, 0x97), rb(0x9d,0xae,0xc2); - graph.frame_rectangle(bi.r, lt, lt, rb, rb); - } + auto area = data.area; - virtual void adorn(window, graph_reference graph, const adorn_t& ad) - { - auto len = static_cast(ad.bound.y - ad.bound.x); - const auto upperblock = ad.block - ad.block / 2; - - ::nana::color clr_from(0x84, 0xc5, 0xff), clr_trans(0x0f, 0x41, 0xcd), clr_to(0x6e, 0x96, 0xff); - if(ad.horizontal) + if (data.vert) { - graph.gradual_rectangle({ ad.bound.x, ad.fixedpos, len, upperblock }, clr_from, clr_trans, true); - graph.gradual_rectangle({ ad.bound.x, ad.fixedpos + static_cast(upperblock), len, ad.block - upperblock }, clr_trans, clr_to, true); + area.x = area.width / 2 - 2; + area.width = 4; } else { - graph.gradual_rectangle({ ad.fixedpos, ad.bound.x, upperblock, len }, clr_from, clr_trans, false); - graph.gradual_rectangle({ ad.fixedpos + static_cast(upperblock), ad.bound.x, ad.block - upperblock, len }, clr_trans, clr_to, false); + area.y = area.height / 2 - 2; + area.height = 4; } + + graph.rectangle(area, false, static_cast(0x878787)); } - virtual void adorn_textbox(window, graph_reference graph, const std::string& str, const nana::rectangle & r) + void adorn(window, graph_reference graph, const data_adorn& data) override { - graph.rectangle(r, false, colors::white); - graph.string({ r.x + 2, r.y + 1 }, str, colors::white); + rectangle area{ + data.bound.x, data.fixedpos + static_cast(data.block / 2) - 1, + static_cast(data.bound.y - data.bound.x) , 2 + }; + + if (data.vert) + area.shift(); + + graph.rectangle(area, true, static_cast(0x3DA3CE)); + } - virtual void slider(window, graph_reference graph, const slider_t& s) + void vernier(window, graph_reference graph, const data_vernier& data) override { - nana::rectangle r{ graph.size() }; - if(s.horizontal) + if (data.vert) + _m_draw_vernier_vert(graph, data); + else + _m_draw_vernier_horz(graph, data); + } + + void slider(window, graph_reference graph, mouse_action mouse_act, const data_slider& data) override + { + nana::rectangle area{ graph.size() }; + + if (data.vert) { - r.x = s.pos; - r.width = s.scale; + area.y = static_cast(data.pos); + area.height = data.weight; } else { - r.y = s.pos; - r.height = s.scale; + area.x = static_cast(data.pos); + area.width = data.weight; } - graph.round_rectangle(r, 3, 3, colors::black, true, static_cast(0xf0f0f0)); + + color rgb{ static_cast(0x606060) }; + if (mouse_action::normal != mouse_act) + rgb = static_cast(0x2d93be); + + graph.frame_rectangle(area, rgb + static_cast(0x0d0d0d), 1); + graph.rectangle(area.pare_off(1), true, rgb); + + area.height /= 2; + graph.rectangle(area, true, rgb + static_cast(0x101010)); + } + private: + void _m_draw_vernier_horz(graph_reference graph, const data_vernier& data) + { + const unsigned arrow_weight = 5; + + unsigned arrow_pxbuf[] = { + 0x7F, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x7F, 0x00, 0x00, 0x00, + 0x7F, 0x7F, 0x7F, 0x00, 0x00, + 0x7F, 0x7F, 0x7F, 0x7F, 0x00, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x00, + 0x7F, 0x7F, 0x7F, 0x00, 0x00, + 0x7F, 0x7F, 0x00, 0x00, 0x00, + 0x7F, 0x00, 0x00, 0x00, 0x00 + }; + + const size arrow_size{ arrow_weight, 9 }; + + + const unsigned text_margin = 8; + const auto label_size = graph.text_extent_size(data.text) + size{ text_margin * 2, 0 }; + + paint::graphics graph_vern{ label_size }; + graph_vern.rectangle(true, colors::red); + + int arrow_pos; + + point label_pos{ data.position, static_cast(graph.height() - label_size.height) / 2 }; + + if (static_cast(label_size.width + arrow_weight) > data.position) + { + label_pos.x += arrow_weight; + arrow_pos = data.position; + } + else + { + label_pos.x -= label_size.width + arrow_weight; + arrow_pos = data.position - arrow_weight; + } + + graph_vern.blend(rectangle{ label_size }, graph, label_pos, 0.5); + + + for (auto & color : arrow_pxbuf) + { + if (color == 0x7F) + color = 0x7FFF0000; + } + + if (label_pos.x > data.position) + { + for (::nana::size::value_type l = 0; l < arrow_size.height; ++l) + { + auto ptr = arrow_pxbuf + l * arrow_size.width; + + for (::nana::size::value_type x = 0; x < arrow_size.width / 2; ++x) + std::swap(ptr[x], ptr[(arrow_size.width - 1) - x]); + } + } + + paint::pixel_buffer pxbuf{ arrow_size.width, arrow_size.height }; + pxbuf.alpha_channel(true); + pxbuf.put(reinterpret_cast(arrow_pxbuf), arrow_size.width, arrow_size.height, 32, arrow_size.width * 4, false); + + pxbuf.paste(rectangle{ arrow_size }, graph.handle(), { arrow_pos, label_pos.y + static_cast(label_size.height - arrow_size.height) / 2 }); + + label_pos.x += text_margin; + graph.palette(true, colors::white); + graph.string(label_pos, data.text); + } + + void _m_draw_vernier_vert(graph_reference graph, const data_vernier& data) + { + const unsigned arrow_weight = 5; + + unsigned arrow_pxbuf[] = { + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, + 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, + }; + + const size arrow_size{ 9, arrow_weight}; + + + const unsigned text_margin = 8; + const size label_size = (graph.text_extent_size(data.text) + size{ text_margin * 2, 0 }).shift(); + + paint::graphics graph_vern{ label_size }; + + paint::graphics graph_horz{ size(label_size).shift() }; + graph_horz.rectangle(true, colors::red); + graph_horz.string({static_cast(text_margin), static_cast(graph_horz.height() - label_size.width) / 2}, data.text, colors::white); + + paint::pixel_buffer{ graph_horz.handle(), 0, graph_horz.height() }.rotate(90, colors::white).paste(graph_vern.handle(), {}); + + int arrow_pos; + + point label_pos{ static_cast(graph.width() - label_size.width) / 2, data.position }; + + if (static_cast(label_size.height + arrow_weight) > (data.end_position - data.position)) + { + label_pos.y -= arrow_weight + label_size.height; + arrow_pos = data.position - arrow_weight; + + const unsigned line_bytes = arrow_size.width * sizeof(unsigned); + for (size::value_type l = 0; l < arrow_size.height / 2; ++l) + { + auto swap_x = arrow_pxbuf + l* arrow_size.width; + auto swap_y = arrow_pxbuf + (arrow_size.height - 1 - l) * arrow_size.width; + + unsigned tmp[9]; + std::memcpy(tmp, swap_x, line_bytes); + std::memcpy(swap_x, swap_y, line_bytes); + std::memcpy(swap_y, tmp, line_bytes); + } + } + else + { + label_pos.y += arrow_weight; + arrow_pos = data.position; + } + + graph_vern.blend(rectangle{ label_size }, graph, label_pos, 0.5); + + + for (auto & color : arrow_pxbuf) + { + if (color == 0x7F) + color = 0x7FFF0000; + } + + /* + */ + + paint::pixel_buffer pxbuf{ arrow_size.width, arrow_size.height }; + pxbuf.alpha_channel(true); + pxbuf.put(reinterpret_cast(arrow_pxbuf), arrow_size.width, arrow_size.height, 32, arrow_size.width * 4, false); + + pxbuf.paste(rectangle{ arrow_size }, graph.handle(), { label_pos.x + static_cast(label_size.width - arrow_size.width) / 2, arrow_pos }); + + label_pos.y += text_margin; + /* + graph.palette(true, colors::white); + graph.string(label_pos, data.text); + */ } }; - class controller + class trigger::model { + struct attrib_rep + { + seekdir seek_dir; + bool is_draw_adorn; + + unsigned vmax; + double vcur; + double adorn_pos; + + renderer_interface::data_slider slider; + }; public: - enum class style{horizontal, vertical}; enum class parts{none, bar, slider}; - typedef drawer_trigger::graph_reference graph_reference; + using graph_reference = drawer_trigger::graph_reference; - controller() + model() { other_.wd = nullptr; other_.widget = nullptr; - other_.graph = nullptr; - proto_.renderer = pat::cloneable(interior_renderer()); + proto_.renderer = pat::cloneable{interior_renderer{}}; - attr_.skdir = seekdir::bilateral; - attr_.dir = style::horizontal; + attr_.seek_dir = seekdir::bilateral; + + attr_.is_draw_adorn = false; attr_.vcur = 0; attr_.vmax = 10; - attr_.slider_scale = 8; - attr_.border = 1; - attr_.is_draw_adorn = false; + + attr_.slider.vert = false; + attr_.slider.border_weight = 1; + attr_.slider.pos = 0; + attr_.slider.weight = 8; } - void seek(seekdir sd) + void seek_direction(seekdir sd) { - attr_.skdir = sd; + attr_.seek_dir = sd; } window handle() const @@ -105,86 +285,68 @@ namespace nana return other_.wd; } - void attached(nana::slider& wd, graph_reference graph) + void attached(nana::slider& wdg, graph_reference graph) { - other_.wd = wd.handle(); - other_.widget = &wd; + other_.wd = wdg.handle(); + other_.widget = &wdg; - other_.graph = &graph; _m_mk_slider_pos_by_value(); } - void detached() - { - other_.graph = nullptr; - } - - pat::cloneable& ext_renderer() + pat::cloneable& renderer() { return proto_.renderer; } - void ext_renderer(const pat::cloneable& rd) + void vernier(std::function vernier_string) { - proto_.renderer = rd; + proto_.vernier = vernier_string; } - void ext_provider(const pat::cloneable& pd) + void draw(graph_reference graph) { - proto_.provider = pd; - } - - void draw() - { - if(other_.graph && !other_.graph->size().empty()) + if(!graph.size().empty()) { - bool is_transparent = (bground_mode::basic == API::effects_bground_mode(other_.wd)); - proto_.renderer->background(other_.wd, *other_.graph, is_transparent); - _m_draw_objects(); + proto_.renderer->background(other_.wd, graph, (bground_mode::basic == API::effects_bground_mode(other_.wd))); + _m_draw_elements(graph); } } - void vertical(bool v) + const attrib_rep & attribute() const { - auto dir = (v ? style::vertical : style::horizontal); + return attr_; + } - if(dir != attr_.dir) + bool vertical(bool vert) + { + if (vert != attr_.slider.vert) { - attr_.dir = dir; + attr_.slider.vert = vert; _m_mk_slider_pos_by_value(); - this->draw(); + return true; } + return false; } - bool vertical() const - { - return (style::vertical == attr_.dir); - } - - void vmax(unsigned m) + void maximum(unsigned m) { if(m == 0) m = 1; - if(attr_.vmax != m) + if (attr_.vmax == m) + return; + + attr_.vmax = m; + if(attr_.vcur > m) { - attr_.vmax = m; - if(attr_.vcur > m) - { - attr_.vcur = m; - _m_emit_value_changed(); - } - - _m_mk_slider_pos_by_value(); - draw(); + attr_.vcur = m; + _m_emit_value_changed(); } + + _m_mk_slider_pos_by_value(); + API::refresh_window(other_.wd); } - unsigned vmax() const - { - return attr_.vmax; - } - - void vcur(unsigned v) + bool vcur(unsigned v) { if(attr_.vmax < v) v = attr_.vmax; @@ -193,39 +355,36 @@ namespace nana { attr_.vcur = v; this->_m_mk_slider_pos_by_value(); - draw(); + return true; } - } - - unsigned vcur() const - { - return static_cast(attr_.vcur); + return false; } void resize() { _m_mk_slider_pos_by_value(); - attr_.adorn_pos = attr_.pos; + attr_.adorn_pos = attr_.slider.pos; } parts seek_where(::nana::point pos) const { nana::rectangle r = _m_bar_area(); - if(style::vertical == attr_.dir) + + if (attr_.slider.vert) { std::swap(pos.x, pos.y); std::swap(r.width, r.height); } int sdpos = _m_slider_pos(); - if (sdpos <= pos.x && pos.x < sdpos + static_cast(attr_.slider_scale)) + if (sdpos <= pos.x && pos.x < sdpos + static_cast(attr_.slider.weight)) return parts::slider; - sdpos = static_cast(attr_.slider_scale) / 2; + sdpos = static_cast(attr_.slider.weight) / 2; if (sdpos <= pos.x && pos.x < sdpos + static_cast(r.width)) { - if(pos.y < r.y + static_cast(r.height)) + if(pos.y < r.bottom()) return parts::bar; } return parts::none; @@ -235,50 +394,50 @@ namespace nana //move the slider to a position where a mouse click on WhereBar. bool set_slider_pos(::nana::point pos) { - if(style::vertical == attr_.dir) + if(attr_.slider.vert) std::swap(pos.x, pos.y); pos.x -= _m_slider_refpos(); if(pos.x < 0) return false; - if(pos.x > static_cast(_m_scale())) - pos.x = static_cast(_m_scale()); + if(pos.x > static_cast(_m_range())) + pos.x = static_cast(_m_range()); - double attr_pos = attr_.pos; + auto attr_pos = attr_.slider.pos; double dx = _m_evaluate_by_seekdir(pos.x); - attr_.pos = dx; + attr_.slider.pos = dx; attr_.adorn_pos = dx; _m_mk_slider_value_by_pos(); - return (attr_.pos != attr_pos); + return (attr_.slider.pos != attr_pos); } void set_slider_refpos(::nana::point pos) { - if(style::vertical == attr_.dir) + if (attr_.slider.vert) std::swap(pos.x, pos.y); - slider_state_.trace = slider_state_.TraceCapture; - slider_state_.snap_pos = static_cast(attr_.pos); + slider_state_.mouse_state = ::nana::mouse_action::pressed; + slider_state_.snap_pos = static_cast(attr_.slider.pos); slider_state_.refpos = pos; API::set_capture(other_.wd, true); } bool release_slider() { - if(slider_state_.trace == slider_state_.TraceCapture) + if(::nana::mouse_action::pressed == slider_state_.mouse_state) { API::release_capture(other_.wd); - if(other_.wd != API::find_window(API::cursor_position())) + if (other_.wd != API::find_window(API::cursor_position())) { - slider_state_.trace = slider_state_.TraceNone; + slider_state_.mouse_state = ::nana::mouse_action::normal; attr_.is_draw_adorn = false; } else - slider_state_.trace = slider_state_.TraceOver; + slider_state_.mouse_state = ::nana::mouse_action::hovered; _m_mk_slider_value_by_pos(); _m_mk_slider_pos_by_value(); @@ -289,19 +448,18 @@ namespace nana bool if_trace_slider() const { - return (slider_state_.trace == slider_state_.TraceCapture); + return (::nana::mouse_action::pressed == slider_state_.mouse_state); } bool move_slider(const ::nana::point& pos) { - int mpos = (style::horizontal == attr_.dir ? pos.x : pos.y); - int adorn_pos = slider_state_.snap_pos + (mpos - slider_state_.refpos.x); + int adorn_pos = slider_state_.snap_pos + (attr_.slider.vert ? pos.y : pos.x) - slider_state_.refpos.x; if (adorn_pos > 0) { - int scale = static_cast(_m_scale()); - if (adorn_pos > scale) - adorn_pos = scale; + int range = static_cast(_m_range()); + if (adorn_pos > range) + adorn_pos = range; } else adorn_pos = 0; @@ -309,9 +467,9 @@ namespace nana double dstpos = _m_evaluate_by_seekdir(adorn_pos); attr_.is_draw_adorn = true; - if(dstpos != attr_.pos) + if(dstpos != attr_.slider.pos) { - attr_.pos = dstpos; + attr_.slider.pos = dstpos; attr_.adorn_pos = dstpos; return true; } @@ -320,11 +478,11 @@ namespace nana bool move_adorn(const ::nana::point& pos) { - double xpos = (style::horizontal == attr_.dir ? pos.x : pos.y); + double xpos = (attr_.slider.vert ? pos.y : pos.x) - _m_slider_refpos(); - xpos -= _m_slider_refpos(); - if(xpos > static_cast(_m_scale())) - xpos = static_cast(_m_scale()); + auto range = static_cast(_m_range()); + if (xpos > range) + xpos = range; int adorn_pos = static_cast(attr_.adorn_pos); xpos = _m_evaluate_by_seekdir(xpos); @@ -332,8 +490,8 @@ namespace nana attr_.adorn_pos = xpos; attr_.is_draw_adorn = true; - if(slider_state_.trace == slider_state_.TraceNone) - slider_state_.trace = slider_state_.TraceOver; + if (::nana::mouse_action::normal == slider_state_.mouse_state) + slider_state_.mouse_state = ::nana::mouse_action::hovered; return (adorn_pos != static_cast(xpos)); } @@ -354,7 +512,8 @@ namespace nana if (cmpvalue != value) { _m_mk_slider_pos_by_value(); - draw(); + API::refresh_window(other_.wd); + _m_emit_value_changed(); } @@ -370,14 +529,14 @@ namespace nana { //Test if the slider is captured, the operation should be ignored. Because the mouse_leave always be generated even through //the slider is captured. - if(slider_state_.trace == slider_state_.TraceCapture && (nana::API::capture_window() == this->other_.wd)) + if((::nana::mouse_action::pressed == slider_state_.mouse_state) && (API::capture_window() == this->other_.wd)) return false; - slider_state_.trace = slider_state_.TraceNone; + slider_state_.mouse_state = ::nana::mouse_action::normal; attr_.is_draw_adorn = false; - if(attr_.adorn_pos != attr_.pos) + if(attr_.adorn_pos != attr_.slider.pos) { - attr_.adorn_pos = attr_.pos; + attr_.adorn_pos = attr_.slider.pos; return true; } return false; @@ -389,69 +548,62 @@ namespace nana other_.widget->events().value_changed.emit(::nana::arg_slider{ *other_.widget }, other_.widget->handle()); } - nana::rectangle _m_bar_area() const + ::nana::rectangle _m_bar_area() const { - auto sz = other_.graph->size(); - nana::rectangle r{ sz }; - if(style::horizontal == attr_.dir) + auto sz = other_.widget->size(); + + nana::rectangle area{ sz }; + if (attr_.slider.vert) { - r.x = attr_.slider_scale / 2 - attr_.border; - r.width = (static_cast(sz.width) > (r.x << 1) ? sz.width - (r.x << 1) : 0); + area.y = attr_.slider.weight / 2 - attr_.slider.border_weight; + area.height = (static_cast(sz.height) > (area.y << 1) ? sz.height - (area.y << 1) : 0); } else { - r.y = attr_.slider_scale / 2 - attr_.border; - r.height = (static_cast(sz.height) > (r.y << 1) ? sz.height - (r.y << 1) : 0); + area.x = attr_.slider.weight / 2 - attr_.slider.border_weight; + area.width = (static_cast(sz.width) > (area.x << 1) ? sz.width - (area.x << 1) : 0); } - return r; + return area; } - unsigned _m_scale() const + unsigned _m_range() const { nana::rectangle r = _m_bar_area(); - return ((style::horizontal == attr_.dir ? r.width : r.height) - attr_.border * 2); + return (attr_.slider.vert ? r.height : r.width) - attr_.slider.border_weight * 2; } double _m_evaluate_by_seekdir(double pos) const { - switch(attr_.skdir) + if (seekdir::bilateral != attr_.seek_dir) { - case seekdir::backward: - if(pos < attr_.pos) - pos = attr_.pos; - break; - case seekdir::forward: - if(pos > attr_.pos) - pos = attr_.pos; - break; - default: - break; + if ((seekdir::backward == attr_.seek_dir) == (pos < attr_.slider.pos)) + pos = attr_.slider.pos; } return (pos < 0 ? 0 : pos); } int _m_slider_refpos() const { - return static_cast(attr_.slider_scale / 2); + return static_cast(attr_.slider.weight / 2); } int _m_slider_pos() const { - return static_cast(_m_scale() * attr_.vcur / attr_.vmax); + return static_cast(_m_range() * attr_.vcur / attr_.vmax); } void _m_mk_slider_value_by_pos() { - if(_m_scale()) + auto range = _m_range(); + if (range) { auto cmpvalue = static_cast(attr_.vcur); - if (style::vertical == attr_.dir) - { - double scl = _m_scale(); - attr_.vcur = (scl - attr_.pos) * attr_.vmax / scl; - } + if (attr_.slider.vert) + attr_.vcur = (range - attr_.slider.pos) * attr_.vmax; else - attr_.vcur = (attr_.pos * attr_.vmax / _m_scale()); + attr_.vcur = (attr_.slider.pos * attr_.vmax); + + attr_.vcur /= range; if (cmpvalue != static_cast(attr_.vcur)) _m_emit_value_changed(); } @@ -459,224 +611,192 @@ namespace nana void _m_mk_slider_pos_by_value() { - attr_.pos = double(_m_scale()) * attr_.vcur / attr_.vmax; + const auto range = _m_range(); + attr_.slider.pos = double(range) * attr_.vcur / attr_.vmax; - if (style::vertical == attr_.dir) - attr_.pos = _m_scale() - attr_.pos; + if (attr_.slider.vert) + attr_.slider.pos = range - attr_.slider.pos; - if(slider_state_.trace == slider_state_.TraceNone) - attr_.adorn_pos = attr_.pos; + if(::nana::mouse_action::normal == slider_state_.mouse_state) + attr_.adorn_pos = attr_.slider.pos; } unsigned _m_value_by_pos(double pos) const { - if(_m_scale()) - return static_cast(pos * attr_.vmax / _m_scale()); - return 0; + const auto range = _m_range(); + + if (0 == range) + return 0; + + return static_cast((attr_.slider.vert ? range - pos : pos) * attr_.vmax / range); } - void _m_draw_objects() + void _m_draw_elements(graph_reference graph) { - renderer::bar_t bar; + renderer_interface::data_bar bar; - bar.horizontal = (style::horizontal == attr_.dir); - bar.border_size = attr_.border; - bar.r = _m_bar_area(); + bar.vert = attr_.slider.vert; + bar.border_weight = attr_.slider.border_weight; + bar.area = _m_bar_area(); - if (bar.r.empty()) + if (bar.area.empty()) return; - proto_.renderer->bar(other_.wd, *other_.graph, bar); + proto_.renderer->bar(other_.wd, graph, bar); //adorn - renderer::adorn_t adorn; - adorn.horizontal = bar.horizontal; - if (adorn.horizontal) + renderer_interface::data_adorn adorn; + adorn.vert = bar.vert; + if (adorn.vert) { - adorn.bound.x = bar.r.x + attr_.border; - adorn.bound.y = adorn.bound.x + static_cast(attr_.adorn_pos); + adorn.bound.x = static_cast(attr_.adorn_pos + attr_.slider.border_weight + bar.area.y); + adorn.bound.y = static_cast(graph.height()) - static_cast(attr_.slider.border_weight + bar.area.y); + //adorn.bound.x = } else { - adorn.bound.y = static_cast(other_.graph->height()) - static_cast(attr_.border + bar.r.y); - adorn.bound.x = static_cast(attr_.adorn_pos + attr_.border + bar.r.y); + adorn.bound.x = bar.area.x + attr_.slider.border_weight; + adorn.bound.y = adorn.bound.x + static_cast(attr_.adorn_pos); } - adorn.vcur_scale = static_cast(attr_.pos); - adorn.block = (bar.horizontal ? bar.r.height : bar.r.width) - attr_.border * 2; - adorn.fixedpos = static_cast((bar.horizontal ? bar.r.y : bar.r.x) + attr_.border); - proto_.renderer->adorn(other_.wd, *other_.graph, adorn); + adorn.vcur_scale = static_cast(attr_.slider.pos); + adorn.block = (bar.vert ? bar.area.width : bar.area.height) - attr_.slider.border_weight * 2; + adorn.fixedpos = static_cast((bar.vert ? bar.area.x : bar.area.y) + attr_.slider.border_weight); - _m_draw_slider(); + proto_.renderer->adorn(other_.wd, graph, adorn); + + //Draw slider + proto_.renderer->slider(other_.wd, graph, slider_state_.mouse_state, attr_.slider); //adorn textbox - if(proto_.provider && attr_.is_draw_adorn) + if (proto_.vernier && attr_.is_draw_adorn) { - unsigned vadorn = _m_value_by_pos(attr_.adorn_pos); - auto str = proto_.provider->adorn_trace(attr_.vmax, vadorn); - if(str.size()) - { - nana::size ts = other_.graph->text_extent_size(str); - ts.width += 6; - ts.height += 2; + renderer_interface::data_vernier vern; + vern.vert = attr_.slider.vert; + vern.knob_weight = attr_.slider.weight; - int x, y; - const int room = static_cast(attr_.adorn_pos); - if(bar.horizontal) - { - y = adorn.fixedpos + static_cast(adorn.block - ts.height) / 2; - x = (room > static_cast(ts.width + 2) ? room - static_cast(ts.width + 2) : room + 2) + _m_slider_refpos(); - } - else - { - x = (other_.graph->width() - ts.width) / 2; - y = (room > static_cast(ts.height + 2) ? room - static_cast(ts.height + 2) : room + 2) + _m_slider_refpos(); - } - proto_.renderer->adorn_textbox(other_.wd, *other_.graph, str, {x, y, ts.width, ts.height}); + auto vadorn = _m_value_by_pos(attr_.adorn_pos); + proto_.vernier(attr_.vmax, vadorn).swap(vern.text); + if(vern.text.size()) + { + vern.position = adorn.bound.x; + if (!adorn.vert) + vern.position += static_cast(attr_.adorn_pos); + + vern.end_position = adorn.bound.y; + proto_.renderer->vernier(other_.wd, graph, vern); } } } - - void _m_draw_slider() - { - renderer::slider_t s; - s.pos = static_cast(attr_.pos); - s.horizontal = (style::horizontal == attr_.dir); - s.scale = attr_.slider_scale; - s.border = attr_.border; - proto_.renderer->slider(other_.wd, *other_.graph, s); - } private: + attrib_rep attr_; + struct other_tag { window wd; nana::slider * widget; - paint::graphics * graph; }other_; struct prototype_tag { - pat::cloneable renderer; - pat::cloneable provider; + pat::cloneable renderer; + std::function vernier; }proto_; - struct attr_tag - { - seekdir skdir; - style dir; - unsigned border; - unsigned vmax; - double vcur; - double pos; - bool is_draw_adorn; - double adorn_pos; - unsigned slider_scale; - }attr_; - struct slider_state_tag { - enum t{TraceNone, TraceOver, TraceCapture}; - - t trace; //true if the mouse press on slider. int snap_pos; - nana::point refpos; //a point for slider when the mouse was clicking on slider. - - slider_state_tag(): trace(TraceNone){} + ::nana::point refpos; //a point for slider when the mouse was clicking on slider. + ::nana::mouse_action mouse_state{ ::nana::mouse_action::normal }; }slider_state_; }; //class trigger trigger::trigger() - : impl_(new controller_t) + : model_ptr_(new model) {} trigger::~trigger() { - delete impl_; + delete model_ptr_; } - trigger::controller_t* trigger::ctrl() const + auto trigger::get_model() const -> model* { - return impl_; + return model_ptr_; } void trigger::attached(widget_reference widget, graph_reference graph) { - impl_->attached(static_cast(widget), graph); + model_ptr_->attached(static_cast< ::nana::slider&>(widget), graph); } - void trigger::detached() + void trigger::refresh(graph_reference graph) { - impl_->detached(); + model_ptr_->draw(graph); } - void trigger::refresh(graph_reference) + void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) { - impl_->draw(); - } - - void trigger::mouse_down(graph_reference, const arg_mouse& arg) - { - using parts = controller_t::parts; - auto what = impl_->seek_where(arg.pos); + using parts = model::parts; + auto what = model_ptr_->seek_where(arg.pos); if(parts::bar == what || parts::slider == what) { - bool mkdir = impl_->set_slider_pos(arg.pos); - impl_->set_slider_refpos(arg.pos); - if(mkdir) + bool updated = model_ptr_->set_slider_pos(arg.pos); + model_ptr_->set_slider_refpos(arg.pos); + if (updated) { - impl_->draw(); + model_ptr_->draw(graph); API::dev::lazy_refresh(); } } } - void trigger::mouse_up(graph_reference, const arg_mouse&) + void trigger::mouse_up(graph_reference graph, const arg_mouse&) { - bool mkdraw = impl_->release_slider(); - if(mkdraw) + if (model_ptr_->release_slider()) { - impl_->draw(); + model_ptr_->draw(graph); API::dev::lazy_refresh(); } } - void trigger::mouse_move(graph_reference, const arg_mouse& arg) + void trigger::mouse_move(graph_reference graph, const arg_mouse& arg) { - bool mkdraw = false; - if(impl_->if_trace_slider()) + bool updated = false; + if (model_ptr_->if_trace_slider()) { - mkdraw = impl_->move_slider(arg.pos); + updated = model_ptr_->move_slider(arg.pos); + updated |= model_ptr_->set_slider_pos(arg.pos); } else { - auto what = impl_->seek_where(arg.pos); - if(controller_t::parts::none != what) - mkdraw = impl_->move_adorn(arg.pos); + if (model::parts::none != model_ptr_->seek_where(arg.pos)) + updated = model_ptr_->move_adorn(arg.pos); else - mkdraw = impl_->reset_adorn(); + updated = model_ptr_->reset_adorn(); } - if(mkdraw) + if (updated) { - impl_->draw(); + model_ptr_->draw(graph); API::dev::lazy_refresh(); } } - void trigger::mouse_leave(graph_reference, const arg_mouse&) + void trigger::mouse_leave(graph_reference graph, const arg_mouse&) { - if(impl_->reset_adorn()) + if (model_ptr_->reset_adorn()) { - impl_->draw(); + model_ptr_->draw(graph); API::dev::lazy_refresh(); } } - void trigger::resized(graph_reference, const arg_resized&) + void trigger::resized(graph_reference graph, const arg_resized&) { - impl_->resize(); - impl_->draw(); + model_ptr_->resize(); + model_ptr_->draw(graph); API::dev::lazy_refresh(); } //end class trigger @@ -696,86 +816,81 @@ namespace nana create(wd, r, visible); } - void slider::seek(slider::seekdir sd) + void slider::seek(seekdir sd) { - get_drawer_trigger().ctrl()->seek(sd); + get_drawer_trigger().get_model()->seek_direction(sd); } void slider::vertical(bool v) { - get_drawer_trigger().ctrl()->vertical(v); - API::update_window(this->handle()); + if(get_drawer_trigger().get_model()->vertical(v)) + API::refresh_window(this->handle()); } bool slider::vertical() const { - return get_drawer_trigger().ctrl()->vertical(); + return get_drawer_trigger().get_model()->attribute().slider.vert; } - void slider::vmax(unsigned m) + void slider::maximum(unsigned m) { - if(this->handle()) - { - get_drawer_trigger().ctrl()->vmax(m); - API::update_window(handle()); - } + get_drawer_trigger().get_model()->maximum(m); } - unsigned slider::vmax() const + unsigned slider::maximum() const { - if(handle()) - return get_drawer_trigger().ctrl()->vmax(); - return 0; + if (empty()) + return 0; + + return get_drawer_trigger().get_model()->attribute().vmax; } void slider::value(unsigned v) { if(handle()) { - get_drawer_trigger().ctrl()->vcur(v); - API::update_window(handle()); + if(get_drawer_trigger().get_model()->vcur(v)) + API::refresh_window(handle()); } } unsigned slider::value() const { - if(handle()) - return get_drawer_trigger().ctrl()->vcur(); - return 0; + if (empty()) + return 0; + + return static_cast(get_drawer_trigger().get_model()->attribute().vcur); } unsigned slider::move_step(bool forward) { - if(handle()) - { - drawerbase::slider::controller* ctrl = this->get_drawer_trigger().ctrl(); - unsigned val = ctrl->move_step(forward); - if(val != ctrl->vcur()) - API::update_window(handle()); - return val; - } - return 0; + if (empty()) + return 0; + + return this->get_drawer_trigger().get_model()->move_step(forward); } unsigned slider::adorn() const { - if(empty()) return 0; - return get_drawer_trigger().ctrl()->adorn(); + if(empty()) + return 0; + + return get_drawer_trigger().get_model()->adorn(); } - pat::cloneable& slider::ext_renderer() + const pat::cloneable& slider::renderer() { - return get_drawer_trigger().ctrl()->ext_renderer(); + return get_drawer_trigger().get_model()->renderer(); } - void slider::ext_renderer(const pat::cloneable& di) + void slider::renderer(const pat::cloneable& rd) { - get_drawer_trigger().ctrl()->ext_renderer(di); + get_drawer_trigger().get_model()->renderer() = rd; } - void slider::ext_provider(const pat::cloneable& pi) + void slider::vernier(std::function vernier_string) { - get_drawer_trigger().ctrl()->ext_provider(pi); + get_drawer_trigger().get_model()->vernier(vernier_string); } void slider::transparent(bool enabled) From a0a1f010974bad47d39d1438ff48b58dd499fab8 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 04:40:19 +0800 Subject: [PATCH 162/309] small fixes --- source/basic_types.cpp | 8 ++++---- source/gui/place_parts.hpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/basic_types.cpp b/source/basic_types.cpp index 5820c3cf..b5f7716b 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -621,24 +621,24 @@ namespace nana return *this; } - point rectangle::position() const + point rectangle::position() const noexcept { return{ x, y }; } - rectangle& rectangle::position(const point& p) + rectangle& rectangle::position(const point& p) noexcept { x = p.x; y = p.y; return *this; } - size rectangle::dimension() const + size rectangle::dimension() const noexcept { return{width, height}; } - rectangle& rectangle::dimension(const size& sz) + rectangle& rectangle::dimension(const size& sz) noexcept { width = sz.width; height = sz.height; diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 5f777e3b..d9d7c2d7 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -387,7 +387,7 @@ namespace nana } panels_.emplace_back(); - auto wdg = wdg.get(); + auto wdg_ptr = wdg.get(); panels_.back().widget_ptr.swap(wdg); for (auto & pn : panels_) @@ -395,7 +395,7 @@ namespace nana if (pn.widget_ptr) pn.widget_ptr->move(r); } - return wdg; + return wdg_ptr; } return nullptr; } @@ -698,4 +698,4 @@ namespace nana }//end namespace place_parts }//end namespace nana -#endif //NANA_GUI_PLACE_PARTS_HPP +#endif //NANA_GUI_PLACE_PARTS_HPP \ No newline at end of file From a1b552439d158be234645d07a2547b14f84eb27c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 04:46:07 +0800 Subject: [PATCH 163/309] small fixes --- source/gui/detail/bedrock_posix.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index af6a58c3..1ac30c25 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -515,7 +515,7 @@ namespace detail if(msgwnd) { if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); hovered_wd = msgwnd; @@ -669,7 +669,7 @@ namespace detail { if((arg.button == ::nana::mouse::left_button) && hit) { - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); click_arg.window_handle = reinterpret_cast(msgwnd); draw_invoker(&drawer::click, msgwnd, click_arg, &context); @@ -680,7 +680,7 @@ namespace detail if(wd_manager.available(msgwnd) && msgwnd->flags.enabled) { if(hit) - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); auto retain = msgwnd->together.events_ptr; auto evt_ptr = retain.get(); @@ -766,7 +766,7 @@ namespace detail { evt_code = event_code::mouse_enter; if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); } arg_mouse arg; assign_arg(arg, msgwnd, message, xevent); @@ -781,7 +781,7 @@ namespace detail assign_arg(arg, msgwnd, message, xevent); if (mouse_action::pressed != msgwnd->flags.action) - msgwnd->set_action(mouse_action::over); + msgwnd->set_action(mouse_action::hovered); if (hovered_wd != msgwnd) { From c775ef9f2425bdbcc833692e16d869fbc16ec16b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 05:22:16 +0800 Subject: [PATCH 164/309] small fix --- source/gui/widgets/slider.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index 7cda9e61..28f6dcd5 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -1,5 +1,6 @@ #include +#include //memcpy namespace nana { From 50b982eca773efd3fe514735a2bf5d622115abae Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 18:00:05 +0800 Subject: [PATCH 165/309] add scheme to slider rename widget_colors to widget_geometrics --- include/nana/gui/detail/basic_window.hpp | 4 +- include/nana/gui/detail/bedrock.hpp | 4 +- include/nana/gui/detail/color_schemes.hpp | 12 +-- include/nana/gui/detail/widget_colors.hpp | 46 ------------ include/nana/gui/programming_interface.hpp | 10 +-- include/nana/gui/widgets/listbox.hpp | 2 +- .../widgets/skeletons/text_editor_part.hpp | 4 +- include/nana/gui/widgets/slider.hpp | 30 ++++++-- include/nana/gui/widgets/widget.hpp | 2 +- source/gui/detail/bedrock_pi.cpp | 4 +- source/gui/detail/color_schemes.cpp | 2 +- source/gui/programming_interface.cpp | 8 +- source/gui/widgets/slider.cpp | 75 +++++++++---------- 13 files changed, 84 insertions(+), 119 deletions(-) delete mode 100644 include/nana/gui/detail/widget_colors.hpp diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 6c66b709..6d44a936 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -16,7 +16,7 @@ #include #include "drawer.hpp" #include "events_holder.hpp" -#include "widget_colors.hpp" +#include "widget_geometrics.hpp" #include "widget_notifier_interface.hpp" #include #include @@ -180,7 +180,7 @@ namespace detail std::shared_ptr events_ptr; }together; - widget_colors* scheme{ nullptr }; + widget_geometrics* scheme{ nullptr }; struct { diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index e6d2e0e7..32a812ad 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -82,8 +82,8 @@ namespace detail void define_state_cursor(core_window_t*, nana::cursor, thread_context*); void undefine_state_cursor(core_window_t*, thread_context*); - widget_colors& get_scheme_template(scheme_factory_interface&&); - widget_colors* make_scheme(scheme_factory_interface&&); + widget_geometrics& get_scheme_template(scheme_factory_interface&&); + widget_geometrics* make_scheme(scheme_factory_interface&&); events_operation& evt_operation(); window_manager& wd_manager(); diff --git a/include/nana/gui/detail/color_schemes.hpp b/include/nana/gui/detail/color_schemes.hpp index 2d177c17..79e09775 100644 --- a/include/nana/gui/detail/color_schemes.hpp +++ b/include/nana/gui/detail/color_schemes.hpp @@ -13,7 +13,7 @@ #ifndef NANA_DETAIL_COLOR_SCHEMES_HPP #define NANA_DETAIL_COLOR_SCHEMES_HPP -#include "widget_colors.hpp" +#include "widget_geometrics.hpp" namespace nana { @@ -26,8 +26,8 @@ namespace nana virtual ~scheme_factory_interface() = default; virtual factory_identifier* get_id() const = 0; - virtual widget_colors* create() = 0; - virtual widget_colors* create(widget_colors&) = 0; + virtual widget_geometrics* create() = 0; + virtual widget_geometrics* create(widget_geometrics&) = 0; }; @@ -41,12 +41,12 @@ namespace nana return &fid_; } - widget_colors* create() override + widget_geometrics* create() override { return (new Scheme); } - widget_colors* create(widget_colors& other) override + widget_geometrics* create(widget_geometrics& other) override { return (new Scheme(static_cast(other))); } @@ -65,7 +65,7 @@ namespace nana color_schemes& operator=(const color_schemes&) = delete; color_schemes& operator=(color_schemes&&) = delete; public: - using scheme = widget_colors; + using scheme = widget_geometrics; color_schemes(); ~color_schemes(); diff --git a/include/nana/gui/detail/widget_colors.hpp b/include/nana/gui/detail/widget_colors.hpp deleted file mode 100644 index d4d81e1a..00000000 --- a/include/nana/gui/detail/widget_colors.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Color Schemes -* 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/gui/widget_colors.hpp -* @description: -*/ -#ifndef NANA_DETAIL_WIDGET_COLORS_HPP -#define NANA_DETAIL_WIDGET_COLORS_HPP - -#include -#include -namespace nana -{ - class color_proxy - { - public: - color_proxy(const color_proxy&); - color_proxy(color_rgb); - color_proxy(colors); - color_proxy& operator=(const color_proxy&); - color_proxy& operator=(const ::nana::color&); - color_proxy& operator=(color_rgb); - color_proxy& operator=(colors); - color get_color() const; - operator color() const; - private: - std::shared_ptr color_; - };//end namespace color_proxy - - struct widget_colors - { - virtual ~widget_colors() = default; - - color_proxy activated{ static_cast(0x60C8FD) }; - color_proxy background{colors::button_face}; - color_proxy foreground{colors::black}; - }; -} - -#endif \ No newline at end of file diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index c89508b4..23d5aee8 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -38,7 +38,7 @@ namespace nana struct widget_traits { using event_type = ::nana::general_events; - using scheme_type = ::nana::widget_colors; + using scheme_type = ::nana::widget_geometrics; }; } @@ -46,7 +46,7 @@ namespace API { namespace detail { - ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_interface&&); + ::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&&); } void effects_edge_nimbus(window, effects::edge_nimbus); @@ -70,8 +70,8 @@ namespace API return std::unique_ptr{static_cast(API::detail::make_scheme(::nana::detail::scheme_factory()))}; } - void set_scheme(window, widget_colors*); - widget_colors* get_scheme(window); + void set_scheme(window, widget_geometrics*); + widget_geometrics* get_scheme(window); void attach_drawer(widget&, drawer_trigger&); ::nana::detail::native_string_type window_caption(window) throw(); @@ -250,7 +250,7 @@ namespace API if (nullptr == wdg_colors) throw std::invalid_argument("API::scheme(): bad parameter window handle, no events object or invalid window handle."); - if (std::is_same<::nana::widget_colors, scheme_type>::value) + if (std::is_same<::nana::widget_geometrics, scheme_type>::value) return *static_cast(wdg_colors); auto * comp_wdg_colors = dynamic_cast(wdg_colors); diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 66dd726e..a9e7f423 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -520,7 +520,7 @@ namespace nana }; struct scheme - : public widget_colors + : public widget_geometrics { color_proxy header_bgcolor{static_cast(0xf1f2f4)}; color_proxy header_grabbed{ static_cast(0x8BD6F6)}; diff --git a/include/nana/gui/widgets/skeletons/text_editor_part.hpp b/include/nana/gui/widgets/skeletons/text_editor_part.hpp index 8cf1c389..71d8f525 100644 --- a/include/nana/gui/widgets/skeletons/text_editor_part.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor_part.hpp @@ -2,7 +2,7 @@ #ifndef NANA_WIDGETS_SKELETONS_TEXT_EDITOR_SCHEME_HPP #define NANA_WIDGETS_SKELETONS_TEXT_EDITOR_SCHEME_HPP -#include "../../detail/widget_colors.hpp" +#include "../../detail/widget_geometrics.hpp" #include namespace nana @@ -24,7 +24,7 @@ namespace nana class text_editor; struct text_editor_scheme - : public ::nana::widget_colors + : public ::nana::widget_geometrics { color_proxy selection{static_cast(0x3399FF)}; color_proxy selection_text{colors::white}; diff --git a/include/nana/gui/widgets/slider.hpp b/include/nana/gui/widgets/slider.hpp index 911accbd..fb15bc34 100644 --- a/include/nana/gui/widgets/slider.hpp +++ b/include/nana/gui/widgets/slider.hpp @@ -33,6 +33,23 @@ namespace nana { namespace slider { + + struct scheme_impl + : public widget_geometrics + { + /// Colors + color_proxy color_adorn{ static_cast(0x3da3ce) }; + color_proxy color_bar{ static_cast(0x878787) }; + color_proxy color_slider{ static_cast(0x606060) }; + color_proxy color_slider_highlighted{ static_cast(0x2d93be) }; + color_proxy color_vernier{ colors::red }; + color_proxy color_vernier_text{ colors::white }; + + /// Geometrical parameters + unsigned vernier_text_margin{ 8 }; + + }; + struct slider_events : public general_events { @@ -49,6 +66,7 @@ namespace nana { public: using graph_reference = ::nana::paint::graphics&; + using scheme = scheme_impl; struct data_bar { @@ -86,11 +104,11 @@ namespace nana virtual ~renderer_interface() = default; - virtual void background(window, graph_reference, bool isglass) = 0; - virtual void adorn(window, graph_reference, const data_adorn&) = 0; - virtual void vernier(window, graph_reference, const data_vernier&) = 0; - virtual void bar(window, graph_reference, const data_bar&) = 0; - virtual void slider(window, graph_reference, mouse_action, const data_slider&) = 0; + virtual void background(window, graph_reference, bool transparent, const scheme&) = 0; + virtual void adorn(window, graph_reference, const data_adorn&, const scheme&) = 0; + virtual void vernier(window, graph_reference, const data_vernier&, const scheme&) = 0; + virtual void bar(window, graph_reference, const data_bar&, const scheme&) = 0; + virtual void slider(window, graph_reference, mouse_action, const data_slider&, const scheme&) = 0; }; class trigger @@ -118,7 +136,7 @@ namespace nana /// A slider widget wich the user can drag for tracking \todo add scheme ? class slider - : public widget_object + : public widget_object { public: using renderer_interface = drawerbase::slider::renderer_interface; ///< The interface for customized renderer. diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index f2515e00..ae70b77b 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -160,7 +160,7 @@ namespace nana } /// Base class of all the classes defined as a widget window. Defaultly a widget_tag - template + template class widget_object: public detail::widget_base { protected: diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index e3fb1c6b..087fed6d 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -353,12 +353,12 @@ namespace nana return pi_data_->shortkey_occurred; } - widget_colors& bedrock::get_scheme_template(scheme_factory_interface&& factory) + widget_geometrics& bedrock::get_scheme_template(scheme_factory_interface&& factory) { return pi_data_->scheme.scheme_template(std::move(factory)); } - widget_colors* bedrock::make_scheme(scheme_factory_interface&& factory) + widget_geometrics* bedrock::make_scheme(scheme_factory_interface&& factory) { return pi_data_->scheme.create(std::move(factory)); } diff --git a/source/gui/detail/color_schemes.cpp b/source/gui/detail/color_schemes.cpp index 6cfa41d4..d9fca610 100644 --- a/source/gui/detail/color_schemes.cpp +++ b/source/gui/detail/color_schemes.cpp @@ -93,7 +93,7 @@ namespace nana return *tmpl_scheme.get(); } - widget_colors* color_schemes::create(scheme_factory_interface&& factory) + widget_geometrics* color_schemes::create(scheme_factory_interface&& factory) { return factory.create(scheme_template(std::move(factory))); } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 133b8326..ffcec9a0 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -55,7 +55,7 @@ namespace API namespace detail { - ::nana::widget_colors* make_scheme(::nana::detail::scheme_factory_interface&& factory) + ::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&& factory) { return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_interface&&>(factory)); } @@ -195,15 +195,15 @@ namespace API } - void set_scheme(window wd, widget_colors* wdg_colors) + void set_scheme(window wd, widget_geometrics* wdg_geom) { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) - iwd->scheme = wdg_colors; + iwd->scheme = wdg_geom; } - widget_colors* get_scheme(window wd) + widget_geometrics* get_scheme(window wd) { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index 28f6dcd5..f2b38b75 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -17,13 +17,13 @@ namespace nana : public renderer_interface { private: - void background(window wd, graph_reference graph, bool isglass) override + void background(window wd, graph_reference graph, bool transparent, const scheme& schm) override { - if(!isglass) - graph.rectangle(true, API::bgcolor(wd)); + if (!transparent) + graph.rectangle(true, schm.background); } - void bar(window, graph_reference graph, const data_bar& data) override + void bar(window, graph_reference graph, const data_bar& data, const scheme& schm) override { auto area = data.area; @@ -38,10 +38,10 @@ namespace nana area.height = 4; } - graph.rectangle(area, false, static_cast(0x878787)); + graph.rectangle(area, false, schm.color_bar); } - void adorn(window, graph_reference graph, const data_adorn& data) override + void adorn(window, graph_reference graph, const data_adorn& data, const scheme& schm) override { rectangle area{ data.bound.x, data.fixedpos + static_cast(data.block / 2) - 1, @@ -51,19 +51,19 @@ namespace nana if (data.vert) area.shift(); - graph.rectangle(area, true, static_cast(0x3DA3CE)); + graph.rectangle(area, true, schm.color_adorn); } - void vernier(window, graph_reference graph, const data_vernier& data) override + void vernier(window, graph_reference graph, const data_vernier& data, const scheme& schm) override { if (data.vert) - _m_draw_vernier_vert(graph, data); + _m_draw_vernier_vert(graph, data, schm); else - _m_draw_vernier_horz(graph, data); + _m_draw_vernier_horz(graph, data, schm); } - void slider(window, graph_reference graph, mouse_action mouse_act, const data_slider& data) override + void slider(window, graph_reference graph, mouse_action mouse_act, const data_slider& data, const scheme& schm) override { nana::rectangle area{ graph.size() }; @@ -78,9 +78,9 @@ namespace nana area.width = data.weight; } - color rgb{ static_cast(0x606060) }; + color rgb = schm.color_slider; if (mouse_action::normal != mouse_act) - rgb = static_cast(0x2d93be); + rgb = schm.color_slider_highlighted; graph.frame_rectangle(area, rgb + static_cast(0x0d0d0d), 1); graph.rectangle(area.pare_off(1), true, rgb); @@ -89,7 +89,7 @@ namespace nana graph.rectangle(area, true, rgb + static_cast(0x101010)); } private: - void _m_draw_vernier_horz(graph_reference graph, const data_vernier& data) + void _m_draw_vernier_horz(graph_reference graph, const data_vernier& data, const scheme& schm) { const unsigned arrow_weight = 5; @@ -107,12 +107,10 @@ namespace nana const size arrow_size{ arrow_weight, 9 }; - - const unsigned text_margin = 8; - const auto label_size = graph.text_extent_size(data.text) + size{ text_margin * 2, 0 }; + const auto label_size = graph.text_extent_size(data.text) + size{ schm.vernier_text_margin * 2, 0 }; paint::graphics graph_vern{ label_size }; - graph_vern.rectangle(true, colors::red); + graph_vern.rectangle(true, schm.color_vernier); int arrow_pos; @@ -132,10 +130,11 @@ namespace nana graph_vern.blend(rectangle{ label_size }, graph, label_pos, 0.5); + unsigned arrow_color = 0x7F | schm.color_vernier.get_color().argb().value; for (auto & color : arrow_pxbuf) { if (color == 0x7F) - color = 0x7FFF0000; + color = arrow_color; } if (label_pos.x > data.position) @@ -155,12 +154,11 @@ namespace nana pxbuf.paste(rectangle{ arrow_size }, graph.handle(), { arrow_pos, label_pos.y + static_cast(label_size.height - arrow_size.height) / 2 }); - label_pos.x += text_margin; - graph.palette(true, colors::white); - graph.string(label_pos, data.text); + label_pos.x += static_cast(schm.vernier_text_margin); + graph.string(label_pos, data.text, schm.color_vernier_text); } - void _m_draw_vernier_vert(graph_reference graph, const data_vernier& data) + void _m_draw_vernier_vert(graph_reference graph, const data_vernier& data, const scheme& schm) { const unsigned arrow_weight = 5; @@ -174,15 +172,13 @@ namespace nana const size arrow_size{ 9, arrow_weight}; - - const unsigned text_margin = 8; - const size label_size = (graph.text_extent_size(data.text) + size{ text_margin * 2, 0 }).shift(); + const size label_size = (graph.text_extent_size(data.text) + size{ schm.vernier_text_margin * 2, 0 }).shift(); paint::graphics graph_vern{ label_size }; paint::graphics graph_horz{ size(label_size).shift() }; - graph_horz.rectangle(true, colors::red); - graph_horz.string({static_cast(text_margin), static_cast(graph_horz.height() - label_size.width) / 2}, data.text, colors::white); + graph_horz.rectangle(true, schm.color_vernier); + graph_horz.string({ static_cast(schm.vernier_text_margin), static_cast(graph_horz.height() - label_size.width) / 2 }, data.text, schm.color_vernier_text); paint::pixel_buffer{ graph_horz.handle(), 0, graph_horz.height() }.rotate(90, colors::white).paste(graph_vern.handle(), {}); @@ -216,14 +212,13 @@ namespace nana graph_vern.blend(rectangle{ label_size }, graph, label_pos, 0.5); + unsigned arrow_color = 0x7F | schm.color_vernier.get_color().argb().value; for (auto & color : arrow_pxbuf) { if (color == 0x7F) - color = 0x7FFF0000; + color = arrow_color; } - /* - */ paint::pixel_buffer pxbuf{ arrow_size.width, arrow_size.height }; pxbuf.alpha_channel(true); @@ -231,11 +226,7 @@ namespace nana pxbuf.paste(rectangle{ arrow_size }, graph.handle(), { label_pos.x + static_cast(label_size.width - arrow_size.width) / 2, arrow_pos }); - label_pos.y += text_margin; - /* - graph.palette(true, colors::white); - graph.string(label_pos, data.text); - */ + label_pos.y += static_cast(schm.vernier_text_margin); } }; @@ -308,7 +299,7 @@ namespace nana { if(!graph.size().empty()) { - proto_.renderer->background(other_.wd, graph, (bground_mode::basic == API::effects_bground_mode(other_.wd))); + proto_.renderer->background(other_.wd, graph, (bground_mode::basic == API::effects_bground_mode(other_.wd)), other_.widget->scheme()); _m_draw_elements(graph); } } @@ -634,6 +625,8 @@ namespace nana void _m_draw_elements(graph_reference graph) { + auto & scheme = other_.widget->scheme(); + renderer_interface::data_bar bar; bar.vert = attr_.slider.vert; @@ -643,7 +636,7 @@ namespace nana if (bar.area.empty()) return; - proto_.renderer->bar(other_.wd, graph, bar); + proto_.renderer->bar(other_.wd, graph, bar, scheme); //adorn renderer_interface::data_adorn adorn; @@ -664,10 +657,10 @@ namespace nana adorn.block = (bar.vert ? bar.area.width : bar.area.height) - attr_.slider.border_weight * 2; adorn.fixedpos = static_cast((bar.vert ? bar.area.x : bar.area.y) + attr_.slider.border_weight); - proto_.renderer->adorn(other_.wd, graph, adorn); + proto_.renderer->adorn(other_.wd, graph, adorn, scheme); //Draw slider - proto_.renderer->slider(other_.wd, graph, slider_state_.mouse_state, attr_.slider); + proto_.renderer->slider(other_.wd, graph, slider_state_.mouse_state, attr_.slider, scheme); //adorn textbox if (proto_.vernier && attr_.is_draw_adorn) @@ -685,7 +678,7 @@ namespace nana vern.position += static_cast(attr_.adorn_pos); vern.end_position = adorn.bound.y; - proto_.renderer->vernier(other_.wd, graph, vern); + proto_.renderer->vernier(other_.wd, graph, vern, scheme); } } } From 0122a8b98b8e0d6f3e27fa543e0d972d5b269225 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 18:03:44 +0800 Subject: [PATCH 166/309] rename widget_colors to widget_geometrics --- include/nana/gui/detail/widget_geometrics.hpp | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 include/nana/gui/detail/widget_geometrics.hpp diff --git a/include/nana/gui/detail/widget_geometrics.hpp b/include/nana/gui/detail/widget_geometrics.hpp new file mode 100644 index 00000000..1cb8cd3e --- /dev/null +++ b/include/nana/gui/detail/widget_geometrics.hpp @@ -0,0 +1,46 @@ +/* +* Widget Geometrics +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file: nana/gui/widget_geometrics.hpp +* @description: +*/ +#ifndef NANA_DETAIL_WIDGET_GEOMETRICS_HPP +#define NANA_DETAIL_WIDGET_GEOMETRICS_HPP + +#include +#include +namespace nana +{ + class color_proxy + { + public: + color_proxy(const color_proxy&); + color_proxy(color_rgb); + color_proxy(colors); + color_proxy& operator=(const color_proxy&); + color_proxy& operator=(const ::nana::color&); + color_proxy& operator=(color_rgb); + color_proxy& operator=(colors); + color get_color() const; + operator color() const; + private: + std::shared_ptr color_; + };//end namespace color_proxy + + struct widget_geometrics + { + virtual ~widget_geometrics() = default; + + color_proxy activated{ static_cast(0x60C8FD) }; + color_proxy background{colors::button_face}; + color_proxy foreground{colors::black}; + }; +} + +#endif \ No newline at end of file From 9aa37d5238936687046e4863a811b287a7196ecd Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 22 May 2016 21:30:46 +0800 Subject: [PATCH 167/309] minor changes --- include/nana/gui/widgets/slider.hpp | 10 +++++----- source/paint/pixel_buffer.cpp | 5 +---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/include/nana/gui/widgets/slider.hpp b/include/nana/gui/widgets/slider.hpp index fb15bc34..9adb512c 100644 --- a/include/nana/gui/widgets/slider.hpp +++ b/include/nana/gui/widgets/slider.hpp @@ -38,12 +38,12 @@ namespace nana : public widget_geometrics { /// Colors - color_proxy color_adorn{ static_cast(0x3da3ce) }; - color_proxy color_bar{ static_cast(0x878787) }; - color_proxy color_slider{ static_cast(0x606060) }; + color_proxy color_adorn { static_cast(0x3da3ce) }; + color_proxy color_bar { static_cast(0x878787) }; + color_proxy color_slider { static_cast(0x606060) }; color_proxy color_slider_highlighted{ static_cast(0x2d93be) }; - color_proxy color_vernier{ colors::red }; - color_proxy color_vernier_text{ colors::white }; + color_proxy color_vernier { colors::red }; + color_proxy color_vernier_text { colors::white }; /// Geometrical parameters unsigned vernier_text_margin{ 8 }; diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index f2b438a1..23a8b4e5 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -1,7 +1,7 @@ /* * Pixel Buffer Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -1252,9 +1252,6 @@ namespace nana{ namespace paint const int right_point = static_cast(dest.x) + static_cast(size_rotated.width); - const int source_right = static_cast(sp->pixel_size.width); - const int source_bottom = static_cast(sp->pixel_size.height); - for (point point_dest{ static_cast(dest.x), static_cast(dest.y) }; point_dest.x < right_point; ++point_dest.x) { auto point_source = point_rotate.to(point_dest) + origin; From 32d988e1a7f4ea5fd1938758593ab0f28491fefa Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 2 Jun 2016 01:01:03 +0800 Subject: [PATCH 168/309] minor changes --- include/nana/gui/widgets/listbox.hpp | 4 ++++ source/gui/widgets/listbox.cpp | 11 ++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 422c0bcc..b5781ad2 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -17,6 +17,8 @@ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP +#include + #include "widget.hpp" #include "detail/inline_widget.hpp" #include @@ -747,4 +749,6 @@ the nana::detail::basic_window member pointer scheme void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana + +#include #endif diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 476528aa..bf1260cc 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2341,7 +2341,7 @@ namespace nana unsigned auto_width(size_type pos, unsigned max = 100000) { - max = std::min(max, scheme_ptr->max_header_width); + max = (std::min)(max, scheme_ptr->max_header_width); unsigned max_w{ 0 }; for (const auto &cat : lister.cat_container()) for (const auto &it : cat.items) @@ -2357,7 +2357,7 @@ namespace nana unsigned ext_w = scheme_ptr->ext_w; if (pos == 0 && checkable) // only before the first column (display_order=0 ?) ext_w += 18; // add to geom. scheme (width of the checker) ?? - header.item_width(pos, std::min(max, max_w + ext_w + 1 )); + header.item_width(pos, (std::min)(max, max_w + ext_w + 1 )); return max_w; } @@ -3069,7 +3069,7 @@ namespace nana bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } - unsigned show_w = std::min(content_r.width, width - essence_->scroll.offset_x); + unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.offset_x); auto graph = essence_->graph; @@ -3230,7 +3230,7 @@ namespace nana graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over graph->rectangle(rectangle( item_right, y /*+ 2*/, excess, essence_->scheme_ptr->item_height /*- 4*/ ), true); } - extreme_text = std::max(extreme_text, text_right); + extreme_text = (std::max)(extreme_text, text_right); } } } @@ -3343,10 +3343,7 @@ namespace nana void trigger::attached(widget_reference widget, graph_reference graph) { - //essence_->scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); - //essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); - //essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); essence_->graph = &graph; typeface_changed(graph); From f84e91990d2bcc37a5b446c8c1ab0bf05db3932d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 2 Jun 2016 01:22:47 +0800 Subject: [PATCH 169/309] integrate place with root widget --- include/nana/gui/place.hpp | 2 +- include/nana/gui/widgets/widget.hpp | 37 +++++++++++++++++++++++++---- include/nana/key_type.hpp | 18 +++++++------- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/include/nana/gui/place.hpp b/include/nana/gui/place.hpp index 2f5dc52c..4f674cf2 100644 --- a/include/nana/gui/place.hpp +++ b/include/nana/gui/place.hpp @@ -100,7 +100,7 @@ namespace nana }; public: /// reference to a field manipulator which refers to a field object created by place - typedef field_interface & field_reference; + using field_reference = field_interface &; place(); place(window);///< Attaches to a specified widget. diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index ae70b77b..952cd2a4 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -14,11 +14,10 @@ #define NANA_GUI_WIDGET_HPP #include -#include "../basis.hpp" +#include #include "../programming_interface.hpp" #include #include -#include namespace nana { @@ -392,6 +391,33 @@ namespace nana { return API::window_outline_size(handle()); } + + place & get_place() + { + if (this->empty()) + throw std::runtime_error("form::get_plac: the form has destroyed."); + + if (!place_) + place_.reset(new place{ *this }); + + return *place_; + } + + void div(const char* div_text) + { + get_place().div(div_text); + } + + place::field_reference operator[](const char* field_name) + { + return get_place()[field_name]; + } + + void collocate() noexcept + { + if (place_) + place_->collocate(); + } protected: DrawerTrigger& get_drawer_trigger() { @@ -418,9 +444,10 @@ namespace nana return *events_; } private: - DrawerTrigger trigger_; - std::shared_ptr events_; - std::unique_ptr scheme_; + DrawerTrigger trigger_; + std::shared_ptr events_; + std::unique_ptr scheme_; + std::unique_ptr place_; };//end class widget_object /// Base class of all the classes defined as a frame window. \see nana::frame diff --git a/include/nana/key_type.hpp b/include/nana/key_type.hpp index dcfa4f79..ced29c50 100644 --- a/include/nana/key_type.hpp +++ b/include/nana/key_type.hpp @@ -34,55 +34,55 @@ namespace nana template struct type_escape { - typedef T type; + using type = T; }; template<> struct type_escape { - typedef std::string type; + using type = ::std::string; }; template<> struct type_escape { - typedef std::string type; + using type = ::std::string; }; template struct type_escape { - typedef std::string type; + using type = ::std::string; }; template struct type_escape { - typedef std::string type; + using type = ::std::string; }; template<> struct type_escape { - typedef std::wstring type; + using type = ::std::wstring; }; template<> struct type_escape { - typedef std::wstring type; + using type = ::std::wstring; }; template struct type_escape { - typedef std::wstring type; + using type = ::std::wstring; }; template struct type_escape { - typedef std::wstring type; + using type = ::std::wstring; }; } From 5b1891c18657baef4d319dc356fdfe1111aef980 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 3 Jun 2016 08:00:19 +0800 Subject: [PATCH 170/309] listbox associative category access --- include/nana/gui/widgets/listbox.hpp | 140 +++++++++++++++++++------- include/nana/key_type.hpp | 4 +- source/gui/widgets/combox.cpp | 4 +- source/gui/widgets/listbox.cpp | 143 ++++++++++++++++++--------- 4 files changed, 208 insertions(+), 83 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index a9e7f423..9973c67a 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -610,8 +610,93 @@ By \a clicking on one header the list get \a reordered, first up, and then down listbox(window, bool visible); listbox(window, const rectangle& = {}, bool visible = true); + //Element access + + /// Returns the category at specified location pos, with bounds checking. + cat_proxy at(size_type pos); + const cat_proxy at(size_type pos) const; + + /// Returns the item at specified absolute position + item_proxy at(const index_pair& abs_pos); + const item_proxy at(const index_pair &abs_pos) const; + + /// Returns the category at specified location pos, no bounds checking is performed. + cat_proxy operator[](size_type pos); + const cat_proxy operator[](size_type pos) const; + + /// Returns the item at specified absolute position, no bounds checking is performed. + item_proxy operator[](const index_pair& abs_pos); + const item_proxy operator[](const index_pair &abs_pos) const; + + //Associative element access + + /// Returns a proxy to the category of the key or create a new one in the right order + /** + * @param key The key of category to find + * @return A category proxy + */ + template + cat_proxy assoc(Key&& key) + { + using key_type = typename ::nana::detail::type_escape::type>::type; + + auto p = std::make_shared>>(std::forward(key)); + return cat_proxy(&_m_ess(), _m_assoc(p, true)); + } + + /// Returns a proxy to the category of the key or create a new one in the right order + /** + * @param key The key of category to find + * @return A category proxy + */ + template + cat_proxy assoc_at(Key&& key) + { + using key_type = typename ::nana::detail::type_escape::type>::type; + + auto p = std::make_shared>>(std::forward(key)); + + auto categ = _m_assoc(p, false); + if (nullptr == categ) + throw std::out_of_range("listbox: invalid key."); + + return cat_proxy(&_m_ess(), categ); + } + + /// Removes a category which is associated with the specified key + /** + * @param key The key of category to remove + */ + template + void assoc_erase(Key&& key) + { + using key_type = typename ::nana::detail::type_escape::type>::type; + + ::nana::key> wrap(key); + _m_erase_key(&wrap); + } + + bool assoc_ordered(bool); + + void auto_draw(bool); ///< Set state: Redraw automatically after an operation + template + void avoid_drawing(Function fn) + { + this->auto_draw(false); + try + { + fn(); + } + catch (...) + { + this->auto_draw(true); + throw; + } + this->auto_draw(true); + } + /// Scrolls the view to the first or last item of a specified category void scroll(bool to_bottom, size_type cat_pos = ::nana::npos); void scroll(bool to_bottom, const index_pair& pos); @@ -631,49 +716,32 @@ By \a clicking on one header the list get \a reordered, first up, and then down cat_proxy insert(cat_proxy, ::std::string); cat_proxy insert(cat_proxy, ::std::wstring); - cat_proxy at(size_type pos) const; - /// add categories in order when use a key? - listbox& ordered_categories(bool); + /// Inserts an item before a specified position + /** + * @param abs_pos The absolute position before which an item will be inserted. + * @param text Text of the first column, in UTF-8 encoded. + */ + void insert_item(const index_pair& abs_pos, ::std::string text); - /// return a proxy to tha cat with the key or create a new one in the right order - template - cat_proxy operator[](const Key & ck) - { - using catkey = typename ::nana::detail::type_escape::type; - std::shared_ptr p(new nana::key>(ck), [](nana::detail::key_interface* p) - { - delete p; - }); + /// Inserts an item before a specified position + /** + * @param abs_pos The absolute position before which an item will be inserted. + * @param text Text of the first column. + */ + void insert_item(const index_pair& abs_pos, ::std::wstring text); - return cat_proxy(&_m_ess(), _m_at_key(p)); - } - template - cat_proxy operator[](Key && ck) - { - using catkey = typename ::nana::detail::type_escape::type; - std::shared_ptr p(new nana::key>(std::move(ck)), [](nana::detail::key_interface* p) - { - delete p; - }); - - return cat_proxy(&_m_ess(), _m_at_key(p)); - } - - /// Returns an item by the specified absolute position - item_proxy at(const index_pair &abs_pos) const; /// Returns an index of item which contains the specified point. - index_pair at(const point & pos) const; + index_pair cast(const point & pos) const; + + /// add categories in order when use a key? + //listbox& ordered_categories(bool); //deprecated /// Returns the column which contains the specified point. columns_indexs column_from_pos(const point & pos); - - void insert(const index_pair&, ::std::string); /// - void erase_key(const Key& kv) + void erase_key(const Key& kv) //deprecated { typedef typename nana::detail::type_escape::type key_t; nana::key > key(kv); @@ -698,6 +767,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down nana::key > key(std::move(kv)); _m_erase_key(&key); } + */ bool sortable() const; void sortable(bool enable); @@ -730,7 +800,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down private: drawerbase::listbox::essence_t & _m_ess() const; nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const; - drawerbase::listbox::category_t* _m_at_key(std::shared_ptr); + drawerbase::listbox::category_t* _m_assoc(std::shared_ptr, bool create_if_not_exists); void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana diff --git a/include/nana/key_type.hpp b/include/nana/key_type.hpp index ced29c50..9bca1e18 100644 --- a/include/nana/key_type.hpp +++ b/include/nana/key_type.hpp @@ -26,9 +26,9 @@ namespace nana }; //end class key_interface //Use less compare for equal compare [call it equal_by_less()?] - inline bool pred_equal_by_less(const key_interface * left, const key_interface* right) + inline bool pred_equal(const key_interface * left, const key_interface* right) { - return (left->compare(right) == false) && (right->compare(left) == false); + return (left->same_type(right) && (left->compare(right) == false) && (right->compare(left) == false)); } template diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index 374a9baa..6f5b6de3 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -364,7 +364,7 @@ namespace nana std::size_t pos = 0; for (auto & m : items_) { - if (m->key && detail::pred_equal_by_less(m->key.get(), p.get())) + if (m->key && detail::pred_equal(m->key.get(), p.get())) return pos; ++pos; } @@ -384,7 +384,7 @@ namespace nana std::size_t pos = 0; for (auto & m : items_) { - if (m->key && detail::pred_equal_by_less(m->key.get(), kv)) + if (m->key && detail::pred_equal(m->key.get(), kv)) { erase(pos); return; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 41254770..8aca3d79 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -872,11 +872,20 @@ namespace nana { for (auto i = list_.begin(); i != list_.end(); ++i) { - if (i->key_ptr && i->key_ptr->compare(ptr.get())) + if (i->key_ptr) { - i = list_.emplace(i); - i->key_ptr = ptr; - return &(*i); + if (!i->key_ptr->same_type(ptr.get())) + { + this->ordered_categories_ = false; + break; + } + else if (ptr->compare(i->key_ptr.get())) + { + + i = list_.emplace(i); + i->key_ptr = ptr; + return &(*i); + } } } @@ -892,13 +901,13 @@ namespace nana } /// Insert before item in absolute "pos" a new item with "text" in column 0, and place it in last display position of this cat - bool insert(const index_pair& pos, std::string&& text) + void insert(const index_pair& pos, std::string&& text) { auto & catobj = *get(pos.cat); const auto n = catobj.items.size(); if (pos.item > n) - return false; + throw std::out_of_range("listbox: insert an item at invalid position"); catobj.sorted.push_back(n); @@ -906,8 +915,6 @@ namespace nana catobj.items.emplace(catobj.items.begin() + pos.item, std::move(text)); else catobj.items.emplace_back(std::move(text)); - - return true; } /// convert from display order to absolute (find the real item in that display pos) but without check from current active sorting, in fact using just the last sorting !!! @@ -1178,10 +1185,28 @@ namespace nana //Enable/Disable the ordered categories bool enable_ordered(bool enb) { - if (ordered_categories_ == enb) - return false; + if (ordered_categories_ != enb) + { + if (enb) + { + ::nana::detail::key_interface * refkey = nullptr; + for (auto i = list_.begin(); i != list_.end(); ++i) + { + if (i->key_ptr) + { + if (refkey) + { + if (!i->key_ptr->same_type(refkey)) + return false; + } + else + refkey = i->key_ptr.get(); + } + } + } - ordered_categories_ = enb; + ordered_categories_ = enb; + } return true; } @@ -4352,6 +4377,17 @@ namespace nana create(wd, r, visible); } + bool listbox::assoc_ordered(bool enable) + { + internal_scope_guard lock; + + auto & ess = _m_ess(); + if (ess.lister.enable_ordered(enable)) + ess.update(); + + return true; + } + void listbox::auto_draw(bool ad) { _m_ess().set_auto_draw(ad); @@ -4486,16 +4522,57 @@ namespace nana return cat_proxy{ &ess, new_cat_ptr }; } - listbox::cat_proxy listbox::at(size_type pos) const + + void listbox::insert_item(const index_pair& pos, std::string text) + { + internal_scope_guard lock; + auto & ess = _m_ess(); + ess.lister.insert(pos, std::move(text)); + + if (!empty()) + { + auto & item = ess.lister.at(pos); + item.bgcolor = bgcolor(); + item.fgcolor = fgcolor(); + ess.update(); + } + } + + void listbox::insert_item(const index_pair& pos, std::wstring text) + { + insert_item(pos, to_utf8(text)); + } + + listbox::cat_proxy listbox::at(size_type pos) + { + auto & ess = _m_ess(); + if (pos >= ess.lister.size_categ()) + throw std::out_of_range("Nana.Listbox.at(): invalid position"); + + return{ &ess, pos }; + } + + const listbox::cat_proxy listbox::at(size_type pos) const { auto & ess = _m_ess(); if(pos >= ess.lister.size_categ()) throw std::out_of_range("Nana.Listbox.at(): invalid position"); - return cat_proxy(&ess, pos); + return{ &ess, pos }; } - listbox& listbox::ordered_categories(bool enable_ordered) + listbox::item_proxy listbox::at(const index_pair& abs_pos) + { + return at(abs_pos.cat).at(abs_pos.item); + } + + const listbox::item_proxy listbox::at(const index_pair& pos_abs) const + { + return at(pos_abs.cat).at(pos_abs.item); + } + + /* + listbox& listbox::ordered_categories(bool enable_ordered) //deprecated { internal_scope_guard lock; @@ -4505,15 +4582,11 @@ namespace nana return *this; } - - listbox::item_proxy listbox::at(const index_pair& pos_abs) const - { - return at(pos_abs.cat).at(pos_abs.item); - } + */ // Contributed by leobackes(pr#97) - listbox::index_pair listbox::at ( const point& pos ) const + listbox::index_pair listbox::cast( const point& pos ) const { auto & ess=_m_ess(); auto _where=ess.where(pos.x, pos.y); @@ -4534,27 +4607,6 @@ namespace nana return col; } - void listbox::insert(const index_pair& pos, std::string text) - { - internal_scope_guard lock; - auto & ess = _m_ess(); - if (ess.lister.insert(pos, std::move(text))) - { - if (!empty()) - { - auto & item = ess.lister.at(pos); - item.bgcolor = bgcolor(); - item.fgcolor = fgcolor(); - ess.update(); - } - } - } - - void listbox::insert(const index_pair& pos, std::wstring text) - { - insert(pos, to_utf8(text)); - } - void listbox::checkable(bool chkable) { auto & ess = _m_ess(); @@ -4767,7 +4819,7 @@ namespace nana return _m_ess().lister.anyobj(index_pair{cat, index}, allocate_if_empty); } - drawerbase::listbox::category_t* listbox::_m_at_key(std::shared_ptr ptr) + drawerbase::listbox::category_t* listbox::_m_assoc(std::shared_ptr ptr, bool create_if_not_exists) { auto & ess = _m_ess(); @@ -4775,10 +4827,13 @@ namespace nana for (auto & m : ess.lister.cat_container()) { - if (m.key_ptr && nana::detail::pred_equal_by_less(ptr.get(), m.key_ptr.get())) + if (m.key_ptr && nana::detail::pred_equal(ptr.get(), m.key_ptr.get())) return &m; } + if (!create_if_not_exists) + return nullptr; + drawerbase::listbox::category_t* cat; if (ess.lister.enable_ordered()) @@ -4801,7 +4856,7 @@ namespace nana internal_scope_guard lock; for (auto i = cont.begin(); i != cont.end(); ++i) { - if (i->key_ptr && nana::detail::pred_equal_by_less(p, i->key_ptr.get())) + if (i->key_ptr && nana::detail::pred_equal(p, i->key_ptr.get())) { cont.erase(i); return; From 108a31d907d55fdb5870364d03c25f5e822cd157 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 5 Jun 2016 01:28:43 +0800 Subject: [PATCH 171/309] fix an integer division by zero of text_editor issue --- source/gui/widgets/skeletons/text_editor.cpp | 31 +++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 2ec36439..0c8cf46a 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -477,7 +477,8 @@ namespace nana{ namespace widgets std::size_t _m_textline_from_screen(int y) const { const std::size_t textlines = editor_.textbase_.lines(); - if (0 == textlines) + const auto line_px = static_cast(editor_.line_height()); + if ((0 == textlines) || (0 == line_px)) return 0; const int offset_top = editor_.points_.offset.y; @@ -486,7 +487,7 @@ namespace nana{ namespace widgets if (y < text_area_top) y = offset_top ? offset_top - 1 : 0; else - y = (y - text_area_top) / static_cast(editor_.line_height()) + offset_top; + y = (y - text_area_top) / line_px + offset_top; return (textlines <= static_cast(y) ? textlines - 1 : static_cast(y)); } @@ -1106,28 +1107,24 @@ namespace nana{ namespace widgets //secondary, index of line that the text was splitted into multilines. std::size_t _m_textline_from_screen(int y, std::size_t & secondary) const { - const int text_area_top = editor_.text_area_.area.y; - const int offset_top = editor_.points_.offset.y; + const auto line_px = static_cast(editor_.line_height()); - if (0 == editor_.textbase_.lines()) + if ((0 == editor_.textbase_.lines()) || (0 == line_px)) { secondary = 0; return 0; } - std::size_t screen_line; - if (y < text_area_top) - { - screen_line = (text_area_top - y) / static_cast(editor_.line_height()); - if (screen_line > static_cast(offset_top)) - screen_line = 0; - else - screen_line = static_cast(offset_top)-screen_line; - } - else - screen_line = static_cast((y - text_area_top) / static_cast(editor_.line_height()) + offset_top); + const int text_area_top = editor_.text_area_.area.y; + const int offset_top = editor_.points_.offset.y; - auto primary = _m_textline(screen_line, secondary); + auto screen_line = (text_area_top - y) / line_px; + if ((y < text_area_top) && (screen_line > offset_top)) + screen_line = 0; + else + screen_line = offset_top - screen_line; + + auto primary = _m_textline(static_cast(screen_line), secondary); if (primary < linemtr_.size()) return primary; From 5ab0cfdd17ae2ca1b9063abb6428197c70cba4c9 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 5 Jun 2016 02:36:38 +0800 Subject: [PATCH 172/309] fix a notifier error that can't set icon from its exe file --- include/nana/gui/notifier.hpp | 2 +- source/gui/detail/native_window_interface.cpp | 19 +---- source/gui/notifier.cpp | 77 ++++++++----------- source/paint/image.cpp | 17 ++++ source/paint/image_accessor.hpp | 30 ++++++++ 5 files changed, 84 insertions(+), 61 deletions(-) create mode 100644 source/paint/image_accessor.hpp diff --git a/include/nana/gui/notifier.hpp b/include/nana/gui/notifier.hpp index 48442a96..3e136cdb 100644 --- a/include/nana/gui/notifier.hpp +++ b/include/nana/gui/notifier.hpp @@ -1,7 +1,7 @@ /* * Definition of Notifier * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index b21eb270..4f356b83 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -28,24 +28,9 @@ #include #endif -namespace nana{ - namespace paint - { - class image_accessor - { - public: -#if defined(NANA_WINDOWS) - static HICON icon(const nana::paint::image& img) - { - auto ico = dynamic_cast(img.image_ptr_.get()); - if(ico && ico->ptr()) - return *(ico->ptr()); - return nullptr; - } -#endif - }; - } +#include "../../paint/image_accessor.hpp" +namespace nana{ namespace detail{ #if defined(NANA_WINDOWS) diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 4a9f6ac3..d541788b 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -1,17 +1,17 @@ /* - * Implementation of Notifier - * 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/notifier.cpp - * @contributors: - * Jan - * Benjamin Navarro(pr#81) - */ +* Implementation of Notifier +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file: nana/gui/notifier.cpp +* @contributors: +* Jan +* Benjamin Navarro(pr#81) +*/ #include #include #include @@ -33,9 +33,11 @@ #include #endif +#include "../paint/image_accessor.hpp" + namespace nana { - typedef std::lock_guard lock_guard; + using lock_guard = std::lock_guard; struct notifier::implement { @@ -47,13 +49,15 @@ namespace nana detail::notifier_events events; bool icon_added = false; std::size_t play_index; -#if defined(NANA_WINDOWS) - HICON icon_handle = nullptr; - std::vector icons; - void set_icon(HICON icon) + paint::image icon; + ::std::vector icons; + + void set_icon(const paint::image& ico) { - if (icon_handle) +#if defined(NANA_WINDOWS) + auto ico_handle = paint::image_accessor::icon(ico); + if (ico_handle) { NOTIFYICONDATA icon_data; memset(&icon_data, 0, sizeof icon_data); @@ -62,13 +66,13 @@ namespace nana icon_data.uID = id; icon_data.uFlags = NIF_MESSAGE | NIF_ICON; icon_data.uCallbackMessage = nana::detail::messages::tray; - icon_data.hIcon = icon; + icon_data.hIcon = ico_handle; ::Shell_NotifyIcon(icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); icon_added = true; } - } #endif + } }; arg_notifier::operator nana::arg_mouse() const @@ -287,12 +291,6 @@ namespace nana icon_data.hWnd = reinterpret_cast(impl_->native_handle); icon_data.uID = impl_->id; ::Shell_NotifyIcon(NIM_DELETE, &icon_data); - - if (impl_->icon_handle) - ::DestroyIcon(impl_->icon_handle); - - for (auto handle : impl_->icons) - ::DestroyIcon(handle); #endif API::umake_event(impl_->evt_destroy); notifications::instance().cancel(impl_->native_handle, impl_->id); @@ -321,30 +319,23 @@ namespace nana void notifier::icon(const std::string& icon_file) { -#if defined(NANA_WINDOWS) - auto pre_icon = impl_->icon_handle; - auto ico = (HICON)::LoadImageW(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - if (ico) + paint::image image_ico{ icon_file }; + auto icon_handle = paint::image_accessor::icon(image_ico); + if (icon_handle) { - impl_->icon_handle = ico; impl_->ani_timer.stop(); impl_->play_index = 0; - impl_->set_icon(impl_->icon_handle); - ::DestroyIcon(pre_icon); + impl_->set_icon(image_ico); + impl_->icon = image_ico; } -#else - static_cast(icon_file); //to eliminate unused parameter compiler warning -#endif } void notifier::insert_icon(const std::string& icon_file) { -#if defined(NANA_WINDOWS) - auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - impl_->icons.push_back(icon); -#else - static_cast(icon_file); //to eliminate unused parameter compiler warning. -#endif + paint::image image_ico{ icon_file }; + auto icon_handle = paint::image_accessor::icon(image_ico); + if (icon_handle) + impl_->icons.emplace_back(static_cast(image_ico)); } void notifier::period(unsigned ms) diff --git a/source/paint/image.cpp b/source/paint/image.cpp index 529c5c44..a1e2c889 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -34,10 +34,27 @@ #include "detail/image_bmp.hpp" #include "detail/image_ico.hpp" +#include "image_accessor.hpp" + namespace nana { namespace paint { +#if defined(NANA_WINDOWS) + HICON image_accessor::icon(const nana::paint::image& img) + { + auto ico = dynamic_cast(img.image_ptr_.get()); + if (ico && ico->ptr()) + return *(ico->ptr()); + return nullptr; + } +#else + int image_accessor::icon(const image&) + { + return 0; + } +#endif + namespace detail { //class image_ico diff --git a/source/paint/image_accessor.hpp b/source/paint/image_accessor.hpp new file mode 100644 index 00000000..73060e7e --- /dev/null +++ b/source/paint/image_accessor.hpp @@ -0,0 +1,30 @@ +/* +* Paint Image Accessor +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file nana/paint/image_accessor.hpp +* @brief A declaration of class image_accessor. It is used to access image private data, internal use. +*/ +#ifndef NANA_PAINT_IMAGE_ACCESS_HEADER_INCLUDED +#define NANA_PAINT_IMAGE_ACCESS_HEADER_INCLUDED +namespace nana +{ + namespace paint + { + class image_accessor + { + public: +#if defined(NANA_WINDOWS) + static HICON icon(const image&); +#else + static int icon(const image&); +#endif + }; + } +} +#endif \ No newline at end of file From 9c7ffbeb15c7a686ddd2672c8ff342366c3e2b72 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 10 Jun 2016 16:02:20 +0800 Subject: [PATCH 173/309] avoid UB when int is added to a pointer --- source/deploy.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/deploy.cpp b/source/deploy.cpp index f4337e54..89833ba0 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -500,16 +500,15 @@ namespace nana if (uv < 0xC0) return false; - if ((uv < 0xE0) && (ustr + 1 < end)) + if ((uv < 0xE0) && (end - ustr > 1)) ustr += 2; - else if (uv < 0xF0 && (ustr + 2 <= end)) + else if ((uv < 0xF0) && (end - ustr > 2)) ustr += 3; - else if (uv < 0x1F && (ustr + 3 <= end)) + else if ((uv < 0x1F) && (end - ustr > 3)) ustr += 4; else return false; } - return true; } From 5fdaeb6f458c4c21168c297aeecaac74031bc2cc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 10 Jun 2016 16:04:22 +0800 Subject: [PATCH 174/309] remove deprecated code --- include/nana/gui/widgets/listbox.hpp | 21 --------------------- include/nana/gui/widgets/textbox.hpp | 7 +++++-- source/gui/widgets/listbox.cpp | 14 -------------- 3 files changed, 5 insertions(+), 37 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 9973c67a..02f4fe88 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -736,9 +736,6 @@ By \a clicking on one header the list get \a reordered, first up, and then down /// Returns an index of item which contains the specified point. index_pair cast(const point & pos) const; - /// add categories in order when use a key? - //listbox& ordered_categories(bool); //deprecated - /// Returns the column which contains the specified point. columns_indexs column_from_pos(const point & pos); @@ -751,24 +748,6 @@ By \a clicking on one header the list get \a reordered, first up, and then down void erase(); /// - void erase_key(const Key& kv) //deprecated - { - typedef typename nana::detail::type_escape::type key_t; - nana::key > key(kv); - _m_erase_key(&key); - } - - template - void erase_key(Key&& kv) - { - typedef typename nana::detail::type_escape::type key_t; - nana::key > key(std::move(kv)); - _m_erase_key(&key); - } - */ - bool sortable() const; void sortable(bool enable); diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 13b4eb9b..12008c37 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -172,15 +172,18 @@ namespace nana /// Appends an string. If `at_caret` is `true`, the string is inserted at the position of caret, otherwise, it is appended at end of the textbox. textbox& append(const std::string& text, bool at_caret); - /// Determine wheter the text is line wrapped. + /// Determines whether the text is line wrapped. bool line_wrapped() const; textbox& line_wrapped(bool); - /// Determine whether the text is multi-line enabled. + /// Determines whether the text is multi-line enabled. bool multi_lines() const; textbox& multi_lines(bool); + + /// Determines whether the textbox accepts user input bool editable() const; textbox& editable(bool); + void set_accept(std::function); textbox& tip_string(::std::string); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8aca3d79..9c227d20 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -4571,20 +4571,6 @@ namespace nana return at(pos_abs.cat).at(pos_abs.item); } - /* - listbox& listbox::ordered_categories(bool enable_ordered) //deprecated - { - internal_scope_guard lock; - - auto & ess = _m_ess(); - if (ess.lister.enable_ordered(enable_ordered)) - ess.update(); - - return *this; - } - */ - - // Contributed by leobackes(pr#97) listbox::index_pair listbox::cast( const point& pos ) const { From 488f6ac88c818e212e81e77191cad56ac322e99f Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 12 Jun 2016 06:27:25 +0800 Subject: [PATCH 175/309] remove essence_t::scroll_part::offset_x of listbox --- include/nana/gui/widgets/listbox.hpp | 7 +- source/gui/notifier.cpp | 26 +-- source/gui/widgets/listbox.cpp | 303 ++++++++++++++++----------- 3 files changed, 201 insertions(+), 135 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index dcf6761e..fcfca488 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -359,7 +359,8 @@ namespace nana private: essence_t * ess_; category_t* cat_{nullptr}; - index_pair pos_; + + index_pair pos_; //Position of an item, it never represents a category when item proxy is available. }; class cat_proxy @@ -492,7 +493,7 @@ namespace nana }; /// The event argument type for listbox's category_dbl_click - struct arg_category + struct arg_listbox_category : public event_arg { drawerbase::listbox::cat_proxy category; @@ -503,7 +504,7 @@ namespace nana /// Determines whether expension/shrink of category is blocked bool category_change_blocked() const noexcept; - arg_category(const drawerbase::listbox::cat_proxy&) noexcept; + arg_listbox_category(const drawerbase::listbox::cat_proxy&) noexcept; private: mutable bool block_change_; }; diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 49d604b8..679969ac 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -1,17 +1,17 @@ /* -* Implementation of Notifier -* Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) -* -* Distributed under the Boost Software License, Version 1.0. -* (See accompanying file LICENSE_1_0.txt or copy at -* http://www.boost.org/LICENSE_1_0.txt) -* -* @file: nana/gui/notifier.cpp -* @contributors: -* Jan -* Benjamin Navarro(pr#81) -*/ + * Implementation of Notifier + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/gui/notifier.cpp + * @contributors: + * Jan + * Benjamin Navarro(pr#81) + */ #include #include #include diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 68c34cb8..9a03dc3d 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -17,6 +17,9 @@ * */ +//This marco is used for debugging. It keeps deprecated code for verifying new implementation until new release. +//#define USE_OFFSET_X + #include #include #include //for inline widget @@ -29,33 +32,13 @@ #include #include #include -#include // for debug namespace nana -{ - //void debug(const std::string &msg, const rectangle&r) - //{ - // std::cerr <<"\n" < ptr) { for (auto i = list_.begin(); i != list_.end(); ++i) @@ -1496,76 +1479,78 @@ namespace nana single = true; limited = category_limited; - auto pred = [for_selection](category_t::container::value_type & m){ - return (for_selection ? m.flags.selected : m.flags.checked); - }; + auto pred = [for_selection](category_t::container::value_type & m){ + return (for_selection ? m.flags.selected : m.flags.checked); + }; - auto cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos) + auto cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos) + { + arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)), false }; + if (for_selection) { - arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)), false }; - if (for_selection) - { - m.flags.selected = false; - widget_->events().selected.emit(arg, widget_->handle()); - } - else - { - m.flags.checked = false; - widget_->events().checked.emit(arg, widget_->handle()); - } - }; + m.flags.selected = false; + widget_->events().selected.emit(arg, widget_->handle()); + } + else + { + m.flags.checked = false; + widget_->events().checked.emit(arg, widget_->handle()); + } + }; - std::size_t cat_pos = 0; - if (category_limited) + std::size_t cat_pos = 0; + if (category_limited) + { + for (auto & cat : list_) { - for (auto & cat : list_) + auto i = std::find_if(cat.items.begin(), cat.items.end(), pred); + if (i != cat.items.end()) { - auto i = std::find_if(cat.items.begin(), cat.items.end(), pred); - if (i != cat.items.end()) + ++i; + for (auto end = cat.items.end(); i != end; ++i) { - ++i; - for (auto end = cat.items.end(); i != end; ++i) + if (pred(*i)) + cancel(*i, cat_pos, i - cat.items.begin()); + } + } + ++cat_pos; + } + } + else + { + bool selected = false; + for (auto & cat : list_) + { + if (!selected) + { + const auto end = cat.items.end(); + + auto i = std::find_if(cat.items.begin(), end, pred); + if (i != end) + { + selected = true; + + for (++i; i != end; ++i) { if (pred(*i)) cancel(*i, cat_pos, i - cat.items.begin()); } } - ++cat_pos; } - } - else - { - bool selected = false; - for (auto & cat : list_) + else { - if (!selected) + std::size_t item_pos = 0; + for (auto & m : cat.items) { - auto i = std::find_if(cat.items.begin(), cat.items.end(), pred); - if (i != cat.items.end()) - { - selected = true; - ++i; - for (auto end = cat.items.end(); i != end; ++i) - { - if (pred(*i)) - cancel(*i, cat_pos, i - cat.items.begin()); - } - } - } - else - { - std::size_t item_pos = 0; - for (auto & m : cat.items) - { - if (pred(m)) - cancel(m, cat_pos, item_pos); + if (pred(m)) + cancel(m, cat_pos, item_pos); - ++item_pos; - } + ++item_pos; } - ++cat_pos; } + ++cat_pos; } + } } void disable_single(bool for_selection) @@ -1808,11 +1793,8 @@ namespace nana { auto i = get(from.cat); size_type n = (from.is_category() ? 1 : from.item + 2); // ?? - if(n <= offs) - { - offs -= n; - } - else + + if (n > offs) { n -=offs; item.cat = from.cat; @@ -1820,6 +1802,8 @@ namespace nana return true; } + offs -= n; + while(i != list_.cbegin()) { --i; @@ -1891,10 +1875,6 @@ namespace nana bool auto_draw{true}; bool checkable{false}; bool if_image{false}; - //unsigned header_size{25}; - //unsigned item_size{24}; - //unsigned text_height{0}; - //unsigned suspension_width{0}; ::nana::listbox::export_options def_exp_options; @@ -1909,8 +1889,15 @@ namespace nana struct scroll_part { - static const unsigned scale = 16; // ? + static const unsigned scale = 16; // ? +#ifdef USE_OFFSET_X int offset_x; +#else + unsigned x_offset() const + { + return (h.empty() ? 0 : h.value()); + } +#endif index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. // need to be abs??? to see the same item after sort() ?? nana::scroll v; @@ -1933,7 +1920,9 @@ namespace nana essence_t() { +#ifdef USE_OFFSET_X scroll.offset_x = 0; +#endif pointer_where.first = parts::unknown; lister.fetch_ordering_comparer = std::bind(&es_header::fetch_comp, &header, std::placeholders::_1); } @@ -2065,16 +2054,26 @@ namespace nana return; const auto header_px = header.pixels(); - const unsigned window_px = graph_size.width - (4 + (scroll.v.empty() ? 0 : scroll.scale - 1)); + const unsigned window_px = graph_size.width - ext_px; +#ifdef USE_OFFSET_X if (header_px < window_px + scroll.offset_x) { scroll.offset_x = header_px - window_px; } +#else + auto offset_x = scroll.x_offset(); + if (header_px < window_px + offset_x) + offset_x = header_px - window_px; +#endif scroll.h.amount(header_px); scroll.h.range(window_px); +#ifdef USE_OFFSET_X scroll.h.value(scroll.offset_x); +#else + scroll.h.value(offset_x); +#endif scroll.h.step(graph->text_extent_size(L"W").width); } @@ -2114,8 +2113,8 @@ namespace nana window wd = lister.wd_ptr()->handle(); //H scroll enabled - bool h = (header_s + 4 > sz.width ); // 4? - unsigned head_scroll = 2 + header_visible_px() + (h ? scroll.scale : 0); // 2? + bool h = (header_s + 4 > sz.width ); // 4px = left and right borders(2px) + left and right gaps(2px) + unsigned head_scroll = 2 + header_visible_px() + (h ? scroll.scale : 0); // 2px left and right gaps(2px) unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0 ; size_type screen_number = (lister_s / scheme_ptr->item_height); @@ -2123,10 +2122,10 @@ namespace nana bool v = (lister.the_number_of_expanded() > screen_number); if(v == true && h == false) - h = ( (header_s + 2 + scroll.scale ) > sz.width); // 2? + h = ( (header_s + 2 + scroll.scale ) > sz.width); - unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2? - unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2? + unsigned width = sz.width - 2 - (v ? scroll.scale : 0); + unsigned height = sz.height - 2 - (h ? scroll.scale : 0); //event hander for scrollbars auto evt_fn = [this](const arg_scroll& arg) @@ -2141,15 +2140,17 @@ namespace nana set_scroll_y_dpl(item); } +#ifdef USE_OFFSET_X else scroll.offset_x = static_cast(scroll.h.value()); +#endif API::refresh_window(this->lister.wd_ptr()->handle()); }; if(h) { - rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); // -? + rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); if(scroll.h.empty()) { scroll.h.create(wd, r); @@ -2164,7 +2165,7 @@ namespace nana if(v) { - rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); // -? + rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); if(scroll.v.empty()) { scroll.v.create(wd, r); @@ -2180,17 +2181,19 @@ namespace nana scroll.v.close(); set_scroll_y_dpl({0,0}); +#ifdef USE_OFFSET_X nana::rectangle r; if(rect_header(r)) { if(header_s > r.width) { - if(header_s < r.width - scroll.offset_x) + if((header_s - scroll.offset_x) < r.width) scroll.offset_x = header_s - r.width; } else scroll.offset_x = 0; } +#endif } adjust_scroll_value(); } @@ -2216,7 +2219,11 @@ namespace nana int item_xpos(const nana::rectangle& r) const { auto seq = header_seq(r.width); +#ifdef USE_OFFSET_X return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0); +#else + return (seq.empty() ? 0 : header.item_pos(seq[0], nullptr) - static_cast(scroll.x_offset()) + r.x); +#endif } std::pair where(int x, int y) @@ -2228,8 +2235,11 @@ namespace nana if(header.visible() && y < static_cast(scheme_ptr->header_height + 1)) { /// we are in the header - +#ifdef USE_OFFSET_X x -= (2 - scroll.offset_x); +#else + x += static_cast(scroll.x_offset()) - 2; +#endif new_where.first = parts::header; new_where.second = header.item_by_x(x); } @@ -2257,9 +2267,9 @@ namespace nana return new_where; } - bool calc_where(int x, int y) + bool calc_where(const point& pos) { - std::pair< parts, size_t > new_where=where(x,y); + auto new_where = where(pos.x, pos.y); if (new_where == pointer_where) return false; @@ -2270,7 +2280,11 @@ namespace nana void widget_to_header(nana::point& pos) { --pos.y; - pos.x += (scroll.offset_x - 2); // why not: pos.x -= (scroll.offset_x + 1); +#ifdef USE_OFFSET_X + pos.x += (scroll.offset_x - 2); +#else + pos.x += static_cast(scroll.x_offset()) - 2; +#endif } bool rect_header(nana::rectangle& r) const @@ -2337,9 +2351,9 @@ namespace nana index_pair target; if(upwards == false) - lister.forward(scroll.offset_y_dpl, 3, target); // scheme ?? + lister.forward(scroll.offset_y_dpl, 1, target); else - lister.backward(scroll.offset_y_dpl, 3, target); + lister.backward(scroll.offset_y_dpl, 1, target); if (target == scroll.offset_y_dpl) return false; @@ -2351,7 +2365,12 @@ namespace nana std::vector header_seq(unsigned lister_w)const { std::vector seqs; + +#ifdef USE_OFFSET_X int x = -(scroll.offset_x); +#else + int x = -static_cast(scroll.x_offset()); +#endif for (const auto& hd : header.cont()) { if (false == hd.visible) continue; @@ -2704,7 +2723,11 @@ namespace nana { if(essence_->ptr_state == item_state::highlighted) { +#ifdef USE_OFFSET_X x -= (r.x - essence_->scroll.offset_x); +#else + x -= r.x - static_cast(essence_->scroll.x_offset()); +#endif for(auto & hd : essence_->header.cont()) // in current order { if(hd.visible) @@ -2720,7 +2743,7 @@ namespace nana } } else if(essence_->ptr_state == item_state::normal) - item_spliter_ = npos; + item_spliter_ = npos; return false; } @@ -2757,13 +2780,16 @@ namespace nana auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); if(item.pixels != new_w) { + essence_->header.item_width(item_spliter_, (new_w < ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) ? ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) : new_w) ); +#ifdef USE_OFFSET_X new_w = essence_->header.pixels(); if(new_w < (rect.width + essence_->scroll.offset_x)) essence_->scroll.offset_x = (new_w > rect.width ? new_w - rect.width : 0); +#endif essence_->adjust_scroll_life(); return 2; @@ -2786,7 +2812,11 @@ namespace nana const unsigned height = r.height - 1; const int bottom_y = r.bottom() - 2; +#ifdef USE_OFFSET_X int x = r.x - essence_->scroll.offset_x; +#else + int x = r.x - static_cast(essence_->scroll.x_offset()); +#endif for (auto & i : essence_->header.cont()) { @@ -2820,10 +2850,18 @@ namespace nana size_type _m_target_strip(int x, const nana::rectangle& rect, size_type grab, bool& place_front) { //convert x to header logic coordinate. +#ifdef USE_OFFSET_X if(x < essence_->scroll.offset_x) x = essence_->scroll.offset_x; else if(x > essence_->scroll.offset_x + static_cast(rect.width)) x = essence_->scroll.offset_x + static_cast(rect.width); +#else + const int x_offset = static_cast(essence_->scroll.x_offset()); + if (x < x_offset) + x = x_offset; + else if (x > x_offset + static_cast(rect.width)) + x = x_offset + static_cast(rect.width); +#endif size_type i = essence_->header.item_by_x(x); if(i == npos) @@ -2840,8 +2878,13 @@ namespace nana place_front = (x <= (item_x + static_cast(item_pixels / 2))); x = (place_front ? item_x : essence_->header.item_pos(essence_->header.neighbor(i, false), nullptr)); +#ifdef USE_OFFSET_X if(i != npos) essence_->graph->rectangle({ x - essence_->scroll.offset_x + rect.x, rect.y, 2, rect.height }, true, colors::red); +#else + if (npos != i) + essence_->graph->rectangle({x - x_offset + rect.x, rect.y, 2, rect.height}, true, colors::red); +#endif return i; } @@ -2883,7 +2926,12 @@ namespace nana _m_draw_header_item(ext_graph, 0, 0, essence_->scheme_ptr->header_height, txtop, colors::white, item, item_state::floated); int xpos = essence_->header.item_pos(item.index, nullptr) + pos.x - ref_xpos_; + +#ifdef USE_OFFSET_X ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); +#else + ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), point{xpos - static_cast(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5); +#endif } private: @@ -2918,12 +2966,21 @@ namespace nana auto bgcolor = wdptr->bgcolor(); auto fgcolor = wdptr->fgcolor(); - int header_w = essence_->header.pixels(); essence_->graph->palette(false, bgcolor); + +#ifdef USE_OFFSET_X + int header_w = essence_->header.pixels(); if( header_w - essence_->scroll.offset_x < static_cast(rect.width) ) essence_->graph->rectangle(rectangle{ point(rect.x + header_w -essence_->scroll.offset_x, rect.y), size(static_cast(rect.width) + essence_->scroll.offset_x - header_w , rect.height) }, true); +#else + const auto header_w = essence_->header.pixels(); + const auto x_offset = essence_->scroll.x_offset(); + if (header_w < x_offset + rect.width) + essence_->graph->rectangle(rectangle{ point{ rect.x + static_cast(header_w) - static_cast(x_offset), rect.y }, + size{rect.width + x_offset - header_w, rect.height} }, true); +#endif es_lister & lister = essence_->lister; //The Tracker indicates the item where mouse placed. @@ -2992,7 +3049,11 @@ namespace nana state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal); +#ifdef USE_OFFSET_X _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); +#else + _m_draw_categ(*i_categ, rect.x - static_cast(x_offset), y, txtoff, header_w, rect, bgcolor, state); +#endif y += essence_->scheme_ptr->item_height; if(false == i_categ->expand) @@ -3058,7 +3119,11 @@ namespace nana //Draw selecting inner rectangle if (sel && (categ.expand == false)) { +#ifdef USE_OFFSET_X width -= essence_->scroll.offset_x; +#else + width -= essence_->scroll.x_offset(); +#endif _m_draw_border(r.x, y, (r.width < width ? r.width : width)); } } @@ -3095,7 +3160,11 @@ namespace nana bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } +#ifdef USE_OFFSET_X unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.offset_x); +#else + unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.x_offset()); +#endif auto graph = essence_->graph; @@ -3370,7 +3439,6 @@ namespace nana void trigger::attached(widget_reference widget, graph_reference graph) { essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); - essence_->graph = &graph; typeface_changed(graph); @@ -3397,18 +3465,10 @@ namespace nana nana::rectangle r; - //essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); - if (essence_->header.visible() && essence_->rect_header(r)) drawer_header_->draw(r); - - //debug("Header: ", r); - if (essence_->rect_lister(r)) drawer_lister_->draw(r); - - //debug("Lister: ", r); - _m_draw_border(); } @@ -3440,7 +3500,7 @@ namespace nana essence_->rect_header(r); update = drawer_header_->grab_move(r, pos); } - else if(essence_->calc_where(arg.pos.x, arg.pos.y)) + else if(essence_->calc_where(arg.pos)) { essence_->ptr_state = item_state::highlighted; update = 2; @@ -3597,6 +3657,7 @@ namespace nana } } + void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) { using item_state = essence_t::item_state; @@ -3844,7 +3905,8 @@ namespace nana /// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected item_proxy & item_proxy::select(bool s) { - auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat? + //pos_ never represents a category if this item_proxy is available. + auto & m = cat_->items.at(pos_.item); // a ref to the real item if(m.flags.selected == s) return *this; // ignore if no change m.flags.selected = s; // actually change selection @@ -4392,12 +4454,12 @@ namespace nana { } - void arg_category::block_category_change() const noexcept + void arg_listbox_category::block_category_change() const noexcept { block_change_ = true; } - bool arg_category::category_change_blocked() const noexcept + bool arg_listbox_category::category_change_blocked() const noexcept { return block_change_; } @@ -4627,7 +4689,11 @@ namespace nana listbox::columns_indexs listbox::column_from_pos ( const point& pos ) { auto & ess=_m_ess(); +#ifdef USE_OFFSET_X columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); +#else + columns_indexs col = ess.header.item_by_x(pos.x - 2 - static_cast(ess.scroll.x_offset())); +#endif return col; } @@ -4650,11 +4716,10 @@ namespace nana { auto & ess = _m_ess(); ess.lister.clear(cat); - //unsort(); // ?? - // from current display position - // move to the cat self if not in first cat - // move to first item ?? if in first cat + // from current display position + // move to the cat self if not in first cat + // move to first item ?? if in first cat ess.scroll_y_abs(ess.scroll_y_abs()); ess.update(); From be59604a080513d273fcc93c91293b6a2ccf3826 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 13 Jun 2016 06:21:58 +0800 Subject: [PATCH 176/309] listbox header functions are deprecated, use column_interface --- include/nana/gui/widgets/listbox.hpp | 122 ++- source/gui/detail/bedrock_windows.cpp | 2 + source/gui/widgets/listbox.cpp | 891 +++++++++++-------- source/gui/widgets/skeletons/text_editor.cpp | 6 - 4 files changed, 599 insertions(+), 422 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index fcfca488..4e8071a2 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -36,6 +36,42 @@ namespace nana { namespace listbox { + /// An interface of column operations + class column_interface + { + public: + /// Destructor + virtual ~column_interface() = default; + + /// Returns the width of column, in pixel + virtual unsigned width() const noexcept = 0; + + /// Sets width + /** + * @param pixels The pixels of width + */ + virtual void width(unsigned pixels) noexcept = 0; + + /// Automatically adjusted width + /** + * @param minimize The minimized width of column, in pixel + * @param maximize The maximized width of column, in pixel + */ + virtual void width(unsigned minimize, unsigned maximize) = 0; + + /// Sets alignment of column text + /** + * @param align Alignment + */ + virtual void text_align(::nana::align align) noexcept = 0; + + /// Adjusts the width to fit the content + /** + * The priority of max: maximize, ranged width, scheme's max_fit_content. + */ + virtual void fit_content(unsigned maximize = 0) noexcept = 0; + }; + using size_type = std::size_t; using native_string_type = ::nana::detail::native_string_type; @@ -86,9 +122,9 @@ namespace nana } }; - using selection = std::vector; + using index_pairs = ::std::vector; - using inline_notifier_interface = detail::inline_widget_notifier_interface; + using inline_notifier_interface = detail::inline_widget_notifier_interface; struct cell { @@ -96,7 +132,7 @@ namespace nana { ::nana::color bgcolor; ::nana::color fgcolor; - /// ::nana::paint::font font; \todo + format() = default; format(const ::nana::color& bgcolor, const ::nana::color& fgcolor); }; @@ -173,8 +209,6 @@ namespace nana std::size_t pos_{0}; }; - using selection = std::vector; - /// struct essence_t ///@brief: this struct gives many data for listbox, /// the state of the struct does not effect on member funcions, therefore all data members are public. @@ -535,14 +569,18 @@ namespace nana color_proxy item_selected{ static_cast(0xD5EFFC) }; /// \todo how to implement some geometrical parameters ?? - unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this - unsigned min_header_width{ 20 }; ///< def=20 . non counting suspension_width - unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") - unsigned ext_w { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 - unsigned header_height { 25 }; ///< def=25 . header height header_size - unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font - unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex - unsigned item_height { 24 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex + + /// The max column width which is generated by fit_content is allowed. It is ignored when it is 0, or a max value is passed to fit_content. + unsigned max_fit_content{ 0 }; + + unsigned min_column_width{ 20 }; ///< def=20 . non counting suspension_width + + unsigned suspension_width { 8 }; ///< def= . the trigger will set this to the width if ("...") + unsigned text_margin { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 + unsigned header_height { 25 }; ///< def=25 . header height header_size + unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font + unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex + unsigned item_height { 24 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex unsigned header_mouse_spliter_area_before{ 2 }; ///< def=2. But 4 is better... IMO unsigned header_mouse_spliter_area_after { 3 }; ///< def=3. But 4 is better... @@ -614,18 +652,41 @@ the nana::detail::basic_window member pointer scheme public concepts::any_objective { public: + /// An unsigned integral type using size_type = drawerbase::listbox::size_type; + + /// The representation of a category/item using index_pair = drawerbase::listbox::index_pair; + + /// A index_pair package + using index_pairs = drawerbase::listbox::index_pairs; + + /// Iterator to access category using cat_proxy = drawerbase::listbox::cat_proxy; + + /// Iterator to access item using item_proxy = drawerbase::listbox::item_proxy; - using selection = drawerbase::listbox::selection; /// #include +#include //use std::cerr + #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x020A #endif diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 9a03dc3d..a9d1ba09 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -325,253 +325,6 @@ namespace nana } //end class iresolver/oresolver - /// Essence of the columns Header - class es_header - { - public: - - struct column_t - { - native_string_type text; ///< "text" header of the column number "index" with weigth "pixels" - unsigned pixels; ///< width - bool visible{true}; - size_type index; - std::function weak_ordering; - - column_t() = default; - column_t(native_string_type&& txt, unsigned px, size_type pos) - : text(std::move(txt)), pixels(px), index(pos) - {} - /// \todo introduce default cell format - }; - - using container = std::vector ; - - export_options::columns_indexs all_headers(bool only_visibles) const - { - export_options::columns_indexs idx; - for(const auto &header : cont()) - { - if(header.visible || !only_visibles) - idx.push_back(header.index); - } - return idx; - } - - std::string to_string(const export_options& exp_opt) const - { - std::string head_str; - bool first{true}; - for( size_type idx{}; idx fetch_comp(std::size_t pos) const - { - try - { - return column_ref(pos).weak_ordering; - } - catch (...) - { - } - return{}; - } - - size_type create(native_string_type&& text, unsigned pixels) - { - cont_.emplace_back(std::move(text), pixels, static_cast(cont_.size())); - return cont_.back().index; - } - - void item_width(size_type pos, unsigned width) ///< set the column width - { - column(pos).pixels = width; - } - - unsigned item_width(size_type pos) const throw() - { - try - { - return column_ref(pos).pixels; - } - catch (...) - { - } - return 0; - } - - unsigned pixels() const ///< the visible width of the whole header - { - unsigned pixels = 0; - for(auto & m : cont_) - { - if(m.visible) - pixels += m.pixels; - } - return pixels; - } - - const container& cont() const - { - return cont_; - } - - /// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization. - column_t& column(size_type pos) - { - for(auto & m : cont_) - { - if(m.index == pos) - return m; - } - throw std::out_of_range("Nana.GUI.Listbox: invalid header index."); - } - const column_t& column_ref(size_type pos) const - { - for(const auto & m : cont_) - { - if(m.index == pos) - return m; - } - throw std::out_of_range("Nana.GUI.Listbox: invalid header index."); - } - - /// return the original index of the current column at x . - size_type item_by_x(int x) const - { - for(const auto & col : cont_) // in current order - { - if(x < static_cast(col.pixels)) - return col.index; - if (col.visible) - x -= col.pixels; - } - return npos; - } - - /// return the left position and width (in variable *pixels) of the column originaly at index "pos" . - int item_pos(size_type pos, unsigned * pixels) const - { - int left = 0; - for (auto & m : cont_) - { - if (m.index == pos) - { - if (pixels) - *pixels = m.pixels; - break; - } - - if (m.visible) - left += m.pixels; - } - return left; - } - - /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" - size_type neighbor(size_type index, bool front) const - { - size_type n = npos; - for(auto i = cont_.cbegin(); i != cont_.cend(); ++i) // in current order - { - if(i->index == index) - { - if(front) return n; - for(++i; i != cont_.cend(); ++i) - { - if(i->visible) return i->index; - } - break; - } - else if(i->visible) - n = i->index; - } - return npos; - } - - /// return the original index of the currently first visible col - size_type begin() const - { - for(const auto & m : cont_) - { - if(m.visible) return m.index; - } - return npos; - } - - /// return the original index of the currently last visible col - size_type last() const - { - for(auto i = cont_.rbegin(); i != cont_.rend(); ++i) - { - if(i->visible) return i->index; - } - return npos; - } - - /// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index - void move(size_type index, size_type to, bool front) throw() - { - if ((index == to) || (index >= cont_.size()) || (to >= cont_.size())) - return; - - for (auto i = cont_.begin(); i != cont_.end(); ++i) - { - if (index == i->index) - { - column_t from = std::move(*i); - cont_.erase(i); - - for (auto u = cont_.begin(); u != cont_.end(); ++u) - { - if (to == u->index) - { - cont_.insert(front ? u : ++u, from); - return; - } - } - return; - } - } - } - private: - bool visible_{true}; - bool sortable_{true}; - container cont_; - }; - struct essence_t; struct item_t @@ -586,8 +339,8 @@ namespace nana struct flags_tag { - bool selected :1; - bool checked :1; + bool selected : 1; + bool checked : 1; }flags; mutable std::unique_ptr anyobj; @@ -598,12 +351,12 @@ namespace nana } item_t(const item_t& r) - : cells(r.cells), - bgcolor(r.bgcolor), - fgcolor(r.fgcolor), - img(r.img), - flags(r.flags), - anyobj(r.anyobj ? new nana::any(*r.anyobj) : nullptr) + : cells(r.cells), + bgcolor(r.bgcolor), + fgcolor(r.fgcolor), + img(r.img), + flags(r.flags), + anyobj(r.anyobj ? new nana::any(*r.anyobj) : nullptr) {} item_t(container&& cont) @@ -619,8 +372,8 @@ namespace nana } item_t(std::string&& s, const nana::color& bg, const nana::color& fg) - : bgcolor(bg), - fgcolor(fg) + : bgcolor(bg), + fgcolor(fg) { flags.selected = flags.checked = false; cells.emplace_back(std::move(s)); @@ -655,7 +408,7 @@ namespace nana item_str += cells[exp_opt.columns_order[idx]].text; } - return item_str; + return item_str; } }; @@ -668,7 +421,7 @@ namespace nana native_string_type text; std::vector sorted; container items; - bool expand{true}; + bool expand{ true }; //A cat may have a key object to identify the category std::shared_ptr key_ptr; @@ -692,6 +445,334 @@ namespace nana } }; + using list_category = std::list; + + + /// Essence of the columns Header + class es_header + { + public: + struct column + : public column_interface + { + native_string_type text; + unsigned width_px; + std::pair range_width_px; + bool visible{ true }; + + /// Position of column when it was creating + size_type index; + + nana::align alignment{ nana::align::left }; + + std::function weak_ordering; + + + column() = default; + + + column(const column&) = default; + + column& operator=(const column& other) + { + if (this != &other) + { + text = other.text; + width_px = other.width_px; + range_width_px = other.range_width_px; + visible = other.visible; + index = other.index; + alignment = other.alignment; + weak_ordering = other.weak_ordering; + } + return *this; + + } + + column(column&& other): + text(std::move(other.text)), + width_px(other.width_px), + range_width_px(other.range_width_px), + visible(other.visible), + index(other.index), + alignment(other.alignment), + weak_ordering(weak_ordering), + ess_(other.ess_) + { + } + + column& operator=(column&& other) + { + if (this != &other) + { + text = std::move(other.text); + width_px = other.width_px; + range_width_px = other.range_width_px; + visible = other.visible; + index = other.index; + alignment = other.alignment; + weak_ordering = std::move(other.weak_ordering); + } + return *this; + } + + column(essence_t* ess, native_string_type&& text, unsigned px, size_type pos) : + text(std::move(text)), + width_px(px), + index(pos), + ess_(ess) + { + } + private: + essence_t* const ess_; + public: + //Implementation of column_interface + unsigned width() const noexcept override + { + return width_px; + } + + // Sets the width and overrides the ranged width + void width(unsigned pixels) noexcept override + { + width_px = pixels; + range_width_px.first = range_width_px.second = 0; + } + + void width(unsigned minimize, unsigned maximize) + { + //maximize must be larger than minimize, but minimize == maximize is allowed + if ((minimize >= maximize) && (minimize != 0)) + throw std::invalid_argument("listbox.column.width() minimize must be less than maximize"); + + range_width_px.first = minimize; + range_width_px.second = maximize; + } + + void text_align(::nana::align align) noexcept override + { + alignment = align; + } + + //Definition is provided after essence + void fit_content(unsigned maximize = 100000) noexcept override; + }; + + using container = std::vector; + + export_options::columns_indexs all_headers(bool only_visibles) const + { + export_options::columns_indexs idx; + for(const auto &col : cont()) + { + if(col.visible || !only_visibles) + idx.push_back(col.index); + } + return idx; + } + + std::string to_string(const export_options& exp_opt) const + { + std::string head_str; + bool first{true}; + for( size_type idx{}; idx fetch_comp(std::size_t pos) const + { + try + { + return at(pos).weak_ordering; + } + catch (...) + { + } + return{}; + } + + size_type create(essence_t* ess, native_string_type&& text, unsigned pixels) + { + cont_.emplace_back(ess, std::move(text), pixels, static_cast(cont_.size())); + return cont_.back().index; + } + + unsigned pixels() const ///< the visible width of the whole header + { + unsigned pixels = 0; + for(auto & col : cont_) + { + if (col.visible) + pixels += col.width_px; + } + return pixels; + } + + const container& cont() const + { + return cont_; + } + + /// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization. + column& at(size_type pos) + { + for(auto & m : cont_) + { + if (m.index == pos) + return m; + } + throw std::out_of_range("Nana.GUI.Listbox: invalid header index."); + } + + const column& at(size_type pos) const + { + for(const auto & m : cont_) + { + if (m.index == pos) + return m; + } + throw std::out_of_range("Nana.GUI.Listbox: invalid header index."); + } + + /// Returns the position(original index when it is creating) of the current column at point x + size_type column_from_point(int x) const + { + for (const auto & col : cont_) + { + if (col.visible) + { + x -= static_cast(col.width_px); + continue; + } + + if (x < static_cast(col.width_px)) + return col.index; + } + + return npos; + } + + /// Returns the left point position and width(in variable * pixels) of column originaly at position pos. + int position(size_type pos, unsigned * pixels) const + { + int left = 0; + for (auto & m : cont_) + { + if (m.index == pos) + { + if (pixels) + *pixels = m.width_px; + break; + } + + if (m.visible) + left += m.width_px; + } + return left; + } + + /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" + size_type neighbor(size_type index, bool front) const + { + size_type n = npos; + for(auto i = cont_.cbegin(); i != cont_.cend(); ++i) // in current order + { + if(i->index == index) + { + if(front) return n; + for(++i; i != cont_.cend(); ++i) + { + if(i->visible) return i->index; + } + break; + } + else if(i->visible) + n = i->index; + } + return npos; + } + + /// return the original index of the currently first visible col + size_type begin() const + { + for(const auto & m : cont_) + if(m.visible) return m.index; + + return npos; + } + + /// return the original index of the currently last visible col + size_type last() const + { + for(auto i = cont_.rbegin(); i != cont_.rend(); ++i) + { + if(i->visible) return i->index; + } + return npos; + } + + /// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index + void move(size_type index, size_type to, bool front) throw() + { + if ((index == to) || (index >= cont_.size()) || (to >= cont_.size())) + return; + + for (auto i = cont_.begin(); i != cont_.end(); ++i) + { + if (index == i->index) + { + auto col_from = std::move(*i); + cont_.erase(i); + + for (auto u = cont_.begin(); u != cont_.end(); ++u) + { + if (to == u->index) + { + cont_.insert(front ? u : ++u, col_from); + return; + } + } + return; + } + } + } + private: + bool visible_{true}; + bool sortable_{true}; + container cont_; + }; + class es_lister { public: @@ -738,6 +819,10 @@ namespace nana std::string to_string(const export_options& exp_opt) const; + + // Definition is provided after struct essence_t + unsigned column_content_pixels(size_type pos) const; + /// each sort() ivalidate any existing reference from display position to absolute item, that is after sort() display offset point to different items void sort() { @@ -1251,24 +1336,6 @@ namespace nana } } - selection item_checked() const - { - selection vec; - index_pair id; - for(auto & cat : list_) - { - id.item = 0; - for(auto & m : cat.items) - { - if(m.flags.checked) - vec.push_back(id); - ++id.item; - } - ++id.cat; - } - return vec; - } - void select_range(index_pair fr, index_pair to, bool sel) { if (fr > to) @@ -1283,6 +1350,7 @@ namespace nana if (to.is_item()) item_proxy(ess_, to).select(sel); } + void select_display_range(index_pair fr_abs, index_pair to_dpl, bool sel) { index_pair fr_dpl (fr_abs.cat, this->display_order(fr_abs.cat, fr_abs.item)); @@ -1329,20 +1397,23 @@ namespace nana } /// return absolute positions, no relative to display - void item_selected(selection& vec) const // change to selection item_selected(); + index_pairs pick_items(bool for_selection) const { + index_pairs results; index_pair id; - for(auto & cat : list_) + for (auto & cat : list_) { id.item = 0; - for(auto & m : cat.items) + for (auto & m : cat.items) { - if(m.flags.selected) - vec.push_back(id); // absolute positions, no relative to display + if (for_selection ? m.flags.selected : m.flags.checked) + results.push_back(id); // absolute positions, no relative to display ++id.item; } ++id.cat; } + + return results; } index_pair find_first_selected() @@ -1363,7 +1434,7 @@ namespace nana } /// return absolute positions, no relative to display - bool item_selected_all_checked(selection& vec) const + bool item_selected_all_checked(index_pairs& vec) const { index_pair id; bool ck = true; @@ -2220,9 +2291,9 @@ namespace nana { auto seq = header_seq(r.width); #ifdef USE_OFFSET_X - return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0); + return (seq.size() ? (header.position(seq[0], nullptr) - scroll.offset_x + r.x) : 0); #else - return (seq.empty() ? 0 : header.item_pos(seq[0], nullptr) - static_cast(scroll.x_offset()) + r.x); + return (seq.empty() ? 0 : header.position(seq[0], nullptr) - static_cast(scroll.x_offset()) + r.x); #endif } @@ -2241,7 +2312,7 @@ namespace nana x += static_cast(scroll.x_offset()) - 2; #endif new_where.first = parts::header; - new_where.second = header.item_by_x(x); + new_where.second = header.column_from_point(x); } else { @@ -2252,7 +2323,7 @@ namespace nana nana::rectangle r; if(rect_lister(r)) { - std::size_t top = new_where.second * scheme_ptr->item_height + header_visible_px(); + auto top = new_where.second * scheme_ptr->item_height + header_visible_px(); if(checkarea(item_xpos(r), static_cast(top)).is_hit(x, y)) new_where.first = parts::checker; } @@ -2371,12 +2442,15 @@ namespace nana #else int x = -static_cast(scroll.x_offset()); #endif - for (const auto& hd : header.cont()) + for (const auto& col : header.cont()) { - if (false == hd.visible) continue; - x += static_cast(hd.pixels); + if (!col.visible) + continue; + + x += col.width_px; if (x > 0) - seqs.push_back(hd.index); + seqs.push_back(col.index); + if (x >= static_cast(lister_w)) break; } @@ -2384,28 +2458,6 @@ namespace nana return seqs; } - unsigned auto_width(size_type pos, unsigned max = 100000) - { - max = (std::min)(max, scheme_ptr->max_header_width); - unsigned max_w{ 0 }; - for (const auto &cat : lister.cat_container()) - for (const auto &it : cat.items) - { - if (pos >= it.cells.size()) continue; - // precalcule text geometry - unsigned ts = static_cast (graph->text_extent_size(it.cells[pos].text).width); - if (max_w < ts) - max_w = ts; - } - if (!max_w) return 0; - - unsigned ext_w = scheme_ptr->ext_w; - if (pos == 0 && checkable) // only before the first column (display_order=0 ?) - ext_w += 18; // add to geom. scheme (width of the checker) ?? - header.item_width(pos, (std::min)(max, max_w + ext_w + 1 )); - return max_w; - } - inline_pane * open_inline(pat::abstract_factory* factory, inline_indicator* indicator) { std::unique_ptr pane_ptr; @@ -2436,6 +2488,60 @@ namespace nana } }; + unsigned es_lister::column_content_pixels(size_type pos) const + { + unsigned max_px = 0; + for (auto & cat : list_) + { + for (auto & m : cat.items) + { + if (pos >= m.cells.size()) + continue; + + auto content_px = ess_->graph->text_extent_size(m.cells[pos].text).width; + if (content_px > max_px) + max_px = content_px; + } + } + return max_px; + } + + + void es_header::column::fit_content(unsigned maximize) noexcept + { + auto content_px = ess_->lister.column_content_pixels(index); + + if (0 == content_px) + return; + + content_px += (ess_->scheme_ptr->text_margin * 2); //margin at left/right end. + + if (index == 0 && ess_->checkable) // only before the first column (display_order=0 ?) + content_px += 18; // add to geom. scheme (width of the checker) ?? + + if (range_width_px.first != range_width_px.second) + { + if (range_width_px.first > content_px) + content_px = range_width_px.first; + + //Use range_width_px defined max if maximize is unspecified + if (0 == maximize) + maximize = range_width_px.second; + } + + if (0 == maximize) + maximize = ess_->scheme_ptr->max_fit_content; + + //maximize is only available when it > 0 + if (maximize && (content_px > maximize)) + content_px = maximize; + + width_px = content_px; + + ess_->adjust_scroll_life(); + API::refresh_window(ess_->lister.wd_ptr()->handle()); + } + class inline_indicator : public ::nana::detail::inline_widget_indicator { @@ -2728,17 +2834,19 @@ namespace nana #else x -= r.x - static_cast(essence_->scroll.x_offset()); #endif - for(auto & hd : essence_->header.cont()) // in current order + for(auto & col : essence_->header.cont()) // in current order { - if(hd.visible) + if(col.visible) { - if(( static_cast(hd.pixels) < x + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_before)) - && (x < static_cast(hd.pixels) + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_after)) ) + auto col_pixels = static_cast(col.width_px); + + if ((col_pixels < x + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_before)) + && (x < col_pixels + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_after))) { - item_spliter_ = hd.index; // original index + item_spliter_ = col.index; // original index return true; } - x -= hd.pixels; + x -= col_pixels; } } } @@ -2753,7 +2861,7 @@ namespace nana { ref_xpos_ = pos.x; if(item_spliter_ != npos) // resize header item, not move it - orig_item_width_ = essence_->header.column(item_spliter_).pixels; + orig_item_width_ = essence_->header.at(item_spliter_).width_px; } else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second) essence_->header.move(essence_->pointer_where.second, grab_terminal_.index, grab_terminal_.place_front); @@ -2765,7 +2873,7 @@ namespace nana int grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) - { // move header item, not resize it + { // move column, not resize it draw(rect); // first draw the entery header as it was _m_make_float(rect, pos); // now draw one floating header item @@ -2774,17 +2882,30 @@ namespace nana return 1; } else - { // resize header item, not move it - const auto& item = essence_->header.column(item_spliter_); + { // resize column, not move it + auto& col = essence_->header.at(item_spliter_); + //Resize the item specified by item_spliter_. auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); - if(item.pixels != new_w) - { - essence_->header.item_width(item_spliter_, - (new_w < ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) ? - ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) - : new_w) ); + //Check the minimized and maximized value + if (col.range_width_px.first != col.range_width_px.second) + { + //Column ranged width + if (new_w < col.range_width_px.first) + new_w = col.range_width_px.first; + else if (new_w > col.range_width_px.second) + new_w = col.range_width_px.second; + } + else + { + //Default scheme + new_w = (std::max)(new_w, essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_column_width); + } + + if(col.width_px != new_w) + { + col.width_px = new_w; #ifdef USE_OFFSET_X new_w = essence_->header.pixels(); if(new_w < (rect.width + essence_->scroll.offset_x)) @@ -2818,14 +2939,14 @@ namespace nana int x = r.x - static_cast(essence_->scroll.x_offset()); #endif - for (auto & i : essence_->header.cont()) + for (auto & col : essence_->header.cont()) { - if (i.visible) + if (col.visible) { - int next_x = x + static_cast(i.pixels); + int next_x = x + static_cast(col.width_px); if (next_x > r.x) { - _m_draw_header_item(graph, x, r.y, height, text_top, text_color, i, (i.index == essence_->pointer_where.second ? state : item_state::normal)); + _m_draw_header_item(graph, x, r.y, height, text_top, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); graph.line({ next_x - 1, r.y }, { next_x - 1, bottom_y }, _m_border_color()); } @@ -2863,20 +2984,20 @@ namespace nana x = x_offset + static_cast(rect.width); #endif - size_type i = essence_->header.item_by_x(x); + auto i = essence_->header.column_from_point(x); if(i == npos) { - i = (essence_->header.item_pos(grab, nullptr) < x ? essence_->header.last() : essence_->header.begin()); + i = (essence_->header.position(grab, nullptr) < x ? essence_->header.last() : essence_->header.begin()); } if(grab != i) { unsigned item_pixels = 0; - auto item_x = essence_->header.item_pos(i, &item_pixels); + auto item_x = essence_->header.position(i, &item_pixels); //Get the item pos //if mouse pos is at left of an item middle, the pos of itself otherwise the pos of the next. place_front = (x <= (item_x + static_cast(item_pixels / 2))); - x = (place_front ? item_x : essence_->header.item_pos(essence_->header.neighbor(i, false), nullptr)); + x = (place_front ? item_x : essence_->header.position(essence_->header.neighbor(i, false), nullptr)); #ifdef USE_OFFSET_X if(i != npos) @@ -2904,28 +3025,28 @@ namespace nana case item_state::floated: bgcolor = essence_->scheme_ptr->header_floated.get_color(); break; } - graph.gradual_rectangle({ x, y, item.pixels, height }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true); - graph.string({ x + static_cast(essence_->scheme_ptr->ext_w), txtop }, item.text, fgcolor); + graph.gradual_rectangle({ x, y, item.width_px, height }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true); + graph.string({ x + static_cast(essence_->scheme_ptr->text_margin), txtop }, item.text, fgcolor); if(item.index == essence_->lister.sort_index()) { facade arrow("hollow_triangle"); arrow.direction(essence_->lister.sort_reverse() ? ::nana::direction::south : ::nana::direction::north); - arrow.draw(graph, {}, colors::black, { x + (static_cast(item.pixels) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme? + arrow.draw(graph, {}, colors::black, { x + (static_cast(item.width_px) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme? } } void _m_make_float(const nana::rectangle& rect, const nana::point& pos) { - const auto & item = essence_->header.column(essence_->pointer_where.second); + const auto & col = essence_->header.at(essence_->pointer_where.second); - nana::paint::graphics ext_graph({ item.pixels, essence_->scheme_ptr->header_height }); + nana::paint::graphics ext_graph({ col.width_px, essence_->scheme_ptr->header_height }); ext_graph.typeface(essence_->graph->typeface()); int txtop = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; - _m_draw_header_item(ext_graph, 0, 0, essence_->scheme_ptr->header_height, txtop, colors::white, item, item_state::floated); + _m_draw_header_item(ext_graph, 0, 0, essence_->scheme_ptr->header_height, txtop, colors::white, col, item_state::floated); - int xpos = essence_->header.item_pos(item.index, nullptr) + pos.x - ref_xpos_; + auto xpos = essence_->header.position(col.index, nullptr) + pos.x - ref_xpos_; #ifdef USE_OFFSET_X ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); @@ -3177,12 +3298,12 @@ namespace nana for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed { const auto column_pos = seqs[display_order]; - const auto & header = essence_->header.column(column_pos); // deduce the corresponding header which is in a kind of dislay order + const auto & col = essence_->header.at(column_pos); // deduce the corresponding header which is in a kind of dislay order auto it_bgcolor = bgcolor; - if (header.pixels > essence_->scheme_ptr->ext_w ) + if (col.width_px > essence_->scheme_ptr->text_margin) { - int content_pos = essence_->scheme_ptr->ext_w; + int content_pos = essence_->scheme_ptr->text_margin; //Draw the image in the 1st column in display order if (0 == display_order) @@ -3225,7 +3346,7 @@ namespace nana bool draw_column = true; - if ( content_pos < static_cast(header.pixels)) // we have room + if ( content_pos < static_cast(col.width_px)) // we have room { auto inline_wdg = _m_get_inline_pane(cat, column_pos); if (inline_wdg) @@ -3233,7 +3354,7 @@ namespace nana //Make sure the user-define inline widgets in right visible rectangle. rectangle pane_r; auto wdg_x = item_xpos + content_pos; - auto wdg_w = header.pixels - static_cast(content_pos); + auto wdg_w = col.width_px - static_cast(content_pos); bool visible_state = true; if (::nana::overlap(content_r, { wdg_x, y, wdg_w, essence_->scheme_ptr->item_height }, pane_r)) @@ -3298,7 +3419,7 @@ namespace nana if (item_state::highlighted == state) it_bgcolor = it_bgcolor.blend(static_cast(0x99defd), 0.8); - graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->scheme_ptr->item_height }, true, it_bgcolor); + graph->rectangle(rectangle{ item_xpos, y, col.width_px, essence_->scheme_ptr->item_height }, true, it_bgcolor); cell_txtcolor = m_cell.custom_format->fgcolor; } @@ -3307,8 +3428,8 @@ namespace nana { graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text, cell_txtcolor); // draw full text of the cell index (column) - int item_right = item_xpos + static_cast(header.pixels); - int text_right = item_xpos + content_pos + static_cast(ts.width); + int item_right = item_xpos + col.width_px; + int text_right = item_xpos + content_pos + ts.width; int excess = text_right - item_right ; if (excess > 0) // it was an excess { @@ -3334,7 +3455,7 @@ namespace nana } - item_xpos += static_cast(header.pixels); + item_xpos += col.width_px; if (display_order + 1 >= seqs.size() && extreme_text > item_xpos) { graph->rectangle(rectangle(item_xpos , y /*+ 2*/, extreme_text - item_xpos, essence_->scheme_ptr->item_height /*- 4*/), true, item.bgcolor); @@ -3701,16 +3822,25 @@ namespace nana void trigger::dbl_click(graph_reference graph, const arg_mouse&) { - if (essence_->pointer_where.first == essence_t::parts::header) + using parts = essence_t::parts; + + if (parts::header == essence_->pointer_where.first) + { if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) { - //adjust the width of column to its content. - if (essence_->auto_width(drawer_header_->item_spliter() )) - essence_->update(); + //adjust the width of column to fit its content. + auto split_pos = drawer_header_->item_spliter(); + if (split_pos != npos) + { + essence_->header.at(split_pos).fit_content(); + refresh(graph); + API::dev::lazy_refresh(); + } return; } + } - if (essence_->pointer_where.first != essence_t::parts::lister) + if (parts::lister != essence_->pointer_where.first) return; index_pair item_pos; @@ -3767,7 +3897,7 @@ namespace nana break; case L' ': { - selection s; + index_pairs s; bool ck = ! essence_->lister.item_selected_all_checked(s); for(auto i : s) item_proxy(essence_, i).check(ck); @@ -4533,7 +4663,7 @@ namespace nana { internal_scope_guard lock; auto & ess = _m_ess(); - auto pos = ess.header.create(to_nstring(std::move(s)), width); + auto pos = ess.header.create(&ess, to_nstring(std::move(s)), width); ess.update(); return pos; } @@ -4542,31 +4672,11 @@ namespace nana { internal_scope_guard lock; auto & ess = _m_ess(); - auto pos = ess.header.create(to_nstring(std::move(s)), width); + auto pos = ess.header.create(&ess, to_nstring(std::move(s)), width); ess.update(); return pos; } - listbox& listbox::header_width(size_type pos, unsigned pixels) - { - auto & ess = _m_ess(); - ess.header.item_width(pos, pixels); - ess.update(); - return *this; - } - unsigned listbox::auto_width(size_type pos, unsigned max) - { - auto & ess = _m_ess(); - unsigned max_w = ess.auto_width(pos, max); - ess.update(); - return max_w; - } - - unsigned listbox::header_width(size_type pos) const - { - return _m_ess().header.item_width(pos); - } - listbox::cat_proxy listbox::append(std::string s) { internal_scope_guard lock; @@ -4686,15 +4796,14 @@ namespace nana } //Contributed by leobackes(pr#97) - listbox::columns_indexs listbox::column_from_pos ( const point& pos ) + listbox::size_type listbox::column_from_pos ( const point& pos ) { auto & ess=_m_ess(); #ifdef USE_OFFSET_X - columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); + return ess.header.column_from_point(pos.x - 2 - ess.scroll.offset_x); #else - columns_indexs col = ess.header.item_by_x(pos.x - 2 - static_cast(ess.scroll.x_offset())); + return ess.header.column_from_point(pos.x - 2 - static_cast(ess.scroll.x_offset())); #endif - return col; } void listbox::checkable(bool chkable) @@ -4707,9 +4816,9 @@ namespace nana } } - auto listbox::checked() const -> selection + auto listbox::checked() const -> index_pairs { - return _m_ess().lister.item_checked(); + return _m_ess().lister.pick_items(false); } void listbox::clear(size_type cat) @@ -4816,7 +4925,7 @@ namespace nana void listbox::set_sort_compare(size_type col, std::function strick_ordering) { - _m_ess().header.column(col).weak_ordering = std::move(strick_ordering); + _m_ess().header.at(col).weak_ordering = std::move(strick_ordering); } /// sort() and ivalidate any existing reference from display position to absolute item, that is: after sort() display offset point to different items @@ -4841,11 +4950,9 @@ namespace nana return !_m_ess().lister.active_sort(!freeze); } - auto listbox::selected() const -> selection // change to: selection selected(); + auto listbox::selected() const -> index_pairs { - selection s; - _m_ess().lister.item_selected(s); // absolute positions, no relative to display - return std::move(s); + return _m_ess().lister.pick_items(true); // absolute positions, no relative to display } void listbox::show_header(bool sh) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 2993fd2a..32bd6e6a 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -512,12 +512,6 @@ namespace nana{ namespace widgets const wchar_t* begin; const wchar_t* end; unsigned pixels; - /* - text_section() //deprecated - { - throw std::runtime_error("text_section default construction is forbidden."); - } - */ text_section(const wchar_t* ptr, const wchar_t* endptr) : begin(ptr), end(endptr) From cfcb77635043b5d439e87443ab18a9298f220d4b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 13 Jun 2016 06:42:25 +0800 Subject: [PATCH 177/309] use tabs --- include/nana/gui/widgets/listbox.hpp | 90 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 4e8071a2..9e5ebf19 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -256,12 +256,12 @@ namespace nana item_proxy(essence_t*); item_proxy(essence_t*, const index_pair&); - /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() - static item_proxy from_display(essence_t *ess, const index_pair &relative) ; - item_proxy from_display(const index_pair &relative) const; + /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() + static item_proxy from_display(essence_t *ess, const index_pair &relative) ; + item_proxy from_display(const index_pair &relative) const; - /// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort() - index_pair to_display() const; + /// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort() + index_pair to_display() const; bool empty() const; @@ -388,8 +388,8 @@ namespace nana essence_t * _m_ess() const; private: std::vector & _m_cells() const; - nana::any * _m_value(bool alloc_if_empty); - const nana::any * _m_value() const; + nana::any * _m_value(bool alloc_if_empty); + const nana::any * _m_value() const; private: essence_t * ess_; category_t* cat_{nullptr}; @@ -456,11 +456,11 @@ namespace nana /// convert from display order to absolute (find the real item in that display pos) but without check from current active sorting, in fact using just the last sorting !!! size_type index_by_display_order(size_type disp_order) const; - /// find display order for the real item but without check from current active sorting, in fact using just the last sorting !!! - size_type display_order(size_type pos) const; + /// find display order for the real item but without check from current active sorting, in fact using just the last sorting !!! + size_type display_order(size_type pos) const; - /// this cat position - size_type position() const; + /// this cat position + size_type position() const; /// Returns the number of items size_type size() const; @@ -517,30 +517,30 @@ namespace nana } }//end namespace drawerbase - struct arg_listbox - : public event_arg - { - mutable drawerbase::listbox::item_proxy item; - bool selected; - - arg_listbox(const drawerbase::listbox::item_proxy&, bool selected) noexcept; - }; - - /// The event argument type for listbox's category_dbl_click - struct arg_listbox_category + struct arg_listbox : public event_arg { - drawerbase::listbox::cat_proxy category; + mutable drawerbase::listbox::item_proxy item; + bool selected; + + arg_listbox(const drawerbase::listbox::item_proxy&, bool selected) noexcept; + }; + + /// The event argument type for listbox's category_dbl_click + struct arg_listbox_category + : public event_arg + { + drawerbase::listbox::cat_proxy category; /// Block expension/shrink of category - void block_category_change() const noexcept; + void block_category_change() const noexcept; /// Determines whether expension/shrink of category is blocked - bool category_change_blocked() const noexcept; + bool category_change_blocked() const noexcept; arg_listbox_category(const drawerbase::listbox::cat_proxy&) noexcept; - private: - mutable bool block_change_; + private: + mutable bool block_change_; }; namespace drawerbase @@ -557,7 +557,7 @@ namespace nana basic_event selected; /// An event occurs when a listbox category is double clicking. - basic_event category_dbl_click; + basic_event category_dbl_click; }; struct scheme @@ -674,10 +674,10 @@ the nana::detail::basic_window member pointer scheme using oresolver = drawerbase::listbox::oresolver; /// The representation of an item - using cell = drawerbase::listbox::cell; + using cell = drawerbase::listbox::cell; /// The options of exporting items into a string variable - using export_options= drawerbase::listbox::export_options; + using export_options = drawerbase::listbox::export_options; /// The interface for user-defined inline widgets using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface; @@ -760,7 +760,7 @@ the nana::detail::basic_window member pointer scheme bool assoc_ordered(bool); - void auto_draw(bool); ///< Set state: Redraw automatically after an operation + void auto_draw(bool); ///< Set state: Redraw automatically after an operation template void avoid_drawing(Function fn) @@ -782,7 +782,7 @@ the nana::detail::basic_window member pointer scheme void scroll(bool to_bottom, size_type cat_pos = ::nana::npos); void scroll(bool to_bottom, const index_pair& pos); - /// Appends a new column with a header text and the specified width at the end, and return it position + /// Appends a new column with a header text and the specified width at the end, and return it position size_type append_header(std::string text_utf8, unsigned width = 120); size_type append_header(std::wstring text, unsigned width = 120); @@ -805,8 +805,8 @@ the nana::detail::basic_window member pointer scheme /// Returns the number of columns size_type column_size() const; - cat_proxy append(std::string); ///< Appends a new category to the end - cat_proxy append(std::wstring); ///< Appends a new category to the end + cat_proxy append(std::string); ///< Appends a new category to the end + cat_proxy append(std::wstring); ///< Appends a new category to the end void append(std::initializer_list); ///< Appends categories to the end void append(std::initializer_list); ///< Appends categories to the end @@ -831,10 +831,10 @@ the nana::detail::basic_window member pointer scheme index_pair cast(const point & pos) const; /// Returns the column which contains the specified point. - size_type column_from_pos(const point & pos); + size_type column_from_pos(const point & pos); void checkable(bool); - index_pairs checked() const; /// strick_ordering); + void set_sort_compare( size_type col, + std::function strick_ordering); /// sort() and ivalidate any existing reference from display position to absolute item, that is: after sort() display offset point to different items - void sort_col(size_type col, bool reverse = false); + void sort_col(size_type col, bool reverse = false); size_type sort_col() const; - /// potencially ivalidate any existing reference from display position to absolute item, that is: after sort() display offset point to different items - void unsort(); + /// potencially ivalidate any existing reference from display position to absolute item, that is: after sort() display offset point to different items + void unsort(); bool freeze_sort(bool freeze); - index_pairs selected() const; /// Date: Tue, 14 Jun 2016 19:29:48 +0800 Subject: [PATCH 178/309] add visible() to listbox::column_interface --- include/nana/gui/widgets/listbox.hpp | 12 +++++ source/gui/widgets/listbox.cpp | 72 +++++++++++++++++++++------- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 9e5ebf19..44321f4c 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -70,6 +70,18 @@ namespace nana * The priority of max: maximize, ranged width, scheme's max_fit_content. */ virtual void fit_content(unsigned maximize = 0) noexcept = 0; + + /// Determines the visibility state of the column + /** + * @return true if the column is visible, false otherwise + */ + virtual bool visible() const noexcept = 0; + + /// Sets the visibility state of the column + /** + * @param is_visible Indicates whether to show or hide the column + */ + virtual void visible(bool is_visible) noexcept = 0; }; using size_type = std::size_t; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index a9d1ba09..0ff7b0d6 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -458,7 +458,7 @@ namespace nana native_string_type text; unsigned width_px; std::pair range_width_px; - bool visible{ true }; + bool visible_state{ true }; /// Position of column when it was creating size_type index; @@ -480,7 +480,7 @@ namespace nana text = other.text; width_px = other.width_px; range_width_px = other.range_width_px; - visible = other.visible; + visible_state = other.visible_state; index = other.index; alignment = other.alignment; weak_ordering = other.weak_ordering; @@ -493,7 +493,7 @@ namespace nana text(std::move(other.text)), width_px(other.width_px), range_width_px(other.range_width_px), - visible(other.visible), + visible_state(other.visible_state), index(other.index), alignment(other.alignment), weak_ordering(weak_ordering), @@ -508,7 +508,7 @@ namespace nana text = std::move(other.text); width_px = other.width_px; range_width_px = other.range_width_px; - visible = other.visible; + visible_state = other.visible_state; index = other.index; alignment = other.alignment; weak_ordering = std::move(other.weak_ordering); @@ -523,6 +523,9 @@ namespace nana ess_(ess) { } + private: + //The definition is provided after essence_t + void _m_refresh(); private: essence_t* const ess_; public: @@ -537,6 +540,8 @@ namespace nana { width_px = pixels; range_width_px.first = range_width_px.second = 0; + + _m_refresh(); } void width(unsigned minimize, unsigned maximize) @@ -556,6 +561,17 @@ namespace nana //Definition is provided after essence void fit_content(unsigned maximize = 100000) noexcept override; + + bool visible() const noexcept override + { + return visible_state; + } + + void visible(bool is_visible) noexcept override + { + visible_state = is_visible; + _m_refresh(); + } }; using container = std::vector; @@ -565,7 +581,7 @@ namespace nana export_options::columns_indexs idx; for(const auto &col : cont()) { - if(col.visible || !only_visibles) + if(col.visible_state || !only_visibles) idx.push_back(col.index); } return idx; @@ -633,7 +649,7 @@ namespace nana unsigned pixels = 0; for(auto & col : cont_) { - if (col.visible) + if (col.visible_state) pixels += col.width_px; } return pixels; @@ -670,7 +686,7 @@ namespace nana { for (const auto & col : cont_) { - if (col.visible) + if (col.visible_state) { x -= static_cast(col.width_px); continue; @@ -696,7 +712,7 @@ namespace nana break; } - if (m.visible) + if (m.visible_state) left += m.width_px; } return left; @@ -713,11 +729,11 @@ namespace nana if(front) return n; for(++i; i != cont_.cend(); ++i) { - if(i->visible) return i->index; + if(i->visible_state) return i->index; } break; } - else if(i->visible) + else if(i->visible_state) n = i->index; } return npos; @@ -727,7 +743,7 @@ namespace nana size_type begin() const { for(const auto & m : cont_) - if(m.visible) return m.index; + if(m.visible_state) return m.index; return npos; } @@ -737,7 +753,8 @@ namespace nana { for(auto i = cont_.rbegin(); i != cont_.rend(); ++i) { - if(i->visible) return i->index; + if(i->visible_state) + return i->index; } return npos; } @@ -2444,7 +2461,7 @@ namespace nana #endif for (const auto& col : header.cont()) { - if (!col.visible) + if (!col.visible_state) continue; x += col.width_px; @@ -2506,6 +2523,12 @@ namespace nana return max_px; } + //es_header::column member functions + void es_header::column::_m_refresh() + { + ess_->adjust_scroll_life(); + API::refresh_window(ess_->lister.wd_ptr()->handle()); + } void es_header::column::fit_content(unsigned maximize) noexcept { @@ -2538,9 +2561,9 @@ namespace nana width_px = content_px; - ess_->adjust_scroll_life(); - API::refresh_window(ess_->lister.wd_ptr()->handle()); + _m_refresh(); } + //end es_header::column functions class inline_indicator : public ::nana::detail::inline_widget_indicator @@ -2836,7 +2859,7 @@ namespace nana #endif for(auto & col : essence_->header.cont()) // in current order { - if(col.visible) + if(col.visible_state) { auto col_pixels = static_cast(col.width_px); @@ -2941,7 +2964,7 @@ namespace nana for (auto & col : essence_->header.cont()) { - if (col.visible) + if (col.visible_state) { int next_x = x + static_cast(col.width_px); if (next_x > r.x) @@ -4795,6 +4818,21 @@ namespace nana return item_pos; } + auto listbox::column_at(size_type pos) -> column_interface& + { + return _m_ess().header.at(pos); + } + + auto listbox::column_at(size_type pos) const -> const column_interface& + { + return _m_ess().header.at(pos); + } + + auto listbox::column_size() const ->size_type + { + return _m_ess().header.cont().size(); + } + //Contributed by leobackes(pr#97) listbox::size_type listbox::column_from_pos ( const point& pos ) { From a087486452566887fb39ab1cda57a57693fe10e0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 15 Jun 2016 01:17:28 +0800 Subject: [PATCH 179/309] modify listbox's arg_listbox and arg_listbox_category --- include/nana/gui/widgets/listbox.hpp | 27 +++++++--------- source/gui/widgets/listbox.cpp | 46 +++++++++++----------------- 2 files changed, 29 insertions(+), 44 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 44321f4c..4262604f 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -54,10 +54,10 @@ namespace nana /// Automatically adjusted width /** - * @param minimize The minimized width of column, in pixel - * @param maximize The maximized width of column, in pixel + * @param minimum The minimal width of column, in pixel + * @param maximum The maximal width of column, in pixel */ - virtual void width(unsigned minimize, unsigned maximize) = 0; + virtual void width(unsigned minimum, unsigned maximum) = 0; /// Sets alignment of column text /** @@ -67,9 +67,10 @@ namespace nana /// Adjusts the width to fit the content /** - * The priority of max: maximize, ranged width, scheme's max_fit_content. + * The priority of max: maximum, ranged width, scheme's max_fit_content. + * @param maximum Sets the width of column to the maximum if the width of content is larger than maximum */ - virtual void fit_content(unsigned maximize = 0) noexcept = 0; + virtual void fit_content(unsigned maximum = 0) noexcept = 0; /// Determines the visibility state of the column /** @@ -533,26 +534,20 @@ namespace nana : public event_arg { mutable drawerbase::listbox::item_proxy item; - bool selected; - - arg_listbox(const drawerbase::listbox::item_proxy&, bool selected) noexcept; + + arg_listbox(const drawerbase::listbox::item_proxy&) noexcept; }; - /// The event argument type for listbox's category_dbl_click + /// The event parameter type for listbox's category_dbl_click struct arg_listbox_category : public event_arg { drawerbase::listbox::cat_proxy category; - /// Block expension/shrink of category - void block_category_change() const noexcept; - - /// Determines whether expension/shrink of category is blocked - bool category_change_blocked() const noexcept; + /// A flag that indicates whether or not to block expension/shrink of category when it is double clicking. + mutable bool block_operation{ false }; arg_listbox_category(const drawerbase::listbox::cat_proxy&) noexcept; - private: - mutable bool block_change_; }; namespace drawerbase diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 0ff7b0d6..3656d6ff 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -544,14 +544,14 @@ namespace nana _m_refresh(); } - void width(unsigned minimize, unsigned maximize) + void width(unsigned minimum, unsigned maximum) { - //maximize must be larger than minimize, but minimize == maximize is allowed - if ((minimize >= maximize) && (minimize != 0)) - throw std::invalid_argument("listbox.column.width() minimize must be less than maximize"); + //maximum must be larger than minimum, but maximum == 0 is allowed if minimum is 0 + if ((minimum >= maximum) && (minimum != 0)) + throw std::invalid_argument("listbox.column.width() minimum must be less than maximum"); - range_width_px.first = minimize; - range_width_px.second = maximize; + range_width_px.first = minimum; + range_width_px.second = maximum; } void text_align(::nana::align align) noexcept override @@ -1344,7 +1344,7 @@ namespace nana { m.flags.checked = ck; - arg_listbox arg{ item_proxy{ess_, pos}, ck}; + arg_listbox arg{ item_proxy{ess_, pos}}; wd_ptr()->events().checked.emit(arg, wd_ptr()->handle()); } ++pos.item; @@ -1398,7 +1398,7 @@ namespace nana changed = true; m.flags.selected = sel; - arg_listbox arg{ item_proxy(ess_, i), sel }; + arg_listbox arg{ item_proxy(ess_, i) }; wd_ptr()->events().selected.emit(arg, wd_ptr()->handle()); if (m.flags.selected) @@ -1490,7 +1490,7 @@ namespace nana auto do_cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos) { - arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)), false }; + arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)) }; if (for_selection) { m.flags.selected = false; @@ -1573,7 +1573,7 @@ namespace nana auto cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos) { - arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)), false }; + arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)) }; if (for_selection) { m.flags.selected = false; @@ -1678,7 +1678,7 @@ namespace nana { m.flags.checked = ck; - arg_listbox arg{ item_proxy(ess_, index_pair(cat, index)), ck}; + arg_listbox arg{ item_proxy(ess_, index_pair(cat, index)) }; wd_ptr()->events().checked.emit(arg, widget_->handle()); changed = true; @@ -3749,7 +3749,7 @@ namespace nana { item_ptr->flags.selected = sel; - arg_listbox arg{ item_proxy{ essence_, abs_item_pos }, sel }; + arg_listbox arg{ item_proxy{ essence_, abs_item_pos } }; lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle()); if (item_ptr->flags.selected) @@ -3771,7 +3771,7 @@ namespace nana item_ptr->flags.checked = ! item_ptr->flags.checked; index_pair abs_pos{ item_pos.cat, lister.absolute(item_pos) }; - arg_listbox arg{ item_proxy{ essence_, abs_pos }, item_ptr->flags.checked }; + arg_listbox arg{ item_proxy{ essence_, abs_pos } }; lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle()); if (item_ptr->flags.checked) @@ -4043,7 +4043,7 @@ namespace nana if(m.flags.checked != ck) { m.flags.checked = ck; - arg_listbox arg{*this, ck}; + arg_listbox arg{*this}; ess_->lister.wd_ptr()->events().checked.emit(arg, ess_->lister.wd_ptr()->handle()); ess_->update(); } @@ -4063,7 +4063,7 @@ namespace nana if(m.flags.selected == s) return *this; // ignore if no change m.flags.selected = s; // actually change selection - arg_listbox arg{*this, s}; + arg_listbox arg{*this}; ess_->lister.wd_ptr()->events().selected.emit(arg, ess_->lister.wd_ptr()->handle()); if (m.flags.selected) @@ -4594,8 +4594,8 @@ namespace nana } }//end namespace drawerbase - arg_listbox::arg_listbox(const drawerbase::listbox::item_proxy& m, bool selected) noexcept - : item(m), selected(selected) + arg_listbox::arg_listbox(const drawerbase::listbox::item_proxy& m) noexcept + : item(m) { } @@ -4603,20 +4603,10 @@ namespace nana //Implementation of arg_listbox_category //Contributed by leobackes(pr#97) arg_listbox_category::arg_listbox_category(const nana::drawerbase::listbox::cat_proxy& cat) noexcept - : category(cat), block_change_(false) + : category(cat) { } - void arg_listbox_category::block_category_change() const noexcept - { - block_change_ = true; - } - - bool arg_listbox_category::category_change_blocked() const noexcept - { - return block_change_; - } - //class listbox From 4cda75f20da111cef1e59de48b8b1ede470d93b5 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 15 Jun 2016 01:19:16 +0800 Subject: [PATCH 180/309] a compiler error of arg_listbox_category::block_operation --- source/gui/widgets/listbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3656d6ff..f01c3e90 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3878,7 +3878,7 @@ namespace nana arg_listbox_category arg_cat(cat_proxy(essence_, item_pos.cat)); lister.wd_ptr()->events().category_dbl_click.emit(arg_cat, lister.wd_ptr()->handle()); - if (!arg_cat.category_change_blocked()) + if (!arg_cat.block_operation) { bool do_expand = (lister.expand(item_pos.cat) == false); lister.expand(item_pos.cat, do_expand); From dfc39fdb812376213d430f6f1a07e6b9fae773b6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 17 Jun 2016 02:41:09 +0800 Subject: [PATCH 181/309] fix a bug of listbox's header column_from_point --- source/gui/widgets/listbox.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index f01c3e90..ced6fe24 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -688,14 +688,13 @@ namespace nana { if (col.visible_state) { + if (x < static_cast(col.width_px)) + return col.index; + x -= static_cast(col.width_px); continue; } - - if (x < static_cast(col.width_px)) - return col.index; } - return npos; } From fe76a303d84173aa93c136abc8296bf29132cf3c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 17 Jun 2016 02:43:40 +0800 Subject: [PATCH 182/309] add refresh to listbox column operations --- source/gui/widgets/listbox.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index ced6fe24..1726c2b3 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -552,11 +552,18 @@ namespace nana range_width_px.first = minimum; range_width_px.second = maximum; + + if (width_px < range_width_px.first || range_width_px.second > width_px) + _m_refresh(); } void text_align(::nana::align align) noexcept override { - alignment = align; + if (alignment != align) + { + alignment = align; + _m_refresh(); + } } //Definition is provided after essence From ac477e7a85201f6ad67cf546bbd1e664509c4fb8 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 17 Jun 2016 02:50:02 +0800 Subject: [PATCH 183/309] eliminate the dependence on listbox essence's graph --- source/gui/widgets/listbox.cpp | 51 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 1726c2b3..b4daff77 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2898,17 +2898,14 @@ namespace nana //grab_move /// @brief draw when an item is grabbing. - /// @return 0 = no graphics changed, 1 = just update, 2 = refresh - int grab_move(const nana::rectangle& rect, const nana::point& pos) + /// @return true if refresh is needed, false otherwise + bool grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) { // move column, not resize it - draw(rect); // first draw the entery header as it was - _m_make_float(rect, pos); // now draw one floating header item - - //Draw the target strip - grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front); - return 1; + options_.grab_column = true; + options_.grab_column_position = pos; + return true; } else { // resize column, not move it @@ -2942,16 +2939,14 @@ namespace nana #endif essence_->adjust_scroll_life(); - return 2; + return true; } } - return 0; + return false; } - void draw(const nana::rectangle& r) + void draw(graph_reference graph, const nana::rectangle& r) { - graph_reference graph = *(essence_->graph); - int text_top = (r.height - essence_->scheme_ptr->text_height) / 2 + r.y; auto text_color = essence_->lister.wd_ptr()->fgcolor(); @@ -2989,7 +2984,17 @@ namespace nana graph.rectangle({ x, r.y, static_cast(r.right() - x), height }, true, essence_->scheme_ptr->header_bgcolor); const int y = r.y + r.height - 1; - essence_->graph->line({ r.x, y }, { r.x + static_cast(r.width), y }, _m_border_color()); + graph.line({ r.x, y }, { r.x + static_cast(r.width), y }, _m_border_color()); + + if (options_.grab_column) + { + _m_make_float(r, options_.grab_column_position); // now draw one floating header item + + //Draw the target strip + grab_terminal_.index = _m_target_strip(options_.grab_column_position.x, r, essence_->pointer_where.second, grab_terminal_.place_front); + + options_.grab_column = false; + } } private: ::nana::color _m_border_color() const @@ -3085,6 +3090,7 @@ namespace nana } private: + essence_t * essence_; int ref_xpos_; unsigned orig_item_width_; size_type item_spliter_{npos}; @@ -3093,7 +3099,12 @@ namespace nana size_type index; bool place_front; }grab_terminal_; - essence_t * essence_; + + struct options + { + bool grab_column{ false }; + point grab_column_position; + }options_; }; class drawer_lister_impl @@ -3608,7 +3619,7 @@ namespace nana essence_->scheme_ptr->suspension_width = graph.text_extent_size("...").width; } - void trigger::refresh(graph_reference) + void trigger::refresh(graph_reference graph) { if (API::is_destroying(essence_->lister.wd_ptr()->handle())) return; @@ -3616,7 +3627,7 @@ namespace nana nana::rectangle r; if (essence_->header.visible() && essence_->rect_header(r)) - drawer_header_->draw(r); + drawer_header_->draw(graph, r); if (essence_->rect_lister(r)) drawer_lister_->draw(r); _m_draw_border(); @@ -3648,7 +3659,7 @@ namespace nana nana::rectangle r; essence_->rect_header(r); - update = drawer_header_->grab_move(r, pos); + update = (drawer_header_->grab_move(r, pos) ? 2 : 0); } else if(essence_->calc_where(arg.pos)) { @@ -3705,7 +3716,7 @@ namespace nana } } - void trigger::mouse_down(graph_reference, const arg_mouse& arg) + void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) { using item_state = essence_t::item_state; using parts = essence_t::parts; @@ -3717,7 +3728,7 @@ namespace nana nana::rectangle r; if(essence_->rect_header(r)) { - drawer_header_->draw(r); + drawer_header_->draw(graph, r); update = true; } } From fe8819529cf305dc1186d00376e8a89d665ef96d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 18 Jun 2016 06:38:57 +0800 Subject: [PATCH 184/309] code refine --- include/nana/gui/widgets/listbox.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 4262604f..699aec19 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -588,8 +588,8 @@ namespace nana unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex unsigned item_height { 24 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex - unsigned header_mouse_spliter_area_before{ 2 }; ///< def=2. But 4 is better... IMO - unsigned header_mouse_spliter_area_after { 3 }; ///< def=3. But 4 is better... + unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO + unsigned header_splitter_area_after { 3 }; ///< def=3. But 4 is better... //void debug_print(const std::string &msg); From 5eba74fe0a3c50265fbc306da45719db7454a790 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 18 Jun 2016 06:40:20 +0800 Subject: [PATCH 185/309] code refine --- source/gui/widgets/listbox.cpp | 85 +++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index b4daff77..2057b1ac 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2843,18 +2843,18 @@ namespace nana drawer_header_impl(essence_t* es): essence_(es){} - size_type item_spliter() const + size_type splitter() const { - return item_spliter_; + return grabs_.splitter; } - void cancel_spliter() + void cancel_splitter() { - item_spliter_ = npos; + grabs_.splitter = npos; } - /// return true an set member item_spliter_ if x is in the spliter area after that header item (column) - bool mouse_spliter(const nana::rectangle& r, int x) + // Detects a header spliter, return true if x is in the splitter area after that header item (column) + bool detect_splitter(const nana::rectangle& r, int x) { if(essence_->ptr_state == item_state::highlighted) { @@ -2869,10 +2869,10 @@ namespace nana { auto col_pixels = static_cast(col.width_px); - if ((col_pixels < x + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_before)) - && (x < col_pixels + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_after))) + if ((col_pixels < x + static_cast(essence_->scheme_ptr->header_splitter_area_before)) + && (x < col_pixels + static_cast(essence_->scheme_ptr->header_splitter_area_after))) { - item_spliter_ = col.index; // original index + grabs_.splitter = col.index; // original index return true; } x -= col_pixels; @@ -2880,7 +2880,7 @@ namespace nana } } else if(essence_->ptr_state == item_state::normal) - item_spliter_ = npos; + grabs_.splitter = npos; return false; } @@ -2888,9 +2888,9 @@ namespace nana { if(is_grab) { - ref_xpos_ = pos.x; - if(item_spliter_ != npos) // resize header item, not move it - orig_item_width_ = essence_->header.at(item_spliter_).width_px; + grabs_.start_pos = pos.x; + if(grabs_.splitter != npos) // resize header item, not move it + grabs_.item_width = essence_->header.at(grabs_.splitter).width_px; } else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second) essence_->header.move(essence_->pointer_where.second, grab_terminal_.index, grab_terminal_.place_front); @@ -2901,7 +2901,7 @@ namespace nana /// @return true if refresh is needed, false otherwise bool grab_move(const nana::rectangle& rect, const nana::point& pos) { - if(item_spliter_ == npos) + if(npos == grabs_.splitter) { // move column, not resize it options_.grab_column = true; options_.grab_column_position = pos; @@ -2909,10 +2909,10 @@ namespace nana } else { // resize column, not move it - auto& col = essence_->header.at(item_spliter_); + auto& col = essence_->header.at(grabs_.splitter); //Resize the item specified by item_spliter_. - auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); + auto new_w = grabs_.item_width - (grabs_.start_pos - pos.x); //Check the minimized and maximized value if (col.range_width_px.first != col.range_width_px.second) @@ -2952,7 +2952,7 @@ namespace nana auto state = item_state::normal; //check whether grabing an item, if item_spliter_ != npos, that indicates the grab item is a spliter. - if (essence_->pointer_where.first == parts::header && (item_spliter_ == npos)) + if ((parts::header == essence_->pointer_where.first) && (npos == grabs_.splitter)) state = essence_->ptr_state; const unsigned height = r.height - 1; @@ -3091,9 +3091,15 @@ namespace nana private: essence_t * essence_; - int ref_xpos_; - unsigned orig_item_width_; - size_type item_spliter_{npos}; + + struct grab_variables + { + int start_pos{ npos }; + unsigned item_width; + + size_type splitter{ npos }; + }grabs_; + struct grab_terminal { size_type index; @@ -3637,18 +3643,22 @@ namespace nana { using item_state = essence_t::item_state; using parts = essence_t::parts; - int update = 0; //0 = nothing, 1 = update, 2 = refresh + + bool need_refresh = false; + if(essence_->ptr_state == item_state::pressed) { if(essence_->pointer_where.first == parts::header) - { // moving a pressed header : grab it (or split-resize?) + { // moving a pressed header : grab it essence_->ptr_state = item_state::grabbed; nana::point pos = arg.pos; essence_->widget_to_header(pos); + + //Start to move a header column or resize a header column(depends on item_spliter_) drawer_header_->grab(pos, true); essence_->lister.wd_ptr()->set_capture(true); - update = 2; //0 = nothing, 1 = update, 2 = refresh + need_refresh = true; } } @@ -3659,42 +3669,41 @@ namespace nana nana::rectangle r; essence_->rect_header(r); - update = (drawer_header_->grab_move(r, pos) ? 2 : 0); + need_refresh = drawer_header_->grab_move(r, pos); } else if(essence_->calc_where(arg.pos)) { essence_->ptr_state = item_state::highlighted; - update = 2; + need_refresh = true; } - bool set_spliter = false; + bool set_splitter = false; if(essence_->pointer_where.first == parts::header) { nana::rectangle r; if(essence_->rect_header(r)) { - if(drawer_header_->mouse_spliter(r, arg.pos.x)) + if(drawer_header_->detect_splitter(r, arg.pos.x)) { - set_spliter = true; + set_splitter = true; essence_->lister.wd_ptr()->cursor(cursor::size_we); } } } - if(set_spliter == false && essence_->ptr_state != item_state::grabbed) + + if((!set_splitter) && (essence_->ptr_state != item_state::grabbed)) { - if((drawer_header_->item_spliter() != npos) || (essence_->lister.wd_ptr()->cursor() == cursor::size_we)) + if((drawer_header_->splitter() != npos) || (essence_->lister.wd_ptr()->cursor() == cursor::size_we)) { essence_->lister.wd_ptr()->cursor(cursor::arrow); - drawer_header_->cancel_spliter(); - update = 2; + drawer_header_->cancel_splitter(); + need_refresh = true; } } - if (update) + if (need_refresh) { - if (2 == update) - refresh(graph); - + refresh(graph); API::dev::lazy_refresh(); } } @@ -3722,7 +3731,7 @@ namespace nana using parts = essence_t::parts; bool update = false; auto & ptr_where = essence_->pointer_where; - if((ptr_where.first == parts::header) && (ptr_where.second != npos || (drawer_header_->item_spliter() != npos))) + if((ptr_where.first == parts::header) && (ptr_where.second != npos || (drawer_header_->splitter() != npos))) { essence_->ptr_state = item_state::pressed; nana::rectangle r; @@ -3869,7 +3878,7 @@ namespace nana if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) { //adjust the width of column to fit its content. - auto split_pos = drawer_header_->item_spliter(); + auto split_pos = drawer_header_->splitter(); if (split_pos != npos) { essence_->header.at(split_pos).fit_content(); From 8bcfc825801d03a9356beebfd780f4e400e447a4 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 18 Jun 2016 06:42:42 +0800 Subject: [PATCH 186/309] fix bug that a listbox column can be a negative by moving splitter --- source/gui/widgets/listbox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 2057b1ac..120fa9f4 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2911,8 +2911,10 @@ namespace nana { // resize column, not move it auto& col = essence_->header.at(grabs_.splitter); + auto delta_px = (grabs_.start_pos - pos.x); + //Resize the item specified by item_spliter_. - auto new_w = grabs_.item_width - (grabs_.start_pos - pos.x); + auto new_w = static_cast(grabs_.item_width) > delta_px ? grabs_.item_width - delta_px : 0; //Check the minimized and maximized value if (col.range_width_px.first != col.range_width_px.second) From 58d517d166eb2f6584ab1f5c14f71e62cafec3ef Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 18 Jun 2016 07:23:01 +0800 Subject: [PATCH 187/309] add a new helper class text_aligner --- include/nana/paint/text_renderer.hpp | 31 +++++++++- source/paint/text_renderer.cpp | 92 ++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/include/nana/paint/text_renderer.hpp b/include/nana/paint/text_renderer.hpp index 7234c57c..96fbbfdb 100644 --- a/include/nana/paint/text_renderer.hpp +++ b/include/nana/paint/text_renderer.hpp @@ -9,7 +9,7 @@ namespace nana class text_renderer { public: - typedef graphics & graph_reference; + using graph_reference = graphics &; text_renderer(graph_reference graph, align = align::left); @@ -22,6 +22,35 @@ namespace nana graph_reference graph_; align text_align_; }; + + /// Draw aligned string + class aligner + { + public: + using graph_reference = graphics&; + + /// Constructor + /** + * @param graph Reference to a graphics object + * @param text_align Alignment of text + * @param text_align_if_too_long Alignment of text if the pixels of string is larger than text area + */ + aligner(graph_reference graph, align text_align = align::left); + aligner(graph_reference graph, align text_align, align text_align_if_too_long); + + /// Draws a text with specified text alignment. + /** + * @param text Text to draw + * @param pos Postion where the text to draw + * @param width The width of text area. If the pixels of text is larger than this parameter, it draws ellipsis + */ + void draw(const std::string& text, point pos, unsigned width); + void draw(const std::wstring& text, point pos, unsigned width); + private: + graph_reference graph_; + align text_align_; + align text_align_ex_; + }; } } diff --git a/source/paint/text_renderer.cpp b/source/paint/text_renderer.cpp index 4acd0f36..1716b34c 100644 --- a/source/paint/text_renderer.cpp +++ b/source/paint/text_renderer.cpp @@ -582,5 +582,97 @@ namespace nana } } //end class text_renderer + + //class aligner + + //Constructor + aligner::aligner(graph_reference graph, align text_align) + : aligner{ graph, text_align, text_align } + {} + + aligner::aligner(graph_reference graph, align text_align, align text_align_ex) : + graph_(graph), + text_align_(text_align), + text_align_ex_(text_align_ex) + {} + + // Draws a text with specified text alignment. + void aligner::draw(const std::string& text, point pos, unsigned width) + { + draw(to_wstring(text), pos, width); + } + + void aligner::draw(const std::wstring& text, point pos, unsigned width) + { + auto text_px = graph_.text_extent_size(text).width; + if (text_px <= width) + { + switch (text_align_) + { + case align::center: + pos.x += static_cast(width - text_px) / 2; + break; + case align::right: + pos.x += static_cast(width - text_px); + default: + break; + } + + graph_.bidi_string(pos, text.c_str(), text.size()); + return; + } + + const auto ellipsis = graph_.text_extent_size("...", 3).width; + + std::unique_ptr pixels(new unsigned[text.size()]); + graph_.glyph_pixels(text.c_str(), text.size(), pixels.get()); + + unsigned substr_len = 0; + unsigned substr_px = 0; + + if (align::right == text_align_ex_) + { + auto end = pixels.get(); + auto p = end + text.size(); + do + { + --p; + if (substr_px + *p + ellipsis > width) + { + substr_len = p - pixels.get() + 1; + break; + } + substr_px += *p; + } while (p != end); + + pos.x += static_cast(width - ellipsis - substr_px); + + graph_.string(pos, "..."); + pos.x += ellipsis; + graph_.bidi_string(pos, text.c_str() + substr_len, text.size() - substr_len); + } + else + { + for (auto p = pixels.get(), end = pixels.get() + text.size(); p != end; ++p) + { + if (substr_px + *p + ellipsis > width) + { + substr_len = p - pixels.get(); + break; + } + substr_px += *p; + } + + if (align::center == text_align_ex_) + pos.x += (width - substr_px - ellipsis) / 2; + + graph_.bidi_string(pos, text.c_str(), substr_len); + + pos.x += substr_px; + graph_.string(pos, "..."); + } + } + + //end class string } } From 97952994478ae01ff2695c47c2f5ef76ded691a0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 18 Jun 2016 07:27:26 +0800 Subject: [PATCH 188/309] add text align to listbox --- source/gui/widgets/listbox.cpp | 125 ++++++++++++++++++--------------- 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 120fa9f4..6e7ef9f6 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -26,6 +26,8 @@ #include #include +#include + #include #include #include @@ -2959,34 +2961,47 @@ namespace nana const unsigned height = r.height - 1; const int bottom_y = r.bottom() - 2; + + rectangle column_r{ #ifdef USE_OFFSET_X - int x = r.x - essence_->scroll.offset_x; + r.x - essence_->scroll.offset_x, #else - int x = r.x - static_cast(essence_->scroll.x_offset()); + r.x - static_cast(essence_->scroll.x_offset()), #endif + r.y, + 0, r.height - 1 + }; for (auto & col : essence_->header.cont()) { if (col.visible_state) { - int next_x = x + static_cast(col.width_px); - if (next_x > r.x) + column_r.width = col.width_px; + + const auto right_pos = column_r.right(); + + //Make sure the column is in the display area. + if (right_pos > r.x) { - _m_draw_header_item(graph, x, r.y, height, text_top, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); - graph.line({ next_x - 1, r.y }, { next_x - 1, bottom_y }, _m_border_color()); + _m_draw_header_item(graph, column_r, text_top, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); + graph.line({ right_pos - 1, r.y }, { right_pos - 1, bottom_y }, _m_border_color()); } - x = next_x; - if (x > r.right()) + column_r.x = right_pos; + if (right_pos > r.right()) break; } } - if (x < r.right()) - graph.rectangle({ x, r.y, static_cast(r.right() - x), height }, true, essence_->scheme_ptr->header_bgcolor); + //If the last rendered column's right is less than r.right, fill the spare space. + if (column_r.x < r.right()) + { + column_r.width = (r.right() - column_r.x); + graph.rectangle(column_r, true, essence_->scheme_ptr->header_bgcolor); + } - const int y = r.y + r.height - 1; - graph.line({ r.x, y }, { r.x + static_cast(r.width), y }, _m_border_color()); + const int y = r.bottom() - 1; + graph.line({ r.x, y }, { r.right(), y }, _m_border_color()); if (options_.grab_column) { @@ -3048,8 +3063,7 @@ namespace nana return npos; } - template - void _m_draw_header_item(graph_reference graph, int x, int y, unsigned height, int txtop, const ::nana::color& fgcolor, const Item& item, item_state state) + void _m_draw_header_item(graph_reference graph, const rectangle& column_r, int text_top, const ::nana::color& fgcolor, const es_header::column& column, item_state state) { ::nana::color bgcolor; switch(state) @@ -3061,14 +3075,31 @@ namespace nana case item_state::floated: bgcolor = essence_->scheme_ptr->header_floated.get_color(); break; } - graph.gradual_rectangle({ x, y, item.width_px, height }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true); - graph.string({ x + static_cast(essence_->scheme_ptr->text_margin), txtop }, item.text, fgcolor); + graph.gradual_rectangle(column_r, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true); - if(item.index == essence_->lister.sort_index()) + paint::aligner text_aligner{ graph, column.alignment, column.alignment }; + + auto text_margin = essence_->scheme_ptr->text_margin; + + if (text_margin < column_r.width) + { + graph.palette(true, fgcolor); + + point text_pos{ column_r.x, text_top }; + + if (align::left == column.alignment) + text_pos.x += text_margin; + else if (align::center == column.alignment) + text_margin = 0; + + text_aligner.draw(column.text, text_pos, column_r.width - text_margin); + } + + if (column.index == essence_->lister.sort_index()) { facade arrow("hollow_triangle"); arrow.direction(essence_->lister.sort_reverse() ? ::nana::direction::south : ::nana::direction::north); - arrow.draw(graph, {}, colors::black, { x + (static_cast(item.width_px) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme? + arrow.draw(graph, {}, colors::black, { column_r.x + (static_cast(column_r.width) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme? } } @@ -3079,10 +3110,10 @@ namespace nana nana::paint::graphics ext_graph({ col.width_px, essence_->scheme_ptr->header_height }); ext_graph.typeface(essence_->graph->typeface()); - int txtop = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; - _m_draw_header_item(ext_graph, 0, 0, essence_->scheme_ptr->header_height, txtop, colors::white, col, item_state::floated); + int text_top = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; + _m_draw_header_item(ext_graph, rectangle{ext_graph.size()}, text_top, colors::white, col, item_state::floated); - auto xpos = essence_->header.position(col.index, nullptr) + pos.x - ref_xpos_; + auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos; #ifdef USE_OFFSET_X ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); @@ -3340,8 +3371,7 @@ namespace nana //draw the background for the whole item graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->scheme_ptr->item_height }, true, bgcolor); - int item_xpos = x; - int extreme_text = x; + int column_x = x; for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed { @@ -3351,7 +3381,7 @@ namespace nana if (col.width_px > essence_->scheme_ptr->text_margin) { - int content_pos = essence_->scheme_ptr->text_margin; + int content_pos = 0; //Draw the image in the 1st column in display order if (0 == display_order) @@ -3375,7 +3405,7 @@ namespace nana using state = facade::state; crook_renderer_.check(item.flags.checked ? state::checked : state::unchecked); - crook_renderer_.draw(*graph, bgcolor, fgcolor, essence_->checkarea(item_xpos, y), estate); + crook_renderer_.draw(*graph, bgcolor, fgcolor, essence_->checkarea(column_x, y), estate); } if (essence_->if_image) @@ -3384,7 +3414,7 @@ namespace nana if (item.img) { nana::rectangle img_r(item.img_show_size); - img_r.x = content_pos + item_xpos + (16 - static_cast(item.img_show_size.width)) / 2; // center in 16 - geom scheme? + img_r.x = content_pos + column_x + (16 - static_cast(item.img_show_size.width)) / 2; // center in 16 - geom scheme? img_r.y = y + (static_cast(essence_->scheme_ptr->item_height) - static_cast(item.img_show_size.height)) / 2; // center item.img.stretch(rectangle{ item.img.size() }, *graph, img_r); } @@ -3394,14 +3424,14 @@ namespace nana bool draw_column = true; - if ( content_pos < static_cast(col.width_px)) // we have room + if ( content_pos + essence_->scheme_ptr->text_margin < static_cast(col.width_px)) // we have room { auto inline_wdg = _m_get_inline_pane(cat, column_pos); if (inline_wdg) { //Make sure the user-define inline widgets in right visible rectangle. rectangle pane_r; - auto wdg_x = item_xpos + content_pos; + auto wdg_x = column_x + content_pos; auto wdg_w = col.width_px - static_cast(content_pos); bool visible_state = true; @@ -3467,47 +3497,32 @@ namespace nana if (item_state::highlighted == state) it_bgcolor = it_bgcolor.blend(static_cast(0x99defd), 0.8); - graph->rectangle(rectangle{ item_xpos, y, col.width_px, essence_->scheme_ptr->item_height }, true, it_bgcolor); + graph->rectangle(rectangle{ column_x, y, col.width_px, essence_->scheme_ptr->item_height }, true, it_bgcolor); cell_txtcolor = m_cell.custom_format->fgcolor; } if (draw_column) { - graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text, cell_txtcolor); // draw full text of the cell index (column) + paint::aligner text_aligner{*graph, col.alignment}; - int item_right = item_xpos + col.width_px; - int text_right = item_xpos + content_pos + ts.width; - int excess = text_right - item_right ; - if (excess > 0) // it was an excess - { - //The text is painted over the next subitem // here beging the ... - int xpos = item_right - static_cast(essence_->scheme_ptr->suspension_width); + unsigned text_margin_right = 0; + if (align::left == col.alignment) + content_pos += essence_->scheme_ptr->text_margin; + else if (align::right == col.alignment) + text_margin_right = essence_->scheme_ptr->text_margin; + - // litter rect with the item bg end ... - graph->rectangle(rectangle{ xpos, y /*+ 2*/, essence_->scheme_ptr->suspension_width, essence_->scheme_ptr->item_height /*- 4*/ }, true, it_bgcolor); - graph->string(point{ xpos, y /*+ 2*/ }, L"..."); - - //Erase the part that over the next subitem only if the right of column is less than right of listbox - if (item_right < content_r.right() ) - { - graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over - graph->rectangle(rectangle( item_right, y /*+ 2*/, excess, essence_->scheme_ptr->item_height /*- 4*/ ), true); - } - extreme_text = (std::max)(extreme_text, text_right); - } + graph->palette(true, cell_txtcolor); + text_aligner.draw(m_cell.text, { column_x + content_pos, y + txtoff }, col.width_px - content_pos - text_margin_right); } } - graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast(essence_->scheme_ptr->item_height) - 1 }, static_cast(0xEBF4F9)); + graph->line({ column_x - 1, y }, { column_x - 1, y + static_cast(essence_->scheme_ptr->item_height) - 1 }, static_cast(0xEBF4F9)); } - item_xpos += col.width_px; - if (display_order + 1 >= seqs.size() && extreme_text > item_xpos) - { - graph->rectangle(rectangle(item_xpos , y /*+ 2*/, extreme_text - item_xpos, essence_->scheme_ptr->item_height /*- 4*/), true, item.bgcolor); - } + column_x += col.width_px; } //Draw selecting inner rectangle From 3754d3f51ecebe857ca9696352fbd27651fd5d78 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 19 Jun 2016 15:12:41 +0800 Subject: [PATCH 189/309] implement the listbox ranged column width --- source/gui/widgets/listbox.cpp | 146 +++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 18 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 6e7ef9f6..47d5fe88 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -555,8 +555,16 @@ namespace nana range_width_px.first = minimum; range_width_px.second = maximum; - if (width_px < range_width_px.first || range_width_px.second > width_px) + if (width_px < range_width_px.first) + { + width_px = range_width_px.first; _m_refresh(); + } + else if (range_width_px.second < width_px) + { + width_px = range_width_px.second; + _m_refresh(); + } } void text_align(::nana::align align) noexcept override @@ -664,6 +672,92 @@ namespace nana return pixels; } + /// Calculates the ranged columns to make the whole header fit a specified width + /** + * @param width The width to be fittd + * @return true if the ranged columns is adjusted for the width, false otherwise. + */ + bool calc_ranged_columns(unsigned width) + { + unsigned fixed_px = 0; + unsigned minimal_px = 0; + unsigned maximal_px = 0; + + unsigned ranged_px = 0; + unsigned ranged_count = 0; + + for (auto & col : cont_) + { + if (col.visible_state) + { + if (col.range_width_px.first == col.range_width_px.second) + { + fixed_px += col.width_px; + continue; + } + + minimal_px += col.range_width_px.first; + maximal_px += col.range_width_px.second; + + ranged_px += col.width_px; + ++ranged_count; + } + } + + //Don't calculate the ranged columns if + //There isn't a ranged column while maximal_px == 0, or + //ranged_px + fixed_px == width, or + //the minimal ranged size is larger than width + if ((0 == maximal_px) || (ranged_px + fixed_px == width) || (fixed_px + minimal_px > width)) + return false; + + if (ranged_px + fixed_px > width) + { + auto delta_px = ranged_px + fixed_px - width; + + while (delta_px) + { + for (auto & col : cont_) + { + if (0 == delta_px) + break; + + if (col.visible_state && (col.range_width_px.first < col.range_width_px.second)) + { + if (col.range_width_px.first < col.width_px) + { + --col.width_px; + --delta_px; + } + } + } + } + } + else + { + auto delta_px = width - (ranged_px + fixed_px); + while (delta_px) + { + for (auto & col : cont_) + { + if (0 == delta_px) + break; + + if (col.visible_state && (col.range_width_px.first < col.range_width_px.second)) + { + if (col.width_px < col.range_width_px.second) + { + ++col.width_px; + --delta_px; + } + } + } + } + } + + return true; + } + const container& cont() const { return cont_; @@ -2205,23 +2299,36 @@ namespace nana internal_scope_guard lock; const nana::size sz = graph->size(); - unsigned header_s = header.pixels(); - window wd = lister.wd_ptr()->handle(); + + // Adjust the ranged column assume the vertical scrollbar is enabled. + auto range_adjusted = !this->header.calc_ranged_columns(sz.width - 2 - scroll.scale); + auto columns_pixels = header.pixels(); //H scroll enabled - bool h = (header_s + 4 > sz.width ); // 4px = left and right borders(2px) + left and right gaps(2px) - unsigned head_scroll = 2 + header_visible_px() + (h ? scroll.scale : 0); // 2px left and right gaps(2px) - unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0 ; + //If range_adjusted is true, it indicates no horzontal scroll bar is enabled. + bool enable_horz = (range_adjusted && (columns_pixels + 4 > sz.width)); // 4px = left and right borders(2px) + left and right gaps(2px) + + unsigned head_scroll = 2 + header_visible_px() + (enable_horz ? scroll.scale : 0); // 2px left and right gaps(2px) + unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0; size_type screen_number = (lister_s / scheme_ptr->item_height); //V scroll enabled - bool v = (lister.the_number_of_expanded() > screen_number); + auto enable_vert = (lister.the_number_of_expanded() > screen_number); - if(v == true && h == false) - h = ( (header_s + 2 + scroll.scale ) > sz.width); + if (enable_vert) + { + if (!enable_horz) + enable_horz = ((columns_pixels + 2 + scroll.scale) > sz.width); + } + else if (range_adjusted) + { + //No vertical scrollbar, then re-adjust the range columns for a new width that excludes vert scroll. + this->header.calc_ranged_columns(sz.width - 2); + } - unsigned width = sz.width - 2 - (v ? scroll.scale : 0); - unsigned height = sz.height - 2 - (h ? scroll.scale : 0); + + unsigned width = sz.width - 2 - (enable_vert ? scroll.scale : 0); + unsigned height = sz.height - 2 - (enable_horz ? scroll.scale : 0); //event hander for scrollbars auto evt_fn = [this](const arg_scroll& arg) @@ -2244,13 +2351,16 @@ namespace nana API::refresh_window(this->lister.wd_ptr()->handle()); }; - if(h) + + const auto wd_handle = lister.wd_ptr()->handle(); + + if (enable_horz) { rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); if(scroll.h.empty()) { - scroll.h.create(wd, r); - API::take_active(scroll.h.handle(), false, wd); + scroll.h.create(wd_handle, r); + API::take_active(scroll.h.handle(), false, wd_handle); scroll.h.events().value_changed.connect_unignorable(evt_fn); } else @@ -2259,13 +2369,13 @@ namespace nana else if(!scroll.h.empty()) scroll.h.close(); - if(v) + if (enable_vert) { rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); if(scroll.v.empty()) { - scroll.v.create(wd, r); - API::take_active(scroll.v.handle(), false, wd); + scroll.v.create(wd_handle, r); + API::take_active(scroll.v.handle(), false, wd_handle); scroll.v.events().value_changed.connect_unignorable(evt_fn); } else @@ -3310,7 +3420,7 @@ namespace nana graph->string({ x + 25 + static_cast(text_s), y + txtoff }, str); - if (x + 35 + extend_text_w < x + width) + if (x + 35 + static_cast(extend_text_w) < x + static_cast(width)) { ::nana::point pos{ x + 30 + static_cast(extend_text_w), y + static_cast(essence_->scheme_ptr->item_height) / 2 }; graph->line(pos, { x + static_cast(width)-5, pos.y }, txt_color); From d0d5480a4c4d9d1de56c45d70ec7bb3635db15fc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 19 Jun 2016 16:42:08 +0800 Subject: [PATCH 190/309] improve listbox ranged column width --- source/gui/widgets/listbox.cpp | 139 +++++---------------------------- 1 file changed, 20 insertions(+), 119 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 47d5fe88..46839982 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -17,9 +17,6 @@ * */ -//This marco is used for debugging. It keeps deprecated code for verifying new implementation until new release. -//#define USE_OFFSET_X - #include #include #include //for inline widget @@ -704,11 +701,14 @@ namespace nana } } + // Don't calculate because the header fits the width + if (ranged_px + fixed_px == width) + return true; + //Don't calculate the ranged columns if //There isn't a ranged column while maximal_px == 0, or - //ranged_px + fixed_px == width, or //the minimal ranged size is larger than width - if ((0 == maximal_px) || (ranged_px + fixed_px == width) || (fixed_px + minimal_px > width)) + if ((0 == maximal_px) || (fixed_px + minimal_px > width)) return false; if (ranged_px + fixed_px > width) @@ -2080,14 +2080,12 @@ namespace nana struct scroll_part { static const unsigned scale = 16; // ? -#ifdef USE_OFFSET_X - int offset_x; -#else + unsigned x_offset() const { return (h.empty() ? 0 : h.value()); } -#endif + index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. // need to be abs??? to see the same item after sort() ?? nana::scroll v; @@ -2110,9 +2108,6 @@ namespace nana essence_t() { -#ifdef USE_OFFSET_X - scroll.offset_x = 0; -#endif pointer_where.first = parts::unknown; lister.fetch_ordering_comparer = std::bind(&es_header::fetch_comp, &header, std::placeholders::_1); } @@ -2246,24 +2241,13 @@ namespace nana const auto header_px = header.pixels(); const unsigned window_px = graph_size.width - ext_px; -#ifdef USE_OFFSET_X - if (header_px < window_px + scroll.offset_x) - { - scroll.offset_x = header_px - window_px; - } -#else auto offset_x = scroll.x_offset(); if (header_px < window_px + offset_x) offset_x = header_px - window_px; -#endif scroll.h.amount(header_px); scroll.h.range(window_px); -#ifdef USE_OFFSET_X - scroll.h.value(scroll.offset_x); -#else scroll.h.value(offset_x); -#endif scroll.h.step(graph->text_extent_size(L"W").width); } @@ -2301,7 +2285,7 @@ namespace nana const nana::size sz = graph->size(); // Adjust the ranged column assume the vertical scrollbar is enabled. - auto range_adjusted = !this->header.calc_ranged_columns(sz.width - 2 - scroll.scale); + auto range_adjusted = this->header.calc_ranged_columns(sz.width - 2 - scroll.scale); auto columns_pixels = header.pixels(); //H scroll enabled @@ -2343,10 +2327,6 @@ namespace nana set_scroll_y_dpl(item); } -#ifdef USE_OFFSET_X - else - scroll.offset_x = static_cast(scroll.h.value()); -#endif API::refresh_window(this->lister.wd_ptr()->handle()); }; @@ -2386,20 +2366,6 @@ namespace nana { scroll.v.close(); set_scroll_y_dpl({0,0}); - -#ifdef USE_OFFSET_X - nana::rectangle r; - if(rect_header(r)) - { - if(header_s > r.width) - { - if((header_s - scroll.offset_x) < r.width) - scroll.offset_x = header_s - r.width; - } - else - scroll.offset_x = 0; - } -#endif } adjust_scroll_value(); } @@ -2425,11 +2391,11 @@ namespace nana int item_xpos(const nana::rectangle& r) const { auto seq = header_seq(r.width); -#ifdef USE_OFFSET_X - return (seq.size() ? (header.position(seq[0], nullptr) - scroll.offset_x + r.x) : 0); -#else - return (seq.empty() ? 0 : header.position(seq[0], nullptr) - static_cast(scroll.x_offset()) + r.x); -#endif + + if (seq.empty()) + return 0; + + return (header.position(seq[0], nullptr) - static_cast(scroll.x_offset()) + r.x); } std::pair where(int x, int y) @@ -2441,11 +2407,7 @@ namespace nana if(header.visible() && y < static_cast(scheme_ptr->header_height + 1)) { /// we are in the header -#ifdef USE_OFFSET_X - x -= (2 - scroll.offset_x); -#else x += static_cast(scroll.x_offset()) - 2; -#endif new_where.first = parts::header; new_where.second = header.column_from_point(x); } @@ -2486,11 +2448,8 @@ namespace nana void widget_to_header(nana::point& pos) { --pos.y; -#ifdef USE_OFFSET_X - pos.x += (scroll.offset_x - 2); -#else + pos.x += static_cast(scroll.x_offset()) - 2; -#endif } bool rect_header(nana::rectangle& r) const @@ -2572,11 +2531,8 @@ namespace nana { std::vector seqs; -#ifdef USE_OFFSET_X - int x = -(scroll.offset_x); -#else int x = -static_cast(scroll.x_offset()); -#endif + for (const auto& col : header.cont()) { if (!col.visible_state) @@ -2970,11 +2926,8 @@ namespace nana { if(essence_->ptr_state == item_state::highlighted) { -#ifdef USE_OFFSET_X - x -= (r.x - essence_->scroll.offset_x); -#else x -= r.x - static_cast(essence_->scroll.x_offset()); -#endif + for(auto & col : essence_->header.cont()) // in current order { if(col.visible_state) @@ -3046,12 +2999,6 @@ namespace nana if(col.width_px != new_w) { col.width_px = new_w; -#ifdef USE_OFFSET_X - new_w = essence_->header.pixels(); - if(new_w < (rect.width + essence_->scroll.offset_x)) - essence_->scroll.offset_x = (new_w > rect.width ? new_w - rect.width : 0); -#endif - essence_->adjust_scroll_life(); return true; } @@ -3073,12 +3020,7 @@ namespace nana const int bottom_y = r.bottom() - 2; rectangle column_r{ -#ifdef USE_OFFSET_X - r.x - essence_->scroll.offset_x, -#else - r.x - static_cast(essence_->scroll.x_offset()), -#endif - r.y, + r.x - static_cast(essence_->scroll.x_offset()), r.y, 0, r.height - 1 }; @@ -3132,18 +3074,11 @@ namespace nana size_type _m_target_strip(int x, const nana::rectangle& rect, size_type grab, bool& place_front) { //convert x to header logic coordinate. -#ifdef USE_OFFSET_X - if(x < essence_->scroll.offset_x) - x = essence_->scroll.offset_x; - else if(x > essence_->scroll.offset_x + static_cast(rect.width)) - x = essence_->scroll.offset_x + static_cast(rect.width); -#else const int x_offset = static_cast(essence_->scroll.x_offset()); if (x < x_offset) x = x_offset; else if (x > x_offset + static_cast(rect.width)) x = x_offset + static_cast(rect.width); -#endif auto i = essence_->header.column_from_point(x); if(i == npos) @@ -3160,13 +3095,8 @@ namespace nana place_front = (x <= (item_x + static_cast(item_pixels / 2))); x = (place_front ? item_x : essence_->header.position(essence_->header.neighbor(i, false), nullptr)); -#ifdef USE_OFFSET_X - if(i != npos) - essence_->graph->rectangle({ x - essence_->scroll.offset_x + rect.x, rect.y, 2, rect.height }, true, colors::red); -#else if (npos != i) essence_->graph->rectangle({x - x_offset + rect.x, rect.y, 2, rect.height}, true, colors::red); -#endif return i; } @@ -3225,11 +3155,7 @@ namespace nana auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos; -#ifdef USE_OFFSET_X - ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); -#else ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), point{xpos - static_cast(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5); -#endif } private: @@ -3278,19 +3204,11 @@ namespace nana essence_->graph->palette(false, bgcolor); -#ifdef USE_OFFSET_X - int header_w = essence_->header.pixels(); - if( header_w - essence_->scroll.offset_x < static_cast(rect.width) ) - essence_->graph->rectangle(rectangle{ point(rect.x + header_w -essence_->scroll.offset_x, rect.y), - size(static_cast(rect.width) + essence_->scroll.offset_x - header_w , rect.height) }, - true); -#else const auto header_w = essence_->header.pixels(); const auto x_offset = essence_->scroll.x_offset(); if (header_w < x_offset + rect.width) essence_->graph->rectangle(rectangle{ point{ rect.x + static_cast(header_w) - static_cast(x_offset), rect.y }, size{rect.width + x_offset - header_w, rect.height} }, true); -#endif es_lister & lister = essence_->lister; //The Tracker indicates the item where mouse placed. @@ -3359,11 +3277,8 @@ namespace nana state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal); -#ifdef USE_OFFSET_X - _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); -#else _m_draw_categ(*i_categ, rect.x - static_cast(x_offset), y, txtoff, header_w, rect, bgcolor, state); -#endif + y += essence_->scheme_ptr->item_height; if(false == i_categ->expand) @@ -3429,12 +3344,7 @@ namespace nana //Draw selecting inner rectangle if (sel && (categ.expand == false)) { -#ifdef USE_OFFSET_X - width -= essence_->scroll.offset_x; -#else - width -= essence_->scroll.x_offset(); -#endif - _m_draw_border(r.x, y, (r.width < width ? r.width : width)); + _m_draw_border(r.x, y, (std::min)(r.width, width - essence_->scroll.x_offset())); } } @@ -3470,11 +3380,7 @@ namespace nana bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } -#ifdef USE_OFFSET_X - unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.offset_x); -#else unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.x_offset()); -#endif auto graph = essence_->graph; @@ -3923,8 +3829,7 @@ namespace nana { item_ptr->flags.checked = ! item_ptr->flags.checked; - index_pair abs_pos{ item_pos.cat, lister.absolute(item_pos) }; - arg_listbox arg{ item_proxy{ essence_, abs_pos } }; + arg_listbox arg{ item_proxy{ essence_, abs_item_pos } }; lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle()); if (item_ptr->flags.checked) @@ -4980,11 +4885,7 @@ namespace nana listbox::size_type listbox::column_from_pos ( const point& pos ) { auto & ess=_m_ess(); -#ifdef USE_OFFSET_X - return ess.header.column_from_point(pos.x - 2 - ess.scroll.offset_x); -#else return ess.header.column_from_point(pos.x - 2 - static_cast(ess.scroll.x_offset())); -#endif } void listbox::checkable(bool chkable) From 8d2d240d62d5919d391e0590807449d923c18f8b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 20 Jun 2016 17:10:18 +0200 Subject: [PATCH 191/309] comments in cmake list file --- CMakeLists.txt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46315d96..e80d9061 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,13 @@ # Robert Hauck - Enable support for PNG/Freetype # Qiangqiang Wu - Add biicode support # Ariel Vina-Rodriguez (qPCR4vir) +# +# Nana uses some build systems: MS-VS solution, MAKE, bakefile, codeblock, etc. manually optimized. +# In the future CMake could be the prefered, and maybe will be used to generate the others and the central nana repo +# will distribute all of them. But by now CMake is just one of them and all the other distributed build system +# files/projects are manually write. This current CMakeList.txt reflect this fact and that is why we don't +# generate here configurated *.h files or explicitly enumerate the sources files: anyway this CM-list +# will be "touched" to force a re-run of cmake. #https://cmake.org/cmake-tutorial/ #https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption @@ -13,6 +20,8 @@ # It seems that project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES. # https://bbs.archlinux.org/viewtopic.php?id=84967 + + project(nana) cmake_minimum_required(VERSION 2.8) @@ -87,7 +96,7 @@ endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) -# Compatibility with CMake 3.1 +########### Compatibility with CMake 3.1 if(POLICY CMP0054) # http://www.cmake.org/cmake/help/v3.1/policy/CMP0054.html cmake_policy(SET CMP0054 OLD) @@ -95,6 +104,9 @@ endif() add_definitions(-DNANA_IGNORE_CONF) + +########### OS + if(WIN32) add_definitions(-DWIN32) set(BUILD_FreeMe ON) #"Build FreeMe only on Windows." @@ -136,6 +148,9 @@ if(UNIX) endif(FREETYPE_FOUND) endif(UNIX) + +############# Optional libraries + #Find PNG if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) From a46991673b55073c3eba7035144e94a15986b163 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 20 Jun 2016 17:13:22 +0200 Subject: [PATCH 192/309] avoid duplicate listing of source dir --- CMakeLists.txt | 54 ++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e80d9061..57e3c029 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,8 +137,6 @@ elseif(UNIX) message("added -D linux") endif(APPLE) - - if(UNIX) list(APPEND NANA_LINKS -lX11 ) find_package(Freetype) @@ -200,43 +198,39 @@ endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) -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}/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) +# collect all source sub-directories in a list to avoid duplication here +set(NANA_SOURCE_SUBDIRS /. + /detail + /filesystem + /gui + /gui/detail + /gui/widgets + /gui/widgets/skeletons + /paint + /paint/detail + /system + /threads ) if(NANA_CMAKE_ENABLE_AUDIO) - aux_source_directory(${NANA_SOURCE_DIR}/audio NANA_AUDIO_SOURCE) - aux_source_directory(${NANA_SOURCE_DIR}/audio/detail NANA_AUDIO_DETAIL_SOURCE) + list(APPEND NANA_SOURCE_SUBDIRS + /audio + /audio/detail ) endif() +# collect all source files in the source-sub-dir #To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library #and Use SOURCE_GROUP if all your sources are in the same directory +foreach(subdir ${NANA_SOURCE_SUBDIRS}) + aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) + message("Subir: ${subdir}") + message("Files: ${sources}") +endforeach(subdir ${NANA_SOURCE_SUBDIRS}) -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}) +include_directories(${NANA_INCLUDE_DIR}) +add_library(${PROJECT_NAME} ${sources} ) +target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) - target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) install(TARGETS ${PROJECT_NAME} From b3e9e2d9791ee91d69fa64f3bf80221d4486e822 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 20 Jun 2016 17:14:35 +0200 Subject: [PATCH 193/309] FIX ? add link flag -lstdc++fs to use fs in gcc >= 5.3 --- CMakeLists.txt | 31 ++++++++++++++++--------- source/detail/platform_spec_windows.cpp | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57e3c029..89751d6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ # generate here configurated *.h files or explicitly enumerate the sources files: anyway this CM-list # will be "touched" to force a re-run of cmake. + #https://cmake.org/cmake-tutorial/ #https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption # use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir @@ -310,26 +311,34 @@ endif (NANA_CMAKE_BUILD_FreeMe) endif (NANA_CMAKE_BUILD_DEMOS) +# +# Using gcc: gcc 4.8 don't sopourt C++14 and make_unique. You may want to update at least to 4.9. +# In Windows, the gcc which come with CLion was 4.8 from MinGW. You may want to install MinGW-w64 from the +# TDM-GCC Compiler Suite for Windows which will update you to gcc 5.1. +# gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs +# +# see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html + # set compile flags if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") else("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -lstdc++fs -Wall") endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # enable static linkage - if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) - #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") - - endif () +# enable static linkage +if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) + #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") - if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") - endif () +endif () + +if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") +endif () message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index a2968f5b..7d1ae510 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -9,7 +9,7 @@ * * @file: nana/detail/platform_spec.cpp * - * @brief basis classes and data structrues required by nana + * @brief basis classes and data structures required by nana */ #include From 369d506fdd5b4d30d6b700f5997d21c6bb31465e Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 04:37:05 +0800 Subject: [PATCH 194/309] eliminate GCC warnings --- source/charset.cpp | 8 +- source/gui/detail/native_window_interface.cpp | 1 + source/gui/notifier.cpp | 2 + source/gui/widgets/listbox.cpp | 80 ++++++++----------- source/gui/widgets/slider.cpp | 4 +- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/source/charset.cpp b/source/charset.cpp index 225cba40..eb2fcd55 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -375,7 +375,8 @@ namespace nana utf8_error_police_def_char( unsigned long mark): error_mark{mark}{} unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override { - ++current_code_unit; //check (p != end) ? + if(current_code_unit < end) + ++current_code_unit; return error_mark; } @@ -399,7 +400,7 @@ namespace nana struct utf8_error_police_latin : public encoding_error_police { - unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* /*end*/) override { return *(current_code_unit++) ; } @@ -408,12 +409,11 @@ namespace nana /// buggie? struct utf8_error_police_system : public encoding_error_police { - unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override + unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* /*end*/) override { std::wstring wc; mb2wc(wc, reinterpret_cast(current_code_unit)); current_code_unit++; - //wchar_t *p = &wc[0]; return wc[0]; // use utf16char but what endian? } diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 4f356b83..0657dd14 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -156,6 +156,7 @@ namespace nana{ fn(); #else + static_cast(native_handle); fn(); #endif } diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 679969ac..0324919a 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -71,6 +71,8 @@ namespace nana ::Shell_NotifyIcon(icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); icon_added = true; } +#else + static_cast(ico); #endif } }; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 46839982..9c710901 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -326,7 +326,7 @@ namespace nana struct essence_t; - struct item_t + struct item_data { using container = std::vector; @@ -344,12 +344,12 @@ namespace nana mutable std::unique_ptr anyobj; - item_t() + item_data() { flags.selected = flags.checked = false; } - item_t(const item_t& r) + item_data(const item_data& r) : cells(r.cells), bgcolor(r.bgcolor), fgcolor(r.fgcolor), @@ -358,27 +358,19 @@ namespace nana anyobj(r.anyobj ? new nana::any(*r.anyobj) : nullptr) {} - item_t(container&& cont) + item_data(container&& cont) : cells(std::move(cont)) { flags.selected = flags.checked = false; } - - item_t(std::string&& s) + + item_data(std::string&& s) { flags.selected = flags.checked = false; cells.emplace_back(std::move(s)); } - item_t(std::string&& s, const nana::color& bg, const nana::color& fg) - : bgcolor(bg), - fgcolor(fg) - { - flags.selected = flags.checked = false; - cells.emplace_back(std::move(s)); - } - - item_t& operator=(const item_t& r) + item_data& operator=(const item_data& r) { if (this != &r) { @@ -415,7 +407,7 @@ namespace nana struct category_t { - using container = std::deque; + using container = std::deque; native_string_type text; std::vector sorted; @@ -495,7 +487,7 @@ namespace nana visible_state(other.visible_state), index(other.index), alignment(other.alignment), - weak_ordering(weak_ordering), + weak_ordering(std::move(other.weak_ordering)), ess_(other.ess_) { } @@ -590,16 +582,16 @@ namespace nana using container = std::vector; - export_options::columns_indexs all_headers(bool only_visibles) const - { - export_options::columns_indexs idx; + export_options::columns_indexs all_headers(bool only_visibles) const + { + export_options::columns_indexs idx; for(const auto &col : cont()) { if(col.visible_state || !only_visibles) idx.push_back(col.index); } - return idx; - } + return idx; + } std::string to_string(const export_options& exp_opt) const { @@ -801,7 +793,7 @@ namespace nana return npos; } - /// Returns the left point position and width(in variable * pixels) of column originaly at position pos. + /// Returns the left point position and width(in variable *pixels) of column originaly at position pos. int position(size_type pos, unsigned * pixels) const { int left = 0; @@ -1120,9 +1112,11 @@ namespace nana catobj.sorted.push_back(n); if (pos.item < n) - catobj.items.emplace(catobj.items.begin() + pos.item, std::move(text)); + catobj.items.emplace(catobj.items.begin() + pos.item); else - catobj.items.emplace_back(std::move(text)); + catobj.items.emplace_back(); + + catobj.items.back().cells.emplace_back(std::move(text)); } /// convert from display order to absolute (find the real item in that display pos) but without check from current active sorting, in fact using just the last sorting !!! @@ -1398,18 +1392,19 @@ namespace nana if (enb) { ::nana::detail::key_interface * refkey = nullptr; - for (auto i = list_.begin(); i != list_.end(); ++i) + + for (auto & cat : list_) { - if (i->key_ptr) + if (!cat.key_ptr) + continue; + + if (refkey) { - if (refkey) - { - if (!i->key_ptr->same_type(refkey)) - return false; - } - else - refkey = i->key_ptr.get(); + if (!cat.key_ptr->same_type(refkey)) + return false; } + else + refkey = cat.key_ptr.get(); } } @@ -2964,7 +2959,7 @@ namespace nana //grab_move /// @brief draw when an item is grabbing. /// @return true if refresh is needed, false otherwise - bool grab_move(const nana::rectangle& rect, const nana::point& pos) + bool grab_move(const nana::point& pos) { if(npos == grabs_.splitter) { // move column, not resize it @@ -3016,9 +3011,6 @@ namespace nana if ((parts::header == essence_->pointer_where.first) && (npos == grabs_.splitter)) state = essence_->ptr_state; - const unsigned height = r.height - 1; - const int bottom_y = r.bottom() - 2; - rectangle column_r{ r.x - static_cast(essence_->scroll.x_offset()), r.y, 0, r.height - 1 @@ -3036,7 +3028,7 @@ namespace nana if (right_pos > r.x) { _m_draw_header_item(graph, column_r, text_top, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); - graph.line({ right_pos - 1, r.y }, { right_pos - 1, bottom_y }, _m_border_color()); + graph.line({ right_pos - 1, r.y }, { right_pos - 1, r.bottom() - 2 }, _m_border_color()); } column_r.x = right_pos; @@ -3163,7 +3155,7 @@ namespace nana struct grab_variables { - int start_pos{ npos }; + int start_pos; unsigned item_width; size_type splitter{ npos }; @@ -3440,7 +3432,7 @@ namespace nana bool draw_column = true; - if ( content_pos + essence_->scheme_ptr->text_margin < static_cast(col.width_px)) // we have room + if ( content_pos + essence_->scheme_ptr->text_margin < col.width_px) // we have room { auto inline_wdg = _m_get_inline_pane(cat, column_pos); if (inline_wdg) @@ -3503,7 +3495,6 @@ namespace nana auto cell_txtcolor = fgcolor; auto & m_cell = item.cells[column_pos]; review_utf8(m_cell.text); - nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need { @@ -3699,10 +3690,7 @@ namespace nana { // moving a grabbed header nana::point pos = arg.pos; essence_->widget_to_header(pos); - - nana::rectangle r; - essence_->rect_header(r); - need_refresh = drawer_header_->grab_move(r, pos); + need_refresh = drawer_header_->grab_move(pos); } else if(essence_->calc_where(arg.pos)) { diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index f2b38b75..e89e210f 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -17,7 +17,7 @@ namespace nana : public renderer_interface { private: - void background(window wd, graph_reference graph, bool transparent, const scheme& schm) override + void background(window, graph_reference graph, bool transparent, const scheme& schm) override { if (!transparent) graph.rectangle(true, schm.background); @@ -277,7 +277,7 @@ namespace nana return other_.wd; } - void attached(nana::slider& wdg, graph_reference graph) + void attached(nana::slider& wdg, graph_reference) { other_.wd = wdg.handle(); other_.widget = &wdg; From 705fca523223b5265abc61f744dc771159771628 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 08:47:47 +0800 Subject: [PATCH 195/309] update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7868e3e..3e64fdb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=1 --branch=hotfix-1.3 https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=1 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From d04776216b1c290d2add059e04f046711813e37c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 09:30:15 +0800 Subject: [PATCH 196/309] std.exp.filesystem for vc2013 --- include/nana/c++defines.hpp | 7 +- include/nana/filesystem/filesystem_ext.hpp | 69 ++++++++++--------- .../nana/filesystem/filesystem_selector.hpp | 2 +- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 2dc4c5f2..d9e9fef6 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -43,14 +43,19 @@ //C++ language #if defined(_MSC_VER) -# undef STD_FILESYSTEM_NOT_SUPPORTED # if (_MSC_VER < 1900) +# //About std.experimental.filesystem. +# //Through VC2013 has provided , but all the names are given in namespace std. It's hard to alias these names into std::experimental, +# //So Nana use nana.filesystem implement instead for VC2013 +# # //Nana defines some macros for lack of support of keywords # define _ALLOW_KEYWORD_MACROS # # define CXX_NO_INLINE_NAMESPACE //no support of C++11 inline namespace until Visual C++ 2015 # define noexcept //no support of noexcept until Visual C++ 2015 # define constexpr //no support of constexpr until Visual C++ 2015 +# else +# undef STD_FILESYSTEM_NOT_SUPPORTED # endif #elif defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ < 6) diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index ef561665..feb68fa9 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -42,29 +42,32 @@ class directory_only_iterator : public std::experimental::filesystem::directory_ { using DI = std::experimental::filesystem::directory_iterator; directory_only_iterator& find_first() - { - auto end = directory_only_iterator{}; - while (*this != end) - { - if (is_directory((**this).status())) - return *this; - this->DI::operator++(); - } - return *this; - } + { + auto end = directory_only_iterator{}; + while (*this != end) + { + if (is_directory((**this).status())) + return *this; + this->DI::operator++(); + } + return *this; + } public: - template - directory_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) - { - find_first(); - } - directory_only_iterator( ) {} + directory_only_iterator(){} + + template + directory_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) + { + find_first(); + } + directory_only_iterator& operator++() { this->DI::operator++(); return find_first(); } }; + inline directory_only_iterator begin(directory_only_iterator iter) noexcept { return iter; @@ -81,23 +84,25 @@ class regular_file_only_iterator : public std::experimental::filesystem::directo { using DI = std::experimental::filesystem::directory_iterator; regular_file_only_iterator& find_first() - { - while(( (*this) != DI{}) && !is_regular_file((**this).status())) - this->DI::operator++(); - return (*this); - } + { + while(( (*this) != DI{}) && !is_regular_file((**this).status())) + this->DI::operator++(); + return (*this); + } public: - template - regular_file_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) - { - find_first(); - } regular_file_only_iterator() : DI() {} - regular_file_only_iterator& operator++() - { - this->DI::operator++(); - return find_first(); - } + + template + regular_file_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) + { + find_first(); + } + + regular_file_only_iterator& operator++() + { + this->DI::operator++(); + return find_first(); + } }; inline regular_file_only_iterator begin(regular_file_only_iterator iter) noexcept @@ -113,7 +118,7 @@ inline regular_file_only_iterator end(const regular_file_only_iterator&) noexcep inline std::string pretty_file_size(const std::experimental::filesystem::path& path) // todo: move to .cpp { try { - std::size_t bytes = std::experimental::filesystem::file_size ( path ); + auto bytes = std::experimental::filesystem::file_size ( path ); const char * ustr[] = { " KB", " MB", " GB", " TB" }; std::stringstream ss; if (bytes < 1024) diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index b0d3ae3a..e0b084b4 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -61,7 +61,7 @@ namespace std { } // std #else -# include +# include #endif #ifndef __cpp_lib_experimental_filesystem From 8513b6503eb7af44ce6c2fbc94f03a371e9b50c7 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 16:26:46 +0800 Subject: [PATCH 197/309] fix travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3e64fdb9..7d7029c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -93,7 +93,7 @@ script: - ./dock - ./drag-button - ./draw - - ./file_explorer + #- ./file_explorer #- ./example_menu - ./example_listbox #- ./example_combox From 13fc844a5a714deaf10a617c8a6b7aad501f493b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 18:06:36 +0800 Subject: [PATCH 198/309] debug travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7d7029c6..10769a11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,9 @@ before_script : - cd bin script: + - cat CMakeLists.txt - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cat Makefiles - make - cd .. - mv -v bin/ nana-demo/ From 2243057f1e072013434392493c37d9d9e9ae5e25 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 18:17:24 +0800 Subject: [PATCH 199/309] debug travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 10769a11..93487a20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,9 +76,9 @@ before_script : - cd bin script: - - cat CMakeLists.txt + - pwd + - ls - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - - cat Makefiles - make - cd .. - mv -v bin/ nana-demo/ From 938ee41791fdf73ead9cdfc3fd9d4f095463297b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 18:29:59 +0800 Subject: [PATCH 200/309] debug travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93487a20..bd93457d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,9 +76,9 @@ before_script : - cd bin script: - - pwd - - ls + - cat ../nana-demo/CMakeLists.txt - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cat Makefile - make - cd .. - mv -v bin/ nana-demo/ From 84b9aeaa214f88d9892a0fd08a6b6d5e71e463ae Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 18:47:26 +0800 Subject: [PATCH 201/309] normal travis --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bd93457d..7d7029c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,9 +76,7 @@ before_script : - cd bin script: - - cat ../nana-demo/CMakeLists.txt - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - - cat Makefile - make - cd .. - mv -v bin/ nana-demo/ From befc81c7b75fbdea9f48ba481a6d23554cc41cd6 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 21 Jun 2016 15:21:41 +0200 Subject: [PATCH 202/309] NANA_CMAKE_BOOST_FILESYSTEM_FORCE in travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7868e3e..cb0d55a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,7 @@ before_script : - cd bin script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - cd .. - mv -v bin/ nana-demo/ From 05fd4f797db68d596c6541ce6b369e5d4dfad881 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 23:28:39 +0800 Subject: [PATCH 203/309] remove test file_explorer --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46315d96..deebb178 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# CMake configuration for Nana +# CMake configuration for Nana # Author: Andrew Kornilov(https://github.com/ierofant) # Contributors: # Jinhao @@ -245,7 +245,7 @@ if (NANA_CMAKE_BUILD_DEMOS) enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - set (demos calculator file_explorer helloworld_demo notepad ) + set (demos calculator helloworld_demo notepad ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") From e462eb8f747d4b784f71241812672699c8aa9ba0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jun 2016 23:39:27 +0800 Subject: [PATCH 204/309] remove test folder_tree_std --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index deebb178..50aebed3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,7 +282,7 @@ endif (NANA_CMAKE_BUILD_FreeMe) set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked decore dock drag-button draw example.button example_combox example_listbox example_menu - filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 + filebox-txt folder_tree folder_tree_nana framework_design_1 framework_design_2 framework_design_3 group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image threading thread-pool various_events window-dragger windows-subclassing From 9201ca5d7928b09d243027ceac3ee89f671f1cca Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 22 Jun 2016 01:46:02 +0800 Subject: [PATCH 205/309] remove test widget_show --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50aebed3..da97000c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,7 +260,7 @@ if (NANA_CMAKE_BUILD_DEMOS) message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) - set (demos widget_show widget_show2 ) + set (demos widget_show2 ) if (NANA_CMAKE_BUILD_FreeMe) add_definitions(-DBUILD_FreeMe) From 067eeff3ddc713de7c6ff95ca19100a9fa2c392f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 21 Jun 2016 20:43:36 +0200 Subject: [PATCH 206/309] improve verbose_preprocessor --- CMakeLists.txt | 2 +- include/nana/c++defines.hpp | 8 +++-- include/nana/deploy.hpp | 4 +-- include/nana/verbose_preprocessor.hpp | 51 +++++++++++++++++++++------ source/deploy.cpp | 3 ++ 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89751d6d..2c30bcd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ option(NANA_CMAKE_LIBPNG_FROM_OS "Use libpng from operating system." ON) option(NANA_CMAKE_ENABLE_JPEG "Enable the use of JPEG" OFF) option(NANA_CMAKE_LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) option(NANA_CMAKE_ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) -option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) +option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." ON) option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." OFF) option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 2dc4c5f2..98c383c6 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -35,7 +35,10 @@ * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) * - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8) - */ + * - STD_FILESYSTEM_NOT_SUPPORTED (GCC < 5.3) .... + * - CXX_NO_INLINE_NAMESPACE (Visual C++ < 2015) + * - STD_MAKE_UNIQUE_NOT_SUPPORTED (GCC < 4.9) + */ #ifndef NANA_CXX_DEFINES_INCLUDED #define NANA_CXX_DEFINES_INCLUDED @@ -50,7 +53,7 @@ # # define CXX_NO_INLINE_NAMESPACE //no support of C++11 inline namespace until Visual C++ 2015 # define noexcept //no support of noexcept until Visual C++ 2015 -# define constexpr //no support of constexpr until Visual C++ 2015 +# define constexpr const //no support of constexpr until Visual C++ 2015 ? const ?? # endif #elif defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ < 6) @@ -141,6 +144,7 @@ #if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) # undef STD_FILESYSTEM_NOT_SUPPORTED + /// \todo define the namespace ???? #endif #if (__GNUC__ == 4) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 342adfe7..86bb894b 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -17,9 +17,7 @@ #include #include -#if defined(VERBOSE_PREPROCESSOR) - #include -#endif + #include #include diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp index b62267f6..6a93c654 100644 --- a/include/nana/verbose_preprocessor.hpp +++ b/include/nana/verbose_preprocessor.hpp @@ -11,8 +11,8 @@ * * @brief show the values of configuration constants during compilation to facilitate build debugging. * - * Set VERBOSE_PREPROCESSOR to 1 to show the messages or to 0 for a normal build. - * Normally set to 0. Set to 1 only in case you want to debug the build system because it is extremely repetitive and slow. + * Define VERBOSE_PREPROCESSOR to show the messages or undefine for a normal build. + * Normally undefined. Define in case you want to debug the build system. * * @authors Ariel Vina-Rodriguez (qPCR4vir) * @@ -25,25 +25,55 @@ #if defined(VERBOSE_PREPROCESSOR) + #include + #include + + + #define STRING2(x) #x #define STRING(x) STRING2(x) - #pragma message ( "\nVerbose preprocessor =" STRING(VERBOSE_PREPROCESSOR)" , \n STOP_VERBOSE_PREPROCESSOR=" STRING(STOP_VERBOSE_PREPROCESSOR) ) + #pragma message ( "\n ---> SVerbose preprocessor \nVERBOSE_PREPROCESSOR=" STRING(VERBOSE_PREPROCESSOR)" , \n STOP_VERBOSE_PREPROCESSOR=" STRING(STOP_VERBOSE_PREPROCESSOR) ) - #pragma message ( "\nWindows: \n _WIN32=" STRING(_WIN32) ", \n __WIN32__ =" STRING(__WIN32__) " , \n WIN32=" STRING(WIN32)" , \n NANA_WINDOWS=" STRING(NANA_WINDOWS) ) + #pragma message ( "\n ---> OS: \nWindows: \n _WIN32=" STRING(_WIN32) ", \n __WIN32__ =" STRING(__WIN32__) " , \n WIN32=" STRING(WIN32)" , \n NANA_WINDOWS=" STRING(NANA_WINDOWS) ) - #pragma message ( "\nUNICODE: \n NANA_UNICODE=" STRING(NANA_UNICODE) ", \n _UNICODE =" STRING(_UNICODE) " , \n UNICODE=" STRING(UNICODE) ) + #pragma message ( "\nNIX: \n NANA_LINUX=" STRING(NANA_LINUX) ", \n NANA_POSIX=" STRING(NANA_POSIX) " , \n NANA_X11=" STRING(NANA_X11) " , \n APPLE=" STRING(APPLE) " , \n NANA_MACOS =" STRING(NANA_MACOS) " , \n NANA_IGNORE_CONF=" STRING(NANA_IGNORE_CONF) ) - #pragma message ( "\nMinGW: \n __MINGW32__=" STRING(__MINGW32__) ", \n __MINGW64__=" STRING(__MINGW64__) " , \n MINGW=" STRING(MINGW) ) + #pragma message ( "\n ---> Compilers: \n MinGW: \n __MINGW32__=" STRING(__MINGW32__) ", \n __MINGW64__=" STRING(__MINGW64__) " , \n MINGW=" STRING(MINGW) ) + + #pragma message ( "\nMSC: \n _MSC_VER=" STRING(_MSC_VER) ", \n _MSC_FULL_VER=" STRING(_MSC_FULL_VER ) ) #pragma message ( "\nGNU: \n __GNUC__=" STRING(__GNUC__) ", \n __GNUC_MINOR__=" STRING(__GNUC_MINOR__) " , \n __GNUC_PATCHLEVEL__=" STRING(__GNUC_PATCHLEVEL__) ) - #pragma message ( "\nSTD: \nSTD_CODECVT_NOT_SUPPORTED=" STRING(STD_CODECVT_NOT_SUPPORTED) " , \nSTD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) + #pragma message ( "\nClang compiler: \n __clang__=" STRING(__clang__) ", \n __GLIBCPP__=" STRING(__GLIBCPP__) " , \n __GLIBCXX__=" STRING(__GLIBCXX__) ) - #pragma message ( "\nSTD: \nUSE_github_com_meganz_mingw_std_threads=" STRING(USE_github_com_meganz_mingw_std_threads) " , \nSTD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) + #pragma message ( "\n ---> STD: \n STD_CODECVT_NOT_SUPPORTED=" STRING(STD_CODECVT_NOT_SUPPORTED) " , \n STD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) - #pragma message ( "\nClang compiler: \n__clang__=" STRING(__clang__) ", \n__GLIBCPP__=" STRING(__GLIBCPP__) " , \n__GLIBCXX__=" STRING(__GLIBCXX__) ) + #pragma message ( "\n STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED=" STRING(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED) " , \n STD_TO_STRING_NOT_SUPPORTED=" STRING(STD_TO_STRING_NOT_SUPPORTED) ", \n STD_TO_WSTRING_NOT_SUPPORTED=" STRING(STD_TO_WSTRING_NOT_SUPPORTED)) + + #pragma message ( "\n USE_github_com_meganz_mingw_std_threads=" STRING(USE_github_com_meganz_mingw_std_threads) ", \n NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ=" STRING(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)" , \n STD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) + + #pragma message ( "\n STD_put_time_NOT_SUPPORTED=" STRING(STD_put_time_NOT_SUPPORTED) " , \n STD_MAKE_UNIQUE_NOT_SUPPORTED=" STRING(STD_MAKE_UNIQUE_NOT_SUPPORTED)" , \n STD_FILESYSTEM_NOT_SUPPORTED=" STRING(STD_FILESYSTEM_NOT_SUPPORTED)) + + #pragma message ( "\n BOOST_FILESYSTEM_AVAILABLE=" STRING(BOOST_FILESYSTEM_AVAILABLE) ", \n BOOST_FILESYSTEM_FORCE =" STRING(BOOST_FILESYSTEM_FORCE) " , \n STD_FILESYSTEM_FORCE=" STRING(STD_FILESYSTEM_FORCE) ", \n NANA_FILESYSTEM_FORCE=" STRING(NANA_FILESYSTEM_FORCE) ) + + #pragma message ( "\n CXX_NO_INLINE_NAMESPACE=" STRING(CXX_NO_INLINE_NAMESPACE) ", \n __has_include=" STRING(__has_include)" , \n __cpp_lib_experimental_filesystem=" STRING(__cpp_lib_experimental_filesystem) ) + + #include + + #pragma message ( "\n ...including filesystem_selector: \n STD_put_time_NOT_SUPPORTED=" STRING(STD_put_time_NOT_SUPPORTED) " , \n STD_FILESYSTEM_NOT_SUPPORTED=" STRING(STD_FILESYSTEM_NOT_SUPPORTED)) + + #pragma message ( "\n BOOST_FILESYSTEM_AVAILABLE=" STRING(BOOST_FILESYSTEM_AVAILABLE) ", \n BOOST_FILESYSTEM_FORCE =" STRING(BOOST_FILESYSTEM_FORCE) " , \n STD_FILESYSTEM_FORCE=" STRING(STD_FILESYSTEM_FORCE) ", \n NANA_FILESYSTEM_FORCE=" STRING(NANA_FILESYSTEM_FORCE) ) + + #pragma message ( "\n CXX_NO_INLINE_NAMESPACE=" STRING(CXX_NO_INLINE_NAMESPACE) ", \n __has_include=" STRING(__has_include)" , \n __cpp_lib_experimental_filesystem=" STRING(__cpp_lib_experimental_filesystem) ) + + // #pragma message ( "\n =" STRING() ", \n =" STRING()" , \n =" STRING() ) + + #pragma message ( "\nUNICODE: \n NANA_UNICODE=" STRING(NANA_UNICODE) ", \n _UNICODE =" STRING(_UNICODE) " , \n UNICODE=" STRING(UNICODE) ) + + #pragma message ( "\n ---> Libraries: \n NANA_ENABLE_AUDIO=" STRING(NANA_ENABLE_AUDIO) ", \n NANA_ENABLE_PNG =" STRING(NANA_ENABLE_PNG) " , \n USE_LIBPNG_FROM_OS=" STRING(USE_LIBPNG_FROM_OS) " , \n NANA_LIBPNG=" STRING(NANA_LIBPNG) ) + + #pragma message ( "\n NANA_ENABLE_JPEG=" STRING(NANA_ENABLE_JPEG) ", \n USE_LIBJPEG_FROM_OS =" STRING(USE_LIBJPEG_FROM_OS) " , \n NANA_LIBJPEG=" STRING(NANA_LIBJPEG) ) - #pragma message ( "\nMSC: \n_MSC_VER=" STRING(_MSC_VER) ", \n_MSC_FULL_VER=" STRING(_MSC_FULL_VER ) ) #if defined(STOP_VERBOSE_PREPROCESSOR) #error ("\nCompilation stopped to avoid annoying messages") @@ -52,5 +82,4 @@ #endif // VERBOSE_PREPROCESSOR - #endif //NANA_VERBOSE_PREPROCESSOR_H diff --git a/source/deploy.cpp b/source/deploy.cpp index 3e6dfcf7..b2f216e0 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -702,3 +702,6 @@ namespace nana } +#if defined(VERBOSE_PREPROCESSOR) +# include +#endif \ No newline at end of file From 477ea05ced91deaa2b2e1351d5819e27207f987a Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 21 Jun 2016 20:46:09 +0200 Subject: [PATCH 207/309] FIX linking with CMake - CLion - gcc 5.1 --- CMakeLists.txt | 52 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c30bcd5..e954ec10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ option(NANA_CMAKE_LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) option(NANA_CMAKE_ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." ON) option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) -option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." OFF) +option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." ON) option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) option(NANA_CMAKE_BUILD_FreeMe "Build FreeMe (currently broken)?" OFF) @@ -87,6 +87,7 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) include_directories(SYSTEM "${Boost_INCLUDE_DIR}") list(APPEND NANA_LINKS "${Boost_LIBRARIES}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) set(Boost_USE_STATIC_LIBS ON) @@ -110,7 +111,7 @@ add_definitions(-DNANA_IGNORE_CONF) if(WIN32) add_definitions(-DWIN32) - set(BUILD_FreeMe ON) #"Build FreeMe only on Windows." + # set(BUILD_FreeMe ON) #"Build FreeMe only on Windows." #Global MSVC definitions. You may prefer the hand-tuned sln and projects from the nana repository. if(MSVC) option(WIN32_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON) @@ -132,6 +133,7 @@ if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") set(ENABLE_AUDIO OFF) elseif(UNIX) add_definitions(-Dlinux) @@ -140,10 +142,12 @@ endif(APPLE) if(UNIX) list(APPEND NANA_LINKS -lX11 ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lX11") find_package(Freetype) if (FREETYPE_FOUND) include_directories( ${FREETYPE_INCLUDE_DIRS}) - list(APPEND NANA_LINKS -lXft ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lXft") + list(APPEND NANA_LINKS -lXft ) endif(FREETYPE_FOUND) endif(UNIX) @@ -154,7 +158,8 @@ endif(UNIX) if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) #set(NANA_PNG_LIB "png") - list(APPEND NANA_LINKS -lpng ) + list(APPEND NANA_LINKS -lpng ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpng") if(NANA_CMAKE_LIBPNG_FROM_OS) find_package(PNG) if (PNG_FOUND) @@ -168,7 +173,8 @@ endif(NANA_CMAKE_ENABLE_PNG) if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) #set(NANA_JPEG_LIB "jpeg") - list(APPEND NANA_LINKS -ljpeg ) + list(APPEND NANA_LINKS -ljpeg ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ljpeg") if(NANA_CMAKE_LIBJPEG_FROM_OS) find_package(JPEG) if (JPEG_FOUND) @@ -184,7 +190,8 @@ if(NANA_CMAKE_ENABLE_AUDIO) find_package(ASOUND) if (ASOUND_FOUND) include_directories( ${ASOUND_INCLUDE_DIRS}) - list(APPEND NANA_LINKS -lasound ) + list(APPEND NANA_LINKS -lasound ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lasound") else(ASOUND_FOUND) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) @@ -228,7 +235,7 @@ endforeach(subdir ${NANA_SOURCE_SUBDIRS}) include_directories(${NANA_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) +target_link_libraries(${PROJECT_NAME} ) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) @@ -260,7 +267,7 @@ if (NANA_CMAKE_BUILD_DEMOS) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) @@ -272,19 +279,19 @@ if (NANA_CMAKE_BUILD_DEMOS) set (demos widget_show widget_show2 ) -if (NANA_CMAKE_BUILD_FreeMe) - add_definitions(-DBUILD_FreeMe) -endif (NANA_CMAKE_BUILD_FreeMe) +#if (NANA_CMAKE_BUILD_FreeMe) + # add_definitions(-DBUILD_FreeMe) +#endif (NANA_CMAKE_BUILD_FreeMe) - if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - list(APPEND demos FreeMe) # ?? - endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + # if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + # list(APPEND demos ) # ?? FreeMe + # endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) @@ -302,7 +309,7 @@ endif (NANA_CMAKE_BUILD_FreeMe) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/Examples/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/Examples/") message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) @@ -322,18 +329,21 @@ endif (NANA_CMAKE_BUILD_DEMOS) # set compile flags if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") # Clang else("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -lstdc++fs -Wall") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") # IS_GNUCXX < 5.3 + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -lstdc++fs -Wall") # IS_GNUCXX 5.3 or more + endif() endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # enable static linkage if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) - #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") - + #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") endif () if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") From 264396d008f1c4885f70b82fbfbd2b70cc82b60b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 21 Jun 2016 20:50:25 +0200 Subject: [PATCH 208/309] NANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF in travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cb0d55a0..71fe6094 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,7 @@ before_script : - cd bin script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - cd .. - mv -v bin/ nana-demo/ From 4e536eeff956a5501625984f46d229e287d317b2 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Tue, 21 Jun 2016 23:24:52 +0200 Subject: [PATCH 209/309] fixing linking --- CMakeLists.txt | 92 ++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e954ec10..e71c33c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,9 +85,10 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) find_package(Boost COMPONENTS filesystem) if (Boost_FOUND) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) - include_directories(SYSTEM "${Boost_INCLUDE_DIR}") - list(APPEND NANA_LINKS "${Boost_LIBRARIES}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") + include_directories(SYSTEM "${Boost_INCLUDE_DIR}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") + #list(APPEND NANA_LINKS "${Boost_LIBRARIES}") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) set(Boost_USE_STATIC_LIBS ON) @@ -132,8 +133,9 @@ endif(WIN32) if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) - list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") + #list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -liconv") set(ENABLE_AUDIO OFF) elseif(UNIX) add_definitions(-Dlinux) @@ -142,12 +144,14 @@ endif(APPLE) if(UNIX) list(APPEND NANA_LINKS -lX11 ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lX11") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lX11") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lX11") find_package(Freetype) if (FREETYPE_FOUND) include_directories( ${FREETYPE_INCLUDE_DIRS}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lXft") - list(APPEND NANA_LINKS -lXft ) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lXft") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lXft") + #list(APPEND NANA_LINKS -lXft ) endif(FREETYPE_FOUND) endif(UNIX) @@ -158,8 +162,9 @@ endif(UNIX) if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) #set(NANA_PNG_LIB "png") - list(APPEND NANA_LINKS -lpng ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpng") + #list(APPEND NANA_LINKS -lpng ) + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpng") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpng") if(NANA_CMAKE_LIBPNG_FROM_OS) find_package(PNG) if (PNG_FOUND) @@ -173,8 +178,9 @@ endif(NANA_CMAKE_ENABLE_PNG) if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) #set(NANA_JPEG_LIB "jpeg") - list(APPEND NANA_LINKS -ljpeg ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ljpeg") + # list(APPEND NANA_LINKS -ljpeg ) + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ljpeg") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljpeg") if(NANA_CMAKE_LIBJPEG_FROM_OS) find_package(JPEG) if (JPEG_FOUND) @@ -190,8 +196,9 @@ if(NANA_CMAKE_ENABLE_AUDIO) find_package(ASOUND) if (ASOUND_FOUND) include_directories( ${ASOUND_INCLUDE_DIRS}) - list(APPEND NANA_LINKS -lasound ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lasound") + # list(APPEND NANA_LINKS -lasound ) + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lasound") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasound") else(ASOUND_FOUND) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) @@ -229,16 +236,16 @@ endif() #and Use SOURCE_GROUP if all your sources are in the same directory foreach(subdir ${NANA_SOURCE_SUBDIRS}) aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) - message("Subir: ${subdir}") - message("Files: ${sources}") + # message("Subir: ${subdir}") + # message("Files: ${sources}") endforeach(subdir ${NANA_SOURCE_SUBDIRS}) include_directories(${NANA_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} +target_link_libraries(${PROJECT_NAME} ) # ${NANA_LINKS} or ${ } - # Headers: use INCLUDE_DIRECTORIES - # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) + # Headers: use INCLUDE_DIRECTORIES + # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) install(TARGETS ${PROJECT_NAME} @@ -267,7 +274,7 @@ if (NANA_CMAKE_BUILD_DEMOS) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) @@ -279,9 +286,9 @@ if (NANA_CMAKE_BUILD_DEMOS) set (demos widget_show widget_show2 ) -#if (NANA_CMAKE_BUILD_FreeMe) - # add_definitions(-DBUILD_FreeMe) -#endif (NANA_CMAKE_BUILD_FreeMe) + #if (NANA_CMAKE_BUILD_FreeMe) + # add_definitions(-DBUILD_FreeMe) + #endif (NANA_CMAKE_BUILD_FreeMe) # if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # list(APPEND demos ) # ?? FreeMe @@ -291,7 +298,7 @@ if (NANA_CMAKE_BUILD_DEMOS) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) @@ -309,7 +316,7 @@ if (NANA_CMAKE_BUILD_DEMOS) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/Examples/${demo}.cpp") set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_CXX_FLAGS} + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/Examples/") message("... to build: ../nana-demo/Examples/${demo}.cpp" ) endforeach( demo ${demos}) @@ -327,37 +334,42 @@ endif (NANA_CMAKE_BUILD_DEMOS) # see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html # set compile flags -if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") # Clang - else("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") # IS_GNUCXX < 5.3 - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -lstdc++fs -Wall") # IS_GNUCXX 5.3 or more - endif() - endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") +if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU + + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") # Clang + + else ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") # GNU + + endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # enable static linkage -if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) +if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) # GNU || CLang not MinGW #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++ -pthread") + + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + # IS_GNUCXX < 5.3 + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more + endif() endif () -if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") +if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") endif () message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) -message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) +message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) +message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "DESTDIR = " ${DESTDIR}) message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) -message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO}) message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) From 7c44842350edd3e775c4764b4efa76180acb90dd Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 00:56:53 +0200 Subject: [PATCH 210/309] forgot ${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e71c33c4..e12f9d12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,7 +135,7 @@ if(APPLE) include_directories(/opt/X11/include/) #list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -liconv") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ -liconv") set(ENABLE_AUDIO OFF) elseif(UNIX) add_definitions(-Dlinux) From 0cd9be464171051f29954a144d5414b932a1ed76 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 22 Jun 2016 12:08:46 +0800 Subject: [PATCH 211/309] remove test widget_show2 --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da97000c..339b869c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,11 +260,9 @@ if (NANA_CMAKE_BUILD_DEMOS) message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) - set (demos widget_show2 ) - if (NANA_CMAKE_BUILD_FreeMe) add_definitions(-DBUILD_FreeMe) -endif (NANA_CMAKE_BUILD_FreeMe) + set (demos FreeMe ) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) list(APPEND demos FreeMe) # ?? @@ -279,6 +277,8 @@ endif (NANA_CMAKE_BUILD_FreeMe) message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) +endif (NANA_CMAKE_BUILD_FreeMe) + set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked decore dock drag-button draw example.button example_combox example_listbox example_menu From 179750630c9d3f9a78c323ac2481ae37ddd824f4 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 15:48:56 +0200 Subject: [PATCH 212/309] CMAKE_STATIC_LINKER_FLAGS ? --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e12f9d12..5a4590c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -362,11 +362,15 @@ if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # A set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") endif () +set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") + + message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) +message ( "CMAKE_STATIC_LINKER_FLAGS= " ${CMAKE_STATIC_LINKER_FLAGS}) message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "DESTDIR = " ${DESTDIR}) message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) From fe90da19a2a9e041e1af801fb5f26b4e38aed4bb Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 16:04:14 +0200 Subject: [PATCH 213/309] CMAKE_STATIC_LINKER_FLAGS append? --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a4590c9..a5314e18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -362,7 +362,7 @@ if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # A set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") endif () -set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") +set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) From f22cb91557830a47c318b4b3d2e0de9aa16e62db Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 16:44:50 +0200 Subject: [PATCH 214/309] return to using NANA_LINKS only --- CMakeLists.txt | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5314e18..d05ed3c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,11 +84,11 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) # If using Boost::thread, then Thread::Thread will also be added automatically. find_package(Boost COMPONENTS filesystem) if (Boost_FOUND) - add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) - include_directories(SYSTEM "${Boost_INCLUDE_DIR}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") - #list(APPEND NANA_LINKS "${Boost_LIBRARIES}") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") + add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) + include_directories(SYSTEM "${Boost_INCLUDE_DIR}") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") + list(APPEND NANA_LINKS "${Boost_LIBRARIES}") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) set(Boost_USE_STATIC_LIBS ON) @@ -133,9 +133,9 @@ endif(WIN32) if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) - #list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) + list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ -liconv") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ -liconv") set(ENABLE_AUDIO OFF) elseif(UNIX) add_definitions(-Dlinux) @@ -145,13 +145,13 @@ endif(APPLE) if(UNIX) list(APPEND NANA_LINKS -lX11 ) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lX11") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lX11") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lX11") find_package(Freetype) if (FREETYPE_FOUND) include_directories( ${FREETYPE_INCLUDE_DIRS}) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lXft") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lXft") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lXft") - #list(APPEND NANA_LINKS -lXft ) + list(APPEND NANA_LINKS -lXft ) endif(FREETYPE_FOUND) endif(UNIX) @@ -162,9 +162,9 @@ endif(UNIX) if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) #set(NANA_PNG_LIB "png") - #list(APPEND NANA_LINKS -lpng ) + list(APPEND NANA_LINKS -lpng ) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpng") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpng") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpng") if(NANA_CMAKE_LIBPNG_FROM_OS) find_package(PNG) if (PNG_FOUND) @@ -178,9 +178,9 @@ endif(NANA_CMAKE_ENABLE_PNG) if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) #set(NANA_JPEG_LIB "jpeg") - # list(APPEND NANA_LINKS -ljpeg ) + list(APPEND NANA_LINKS -ljpeg ) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ljpeg") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljpeg") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljpeg") if(NANA_CMAKE_LIBJPEG_FROM_OS) find_package(JPEG) if (JPEG_FOUND) @@ -196,9 +196,9 @@ if(NANA_CMAKE_ENABLE_AUDIO) find_package(ASOUND) if (ASOUND_FOUND) include_directories( ${ASOUND_INCLUDE_DIRS}) - # list(APPEND NANA_LINKS -lasound ) + list(APPEND NANA_LINKS -lasound ) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lasound") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasound") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasound") else(ASOUND_FOUND) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) @@ -232,8 +232,8 @@ if(NANA_CMAKE_ENABLE_AUDIO) endif() # collect all source files in the source-sub-dir -#To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library -#and Use SOURCE_GROUP if all your sources are in the same directory +#To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library +#and Use SOURCE_GROUP if all your sources are in the same directory foreach(subdir ${NANA_SOURCE_SUBDIRS}) aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) # message("Subir: ${subdir}") @@ -242,7 +242,7 @@ endforeach(subdir ${NANA_SOURCE_SUBDIRS}) include_directories(${NANA_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ) # ${NANA_LINKS} or ${ } +target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) # ${NANA_LINKS} or ${ } # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) @@ -349,14 +349,16 @@ endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # enable static linkage if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) # GNU || CLang not MinGW #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++ -pthread") + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) # IS_GNUCXX < 5.3 - else() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more - endif() -endif () + else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + set(CMAKE_EXE_LINKER_FLAGS " -lstdc++fs ${CMAKE_EXE_LINKER_FLAGS}") # IS_GNUCXX 5.3 or more + endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + +endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) + if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") From f59dfb99497d558931321d26e9c281377617b867 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 17:52:16 +0200 Subject: [PATCH 215/309] # set (CMAKE_STATIC_LINKER_FLAGS --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d05ed3c2..d5a448aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,7 +364,7 @@ if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # A set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") endif () -set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") +# set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) From dfdf122ee2077cc7d200e55371606da1ba3bf5fa Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 18:10:35 +0200 Subject: [PATCH 216/309] NANA_LINKS " -lstdc++fs --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5a448aa..79ffc023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,7 @@ if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND N # IS_GNUCXX < 5.3 else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) set(CMAKE_EXE_LINKER_FLAGS " -lstdc++fs ${CMAKE_EXE_LINKER_FLAGS}") # IS_GNUCXX 5.3 or more + set(NANA_LINKS " -lstdc++fs ${NANA_LINKS}") endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) From 250b73b8d45e50016e826eb7402cf2ba8a74625a Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Wed, 22 Jun 2016 20:45:49 +0200 Subject: [PATCH 217/309] NANA_USING_NANA_FILESYSTEM for verbose pp #define NANA_USING_NANA_FILESYSTEM false #define NANA_USING_STD_FILESYSTEM false #define NANA_USING_BOOST_FILESYSTEM false --- include/nana/filesystem/filesystem_selector.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index b0d3ae3a..5a8eac29 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -29,6 +29,10 @@ #include +#define NANA_USING_NANA_FILESYSTEM false +#define NANA_USING_STD_FILESYSTEM false +#define NANA_USING_BOOST_FILESYSTEM false + #if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) ) # include @@ -42,7 +46,7 @@ namespace std { # else using namespace nana::experimental::filesystem::v1; # endif - +#define NANA_USING_NANA_FILESYSTEM true } // filesystem } // experimental } // std @@ -56,12 +60,14 @@ namespace std { namespace experimental { namespace filesystem { using namespace boost::filesystem; +#define NANA_USING_BOOST_FILESYSTEM true } // filesystem } // experimental } // std #else # include +#define NANA_USING_STD_FILESYSTEM true #endif #ifndef __cpp_lib_experimental_filesystem From d0889784503ad1a47abbd9a8447fac617a56ea8a Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 09:19:56 +0200 Subject: [PATCH 218/309] more verbose pp macros --- include/nana/verbose_preprocessor.hpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp index 6a93c654..b19278b1 100644 --- a/include/nana/verbose_preprocessor.hpp +++ b/include/nana/verbose_preprocessor.hpp @@ -32,6 +32,8 @@ #define STRING2(x) #x #define STRING(x) STRING2(x) + #define SHOW_VALUE(x) "\n x=" STRING2(x) + #pragma message ( "\n ---> SVerbose preprocessor \nVERBOSE_PREPROCESSOR=" STRING(VERBOSE_PREPROCESSOR)" , \n STOP_VERBOSE_PREPROCESSOR=" STRING(STOP_VERBOSE_PREPROCESSOR) ) #pragma message ( "\n ---> OS: \nWindows: \n _WIN32=" STRING(_WIN32) ", \n __WIN32__ =" STRING(__WIN32__) " , \n WIN32=" STRING(WIN32)" , \n NANA_WINDOWS=" STRING(NANA_WINDOWS) ) @@ -58,6 +60,8 @@ #pragma message ( "\n CXX_NO_INLINE_NAMESPACE=" STRING(CXX_NO_INLINE_NAMESPACE) ", \n __has_include=" STRING(__has_include)" , \n __cpp_lib_experimental_filesystem=" STRING(__cpp_lib_experimental_filesystem) ) + #pragma message ( "\n NANA_USING_NANA_FILESYSTEM=" STRING(NANA_USING_NANA_FILESYSTEM) ", \n NANA_USING_STD_FILESYSTEM=" STRING(NANA_USING_STD_FILESYSTEM)" , \n NANA_USING_BOOST_FILESYSTEM=" STRING(NANA_USING_BOOST_FILESYSTEM) ) + #include #pragma message ( "\n ...including filesystem_selector: \n STD_put_time_NOT_SUPPORTED=" STRING(STD_put_time_NOT_SUPPORTED) " , \n STD_FILESYSTEM_NOT_SUPPORTED=" STRING(STD_FILESYSTEM_NOT_SUPPORTED)) @@ -66,7 +70,12 @@ #pragma message ( "\n CXX_NO_INLINE_NAMESPACE=" STRING(CXX_NO_INLINE_NAMESPACE) ", \n __has_include=" STRING(__has_include)" , \n __cpp_lib_experimental_filesystem=" STRING(__cpp_lib_experimental_filesystem) ) - // #pragma message ( "\n =" STRING() ", \n =" STRING()" , \n =" STRING() ) + #pragma message ( "\n NANA_USING_NANA_FILESYSTEM=" STRING(NANA_USING_NANA_FILESYSTEM) ", \n NANA_USING_STD_FILESYSTEM=" STRING(NANA_USING_STD_FILESYSTEM)" , \n NANA_USING_BOOST_FILESYSTEM=" STRING(NANA_USING_BOOST_FILESYSTEM) ) + + // #pragma message ( "\n =" STRING() ", \n =" STRING()" , \n =" STRING() ) + + #pragma message ( "\n Show value: =>\n " SHOW_VALUE(NANA_USING_NANA_FILESYSTEM) ) + #pragma message ( "\nUNICODE: \n NANA_UNICODE=" STRING(NANA_UNICODE) ", \n _UNICODE =" STRING(_UNICODE) " , \n UNICODE=" STRING(UNICODE) ) From d26eed8a78b4a6a2241dbcc246bd91894670535a Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 14:10:11 +0200 Subject: [PATCH 219/309] improve verbose pp --- include/nana/config.hpp | 2 +- .../nana/filesystem/filesystem_selector.hpp | 6 +- include/nana/verbose_preprocessor.hpp | 110 ++++++++++++------ 3 files changed, 81 insertions(+), 37 deletions(-) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index ae11279d..084bc1e0 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -109,7 +109,7 @@ #endif #if !defined(STOP_VERBOSE_PREPROCESSOR) -#define STOP_VERBOSE_PREPROCESSOR +//#define STOP_VERBOSE_PREPROCESSOR #endif #endif // NANA_IGNORE_CONFIG diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index 5a8eac29..338c1a6f 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -46,8 +46,8 @@ namespace std { # else using namespace nana::experimental::filesystem::v1; # endif -#define NANA_USING_NANA_FILESYSTEM true - } // filesystem +#undef NANA_USING_NANA_FILESYSTEM +#define NANA_USING_NANA_FILESYSTEM true } // filesystem } // experimental } // std @@ -60,6 +60,7 @@ namespace std { namespace experimental { namespace filesystem { using namespace boost::filesystem; +#undef NANA_USING_BOOST_FILESYSTEM #define NANA_USING_BOOST_FILESYSTEM true } // filesystem } // experimental @@ -67,6 +68,7 @@ namespace std { #else # include +#undef NANA_USING_STD_FILESYSTEM #define NANA_USING_STD_FILESYSTEM true #endif diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp index b19278b1..56c5f328 100644 --- a/include/nana/verbose_preprocessor.hpp +++ b/include/nana/verbose_preprocessor.hpp @@ -32,57 +32,99 @@ #define STRING2(x) #x #define STRING(x) STRING2(x) - #define SHOW_VALUE(x) "\n x=" STRING2(x) + #define SHOW_VALUE(x) " " #x " = " STRING2(x) - #pragma message ( "\n ---> SVerbose preprocessor \nVERBOSE_PREPROCESSOR=" STRING(VERBOSE_PREPROCESSOR)" , \n STOP_VERBOSE_PREPROCESSOR=" STRING(STOP_VERBOSE_PREPROCESSOR) ) + #pragma message ( "\n -----> Verbose preprocessor" ) + #pragma message ( SHOW_VALUE(VERBOSE_PREPROCESSOR) ) + #pragma message ( SHOW_VALUE(STOP_VERBOSE_PREPROCESSOR) ) - #pragma message ( "\n ---> OS: \nWindows: \n _WIN32=" STRING(_WIN32) ", \n __WIN32__ =" STRING(__WIN32__) " , \n WIN32=" STRING(WIN32)" , \n NANA_WINDOWS=" STRING(NANA_WINDOWS) ) + #pragma message ( "\n -----> OS: \n --Windows: " ) + #pragma message ( SHOW_VALUE(_WIN32) ) + #pragma message ( SHOW_VALUE(__WIN32__) ) + #pragma message ( SHOW_VALUE(WIN32) ) + #pragma message ( SHOW_VALUE(NANA_WINDOWS) ) - #pragma message ( "\nNIX: \n NANA_LINUX=" STRING(NANA_LINUX) ", \n NANA_POSIX=" STRING(NANA_POSIX) " , \n NANA_X11=" STRING(NANA_X11) " , \n APPLE=" STRING(APPLE) " , \n NANA_MACOS =" STRING(NANA_MACOS) " , \n NANA_IGNORE_CONF=" STRING(NANA_IGNORE_CONF) ) + #pragma message ( "\n ---NIX: " ) + #pragma message ( SHOW_VALUE(NANA_LINUX) ) + #pragma message ( SHOW_VALUE(NANA_POSIX) ) + #pragma message ( SHOW_VALUE(NANA_X11) ) + #pragma message ( SHOW_VALUE(APPLE) ) + #pragma message ( SHOW_VALUE(NANA_IGNORE_CONF) ) - #pragma message ( "\n ---> Compilers: \n MinGW: \n __MINGW32__=" STRING(__MINGW32__) ", \n __MINGW64__=" STRING(__MINGW64__) " , \n MINGW=" STRING(MINGW) ) - #pragma message ( "\nMSC: \n _MSC_VER=" STRING(_MSC_VER) ", \n _MSC_FULL_VER=" STRING(_MSC_FULL_VER ) ) + #pragma message ( "\n -----> Compilers: \n MinGW: " ) + #pragma message ( SHOW_VALUE(__MINGW32__) ) + #pragma message ( SHOW_VALUE(__MINGW64__) ) + #pragma message ( SHOW_VALUE(MINGW) ) - #pragma message ( "\nGNU: \n __GNUC__=" STRING(__GNUC__) ", \n __GNUC_MINOR__=" STRING(__GNUC_MINOR__) " , \n __GNUC_PATCHLEVEL__=" STRING(__GNUC_PATCHLEVEL__) ) + #pragma message ( "\n ---MSC: " ) + #pragma message ( SHOW_VALUE(_MSC_VER) ) + #pragma message ( SHOW_VALUE(_MSC_FULL_VER) ) - #pragma message ( "\nClang compiler: \n __clang__=" STRING(__clang__) ", \n __GLIBCPP__=" STRING(__GLIBCPP__) " , \n __GLIBCXX__=" STRING(__GLIBCXX__) ) + #pragma message ( "\n ---GNU: " ) + #pragma message ( SHOW_VALUE(__GNUC__) ) + #pragma message ( SHOW_VALUE(__GNUC_MINOR__) ) + #pragma message ( SHOW_VALUE(__GNUC_PATCHLEVEL__) ) - #pragma message ( "\n ---> STD: \n STD_CODECVT_NOT_SUPPORTED=" STRING(STD_CODECVT_NOT_SUPPORTED) " , \n STD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) + #pragma message ( "\n ---Clang compiler: " ) + #pragma message ( SHOW_VALUE(__clang__) ) + #pragma message ( SHOW_VALUE(__GLIBCPP__) ) + #pragma message ( SHOW_VALUE(__GLIBCXX__) ) - #pragma message ( "\n STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED=" STRING(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED) " , \n STD_TO_STRING_NOT_SUPPORTED=" STRING(STD_TO_STRING_NOT_SUPPORTED) ", \n STD_TO_WSTRING_NOT_SUPPORTED=" STRING(STD_TO_WSTRING_NOT_SUPPORTED)) + #pragma message ( "\n -----> STD: " ) + #pragma message ( SHOW_VALUE(STD_CODECVT_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_THREAD_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_TO_STRING_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_TO_WSTRING_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(USE_github_com_meganz_mingw_std_threads) ) + #pragma message ( SHOW_VALUE(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) ) + #pragma message ( SHOW_VALUE(STD_THREAD_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_put_time_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED) ) - #pragma message ( "\n USE_github_com_meganz_mingw_std_threads=" STRING(USE_github_com_meganz_mingw_std_threads) ", \n NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ=" STRING(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)" , \n STD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) - - #pragma message ( "\n STD_put_time_NOT_SUPPORTED=" STRING(STD_put_time_NOT_SUPPORTED) " , \n STD_MAKE_UNIQUE_NOT_SUPPORTED=" STRING(STD_MAKE_UNIQUE_NOT_SUPPORTED)" , \n STD_FILESYSTEM_NOT_SUPPORTED=" STRING(STD_FILESYSTEM_NOT_SUPPORTED)) - - #pragma message ( "\n BOOST_FILESYSTEM_AVAILABLE=" STRING(BOOST_FILESYSTEM_AVAILABLE) ", \n BOOST_FILESYSTEM_FORCE =" STRING(BOOST_FILESYSTEM_FORCE) " , \n STD_FILESYSTEM_FORCE=" STRING(STD_FILESYSTEM_FORCE) ", \n NANA_FILESYSTEM_FORCE=" STRING(NANA_FILESYSTEM_FORCE) ) - - #pragma message ( "\n CXX_NO_INLINE_NAMESPACE=" STRING(CXX_NO_INLINE_NAMESPACE) ", \n __has_include=" STRING(__has_include)" , \n __cpp_lib_experimental_filesystem=" STRING(__cpp_lib_experimental_filesystem) ) - - #pragma message ( "\n NANA_USING_NANA_FILESYSTEM=" STRING(NANA_USING_NANA_FILESYSTEM) ", \n NANA_USING_STD_FILESYSTEM=" STRING(NANA_USING_STD_FILESYSTEM)" , \n NANA_USING_BOOST_FILESYSTEM=" STRING(NANA_USING_BOOST_FILESYSTEM) ) + #pragma message ( SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(BOOST_FILESYSTEM_AVAILABLE) ) + #pragma message ( SHOW_VALUE(BOOST_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(STD_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(NANA_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(CXX_NO_INLINE_NAMESPACE) ) + //#pragma message ( SHOW_VALUE(__has_include) ) + #pragma message ( SHOW_VALUE(__cpp_lib_experimental_filesystem) ) + #pragma message ( SHOW_VALUE(NANA_USING_NANA_FILESYSTEM) ) + #pragma message ( SHOW_VALUE(NANA_USING_STD_FILESYSTEM) ) + #pragma message ( SHOW_VALUE(NANA_USING_BOOST_FILESYSTEM) ) + #pragma message ( "\n#include " ) #include - #pragma message ( "\n ...including filesystem_selector: \n STD_put_time_NOT_SUPPORTED=" STRING(STD_put_time_NOT_SUPPORTED) " , \n STD_FILESYSTEM_NOT_SUPPORTED=" STRING(STD_FILESYSTEM_NOT_SUPPORTED)) + #pragma message ( SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED) ) + #pragma message ( SHOW_VALUE(BOOST_FILESYSTEM_AVAILABLE) ) + #pragma message ( SHOW_VALUE(BOOST_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(STD_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(NANA_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(CXX_NO_INLINE_NAMESPACE) ) + //#pragma message ( SHOW_VALUE(__has_include) ) + #pragma message ( SHOW_VALUE(__cpp_lib_experimental_filesystem) ) + #pragma message ( SHOW_VALUE(NANA_USING_NANA_FILESYSTEM) ) + #pragma message ( SHOW_VALUE(NANA_USING_STD_FILESYSTEM) ) + #pragma message ( SHOW_VALUE(NANA_USING_BOOST_FILESYSTEM) ) - #pragma message ( "\n BOOST_FILESYSTEM_AVAILABLE=" STRING(BOOST_FILESYSTEM_AVAILABLE) ", \n BOOST_FILESYSTEM_FORCE =" STRING(BOOST_FILESYSTEM_FORCE) " , \n STD_FILESYSTEM_FORCE=" STRING(STD_FILESYSTEM_FORCE) ", \n NANA_FILESYSTEM_FORCE=" STRING(NANA_FILESYSTEM_FORCE) ) + #pragma message ( SHOW_VALUE(NANA_UNICODE) ) + #pragma message ( SHOW_VALUE(_UNICODE) ) + #pragma message ( SHOW_VALUE(UNICODE) ) - #pragma message ( "\n CXX_NO_INLINE_NAMESPACE=" STRING(CXX_NO_INLINE_NAMESPACE) ", \n __has_include=" STRING(__has_include)" , \n __cpp_lib_experimental_filesystem=" STRING(__cpp_lib_experimental_filesystem) ) - - #pragma message ( "\n NANA_USING_NANA_FILESYSTEM=" STRING(NANA_USING_NANA_FILESYSTEM) ", \n NANA_USING_STD_FILESYSTEM=" STRING(NANA_USING_STD_FILESYSTEM)" , \n NANA_USING_BOOST_FILESYSTEM=" STRING(NANA_USING_BOOST_FILESYSTEM) ) + #pragma message ( "\n -----> Libraries: " ) + #pragma message ( SHOW_VALUE(NANA_ENABLE_AUDIO) ) + #pragma message ( SHOW_VALUE(NANA_ENABLE_PNG) ) + #pragma message ( SHOW_VALUE(USE_LIBPNG_FROM_OS) ) + #pragma message ( SHOW_VALUE(NANA_LIBPNG) ) + #pragma message ( SHOW_VALUE(NANA_ENABLE_JPEG) ) + #pragma message ( SHOW_VALUE(USE_LIBJPEG_FROM_OS) ) + #pragma message ( SHOW_VALUE(NANA_LIBJPEG) ) // #pragma message ( "\n =" STRING() ", \n =" STRING()" , \n =" STRING() ) - - #pragma message ( "\n Show value: =>\n " SHOW_VALUE(NANA_USING_NANA_FILESYSTEM) ) - - - #pragma message ( "\nUNICODE: \n NANA_UNICODE=" STRING(NANA_UNICODE) ", \n _UNICODE =" STRING(_UNICODE) " , \n UNICODE=" STRING(UNICODE) ) - - #pragma message ( "\n ---> Libraries: \n NANA_ENABLE_AUDIO=" STRING(NANA_ENABLE_AUDIO) ", \n NANA_ENABLE_PNG =" STRING(NANA_ENABLE_PNG) " , \n USE_LIBPNG_FROM_OS=" STRING(USE_LIBPNG_FROM_OS) " , \n NANA_LIBPNG=" STRING(NANA_LIBPNG) ) - - #pragma message ( "\n NANA_ENABLE_JPEG=" STRING(NANA_ENABLE_JPEG) ", \n USE_LIBJPEG_FROM_OS =" STRING(USE_LIBJPEG_FROM_OS) " , \n NANA_LIBJPEG=" STRING(NANA_LIBJPEG) ) - #if defined(STOP_VERBOSE_PREPROCESSOR) #error ("\nCompilation stopped to avoid annoying messages") From 747b301b328396e50939191fe69c965ed698deb9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 14:29:27 +0200 Subject: [PATCH 220/309] typo --- include/nana/filesystem/filesystem_selector.hpp | 3 ++- include/nana/verbose_preprocessor.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index 338c1a6f..6d46444d 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -47,7 +47,8 @@ namespace std { using namespace nana::experimental::filesystem::v1; # endif #undef NANA_USING_NANA_FILESYSTEM -#define NANA_USING_NANA_FILESYSTEM true } // filesystem +#define NANA_USING_NANA_FILESYSTEM true + } // filesystem } // experimental } // std diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp index 56c5f328..aa0cf104 100644 --- a/include/nana/verbose_preprocessor.hpp +++ b/include/nana/verbose_preprocessor.hpp @@ -123,6 +123,7 @@ #pragma message ( SHOW_VALUE(NANA_ENABLE_JPEG) ) #pragma message ( SHOW_VALUE(USE_LIBJPEG_FROM_OS) ) #pragma message ( SHOW_VALUE(NANA_LIBJPEG) ) + // #pragma message ( "\n =" STRING() ", \n =" STRING()" , \n =" STRING() ) From 972ecc97ac030e917d4309f4ffe0f52609687d96 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 14:36:24 +0200 Subject: [PATCH 221/309] improve NANA_LINKS ? --- CMakeLists.txt | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79ffc023..135e4dc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,8 +26,6 @@ project(nana) cmake_minimum_required(VERSION 2.8) -set(NANA_LINKS) - option(NANA_CMAKE_INSTALL_INCLUDES "Install nana includes when compile the library" ON) option(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF) option(NANA_CMAKE_ENABLE_PNG "Enable the use of PNG" OFF) @@ -63,7 +61,7 @@ option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if avail #option(NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") #option(NANA_CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") #include_directories("${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") -#list(APPEND NANA_LINKS "${NANA_CMAKE_BOOST_FILESYSTEM_LIB}" ) +#set(NANA_LINKS "${NANA_LINKS} ${NANA_CMAKE_BOOST_FILESYSTEM_LIB}") if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) @@ -84,11 +82,11 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) # If using Boost::thread, then Thread::Thread will also be added automatically. find_package(Boost COMPONENTS filesystem) if (Boost_FOUND) - add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) + add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) include_directories(SYSTEM "${Boost_INCLUDE_DIR}") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") - list(APPEND NANA_LINKS "${Boost_LIBRARIES}") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") + set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) set(Boost_USE_STATIC_LIBS ON) @@ -133,7 +131,7 @@ endif(WIN32) if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) - list(APPEND NANA_LINKS -L/opt/X11/lib/ -liconv) + set(NANA_LINKS "${NANA_LINKS} -L/opt/X11/lib/ -liconv") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ -liconv") set(ENABLE_AUDIO OFF) @@ -143,7 +141,7 @@ elseif(UNIX) endif(APPLE) if(UNIX) - list(APPEND NANA_LINKS -lX11 ) + set(NANA_LINKS "${NANA_LINKS} -lX11") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lX11") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lX11") find_package(Freetype) @@ -151,7 +149,7 @@ if(UNIX) include_directories( ${FREETYPE_INCLUDE_DIRS}) #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lXft") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lXft") - list(APPEND NANA_LINKS -lXft ) + set(NANA_LINKS "${NANA_LINKS} -lXft") endif(FREETYPE_FOUND) endif(UNIX) @@ -162,7 +160,7 @@ endif(UNIX) if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) #set(NANA_PNG_LIB "png") - list(APPEND NANA_LINKS -lpng ) + set(NANA_LINKS "${NANA_LINKS} -lpng") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpng") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpng") if(NANA_CMAKE_LIBPNG_FROM_OS) @@ -178,7 +176,7 @@ endif(NANA_CMAKE_ENABLE_PNG) if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) #set(NANA_JPEG_LIB "jpeg") - list(APPEND NANA_LINKS -ljpeg ) + set(NANA_LINKS "${NANA_LINKS} -ljpeg") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ljpeg") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljpeg") if(NANA_CMAKE_LIBJPEG_FROM_OS) @@ -196,7 +194,7 @@ if(NANA_CMAKE_ENABLE_AUDIO) find_package(ASOUND) if (ASOUND_FOUND) include_directories( ${ASOUND_INCLUDE_DIRS}) - list(APPEND NANA_LINKS -lasound ) + set(NANA_LINKS "${NANA_LINKS} -lasound") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lasound") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasound") else(ASOUND_FOUND) @@ -242,7 +240,7 @@ endforeach(subdir ${NANA_SOURCE_SUBDIRS}) include_directories(${NANA_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) # ${NANA_LINKS} or ${ } +target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) @@ -354,8 +352,8 @@ if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND N if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) # IS_GNUCXX < 5.3 else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - set(CMAKE_EXE_LINKER_FLAGS " -lstdc++fs ${CMAKE_EXE_LINKER_FLAGS}") # IS_GNUCXX 5.3 or more - set(NANA_LINKS " -lstdc++fs ${NANA_LINKS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs ") # IS_GNUCXX 5.3 or more + set(NANA_LINKS "${NANA_LINKS} -lstdc++fs ") endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) From 9a85b5315a4aaa93fd9b7ff4f8f67c889c82f754 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 14:44:15 +0200 Subject: [PATCH 222/309] trailing space is an error --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 135e4dc2..8dcb0ee4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,8 +352,8 @@ if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND N if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) # IS_GNUCXX < 5.3 else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs ") # IS_GNUCXX 5.3 or more - set(NANA_LINKS "${NANA_LINKS} -lstdc++fs ") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more + set(NANA_LINKS "${NANA_LINKS} -lstdc++fs") endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) From 8fed40f33477465305d5b233cfe8165fc9ccafb6 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 14:52:53 +0200 Subject: [PATCH 223/309] leding space is an error --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dcb0ee4..b9b0d190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) include_directories(SYSTEM "${Boost_INCLUDE_DIR}") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") - set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") + set(NANA_LINKS "${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add ${NANA_LINKS} is not first #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) @@ -131,7 +131,7 @@ endif(WIN32) if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) - set(NANA_LINKS "${NANA_LINKS} -L/opt/X11/lib/ -liconv") + set(NANA_LINKS "${NANA_LINKS} -L/opt/X11/lib/ -liconv") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ -liconv") set(ENABLE_AUDIO OFF) From 599e84e73ad4b7d0dde2d90167cf1779c240c473 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 15:00:12 +0200 Subject: [PATCH 224/309] NANA_CMAKE_FIND_BOOST_FILESYSTEM=OFF --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 71fe6094..fff0412b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,7 @@ before_script : - cd bin script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=OFF -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - cd .. - mv -v bin/ nana-demo/ From e918fa604e72c3c667c0ea34923ed3cd760a4351 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 15:05:22 +0200 Subject: [PATCH 225/309] leading space ? --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9b0d190..97d8677b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) include_directories(SYSTEM "${Boost_INCLUDE_DIR}") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") - set(NANA_LINKS "${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add ${NANA_LINKS} is not first + set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add is not first #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) @@ -240,7 +240,7 @@ endforeach(subdir ${NANA_SOURCE_SUBDIRS}) include_directories(${NANA_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) +target_link_libraries(${PROJECT_NAME}${NANA_LINKS}) # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) From 1626e8193be28dc5bbfb8d96810915067b010993 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 15:43:09 +0200 Subject: [PATCH 226/309] reorganize --- CMakeLists.txt | 154 +++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97d8677b..ab8970c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,37 +64,6 @@ option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if avail #set(NANA_LINKS "${NANA_LINKS} ${NANA_CMAKE_BOOST_FILESYSTEM_LIB}") -if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) - add_definitions(-DNANA_FILESYSTEM_FORCE) - -elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE) - add_definitions(-DSTD_FILESYSTEM_FORCE) - -elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) - - if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) - add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) - endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) - - # https://cmake.org/cmake/help/git-master/module/FindBoost.html - # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, - # even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries. - # If using Boost::thread, then Thread::Thread will also be added automatically. - find_package(Boost COMPONENTS filesystem) - if (Boost_FOUND) - add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) - include_directories(SYSTEM "${Boost_INCLUDE_DIR}") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") - set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add is not first - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") - endif (Boost_FOUND) - - set(Boost_USE_STATIC_LIBS ON) - set(Boost_USE_STATIC_RUNTIME ON) # ?? - #set(Boost_USE_MULTITHREADED ON) - -endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) - ########### Compatibility with CMake 3.1 @@ -154,6 +123,52 @@ if(UNIX) endif(UNIX) +########### Compliers +# +# Using gcc: gcc 4.8 don't sopourt C++14 and make_unique. You may want to update at least to 4.9. +# In Windows, the gcc which come with CLion was 4.8 from MinGW. You may want to install MinGW-w64 from the +# TDM-GCC Compiler Suite for Windows which will update you to gcc 5.1. +# gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs +# +# see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html + +# set compile flags +if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU + + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") # Clang + + else ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") # GNU + + endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + +endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + +# enable static linkage +if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) # GNU || CLang not MinGW + #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") + + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + # IS_GNUCXX < 5.3 + else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more + set(NANA_LINKS "${NANA_LINKS} -lstdc++fs") + endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) + +endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) + + +if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") +endif () + +# set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") + + + + ############# Optional libraries #Find PNG @@ -203,6 +218,39 @@ if(NANA_CMAKE_ENABLE_AUDIO) endif(UNIX) endif(NANA_CMAKE_ENABLE_AUDIO) +if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) + add_definitions(-DNANA_FILESYSTEM_FORCE) + +elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE) + add_definitions(-DSTD_FILESYSTEM_FORCE) + +elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) + + if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) + add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) + endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) + + # https://cmake.org/cmake/help/git-master/module/FindBoost.html + # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, + # even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries. + # If using Boost::thread, then Thread::Thread will also be added automatically. + find_package(Boost COMPONENTS filesystem) + if (Boost_FOUND) + add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) + include_directories(SYSTEM "${Boost_INCLUDE_DIR}") + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") + set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add is not first + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") + endif (Boost_FOUND) + + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_STATIC_RUNTIME ON) # ?? + #set(Boost_USE_MULTITHREADED ON) + +endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) + + + if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) @@ -240,7 +288,7 @@ endforeach(subdir ${NANA_SOURCE_SUBDIRS}) include_directories(${NANA_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME}${NANA_LINKS}) +target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) @@ -323,48 +371,6 @@ if (NANA_CMAKE_BUILD_DEMOS) endif (NANA_CMAKE_BUILD_DEMOS) -# -# Using gcc: gcc 4.8 don't sopourt C++14 and make_unique. You may want to update at least to 4.9. -# In Windows, the gcc which come with CLion was 4.8 from MinGW. You may want to install MinGW-w64 from the -# TDM-GCC Compiler Suite for Windows which will update you to gcc 5.1. -# gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs -# -# see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html - -# set compile flags -if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU - - if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") # Clang - - else ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") # GNU - - endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - -endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - -# enable static linkage -if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) # GNU || CLang not MinGW - #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") - - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - # IS_GNUCXX < 5.3 - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more - set(NANA_LINKS "${NANA_LINKS} -lstdc++fs") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - -endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) - - -if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") -endif () - -# set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") - message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) From 9975984d91ef9fd30370233979084a715c5ce788 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 16:01:39 +0200 Subject: [PATCH 227/309] set POLICY CMP0004 OLD # ignore leading space --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab8970c8..578e2390 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,11 @@ if(POLICY CMP0054) cmake_policy(SET CMP0054 OLD) endif() +if(POLICY CMP0004) # ignore leading space + # http://www.cmake.org/cmake/help/v3.0/policy/CMP0004.html + cmake_policy(SET CMP0004 OLD) +endif() + add_definitions(-DNANA_IGNORE_CONF) From d860daa9acdb38f1958e6968772be5a1d6c37c5f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 23 Jun 2016 16:10:40 +0200 Subject: [PATCH 228/309] NANA_CMAKE_FIND_BOOST_FILESYSTEM=ON --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fff0412b..71fe6094 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,7 +76,7 @@ before_script : - cd bin script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=OFF -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - cd .. - mv -v bin/ nana-demo/ From 880d0becf35096d875a1e169f57572712603cd1a Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 00:25:26 +0800 Subject: [PATCH 229/309] some improvements, deprecated frame widget --- include/nana/config.hpp | 3 + include/nana/gui/basis.hpp | 28 +- include/nana/gui/detail/basic_window.hpp | 67 +++-- include/nana/gui/detail/bedrock.hpp | 4 +- include/nana/gui/detail/drawer.hpp | 45 ++- include/nana/gui/detail/effects_renderer.hpp | 4 +- include/nana/gui/detail/window_manager.hpp | 2 + include/nana/gui/programming_interface.hpp | 25 +- include/nana/gui/widgets/form.hpp | 25 +- include/nana/gui/widgets/frame.hpp | 3 + .../gui/widgets/skeletons/text_editor.hpp | 4 +- include/nana/gui/widgets/widget.hpp | 31 +-- source/gui/detail/basic_window.cpp | 258 +++++++++--------- source/gui/detail/bedrock_pi.cpp | 36 +-- source/gui/detail/bedrock_posix.cpp | 18 +- source/gui/detail/bedrock_windows.cpp | 14 +- source/gui/detail/drawer.cpp | 77 ++++-- source/gui/detail/window_layout.cpp | 2 + source/gui/detail/window_manager.cpp | 48 +++- source/gui/programming_interface.cpp | 194 +++++++------ source/gui/widgets/form.cpp | 52 +++- source/gui/widgets/frame.cpp | 4 + source/gui/widgets/skeletons/text_editor.cpp | 81 +++--- source/paint/pixel_buffer.cpp | 13 +- 24 files changed, 603 insertions(+), 435 deletions(-) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index ae11279d..88781d84 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -93,6 +93,9 @@ #endif #endif +//This marco is defined since 1.4 and until 1.5 for deprecating frame widget. +//This marco and class frame will be removed in version 1.5 +#define WIDGET_FRAME_DEPRECATED /////////////////// // Support for NANA_AUTOMATIC_GUI_TESTING diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index 744fa9ba..a80ff3da 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -56,14 +56,18 @@ namespace nana super, widget = 0x1, lite_widget = 0x3, - root = 0x5, - frame = 0x9 + root = 0x5 +#ifndef WIDGET_FRAME_DEPRECATED + ,frame = 0x9 +#endif }; //wait for constexpr struct widget_tag{ static const flags value = flags::widget; }; struct lite_widget_tag : public widget_tag{ static const flags value = flags::lite_widget; }; struct root_tag : public widget_tag{ static const flags value = flags::root; }; +#ifndef WIDGET_FRAME_DEPRECATED struct frame_tag : public widget_tag{ static const flags value = flags::frame; }; +#endif }// end namespace category using native_window_type = detail::native_window_handle_impl*; @@ -260,6 +264,26 @@ that return a corresponding nana::appearance with predefined values. } }; };//end namespace apper + + /// Interface for caret operations + class caret_interface + { + public: + virtual ~caret_interface() = default; + + virtual void disable_throw() noexcept = 0; + + virtual void effective_range(const rectangle& range) = 0; + + virtual void position(const point& pos) = 0; + virtual point position() const = 0; + + virtual void dimension(const size& size) = 0; + virtual size dimension() const = 0; + + virtual void visible(bool visibility) = 0; + virtual bool visible() const = 0; + };//end class caret_interface }//end namespace nana #include diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 6d44a936..01ccb589 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -32,32 +32,37 @@ namespace detail invisible, visible, displayed }; - class caret_descriptor + class caret + : public caret_interface { public: - typedef basic_window core_window_t; + caret(basic_window* owner, const size& size); + ~caret(); - caret_descriptor(core_window_t*, unsigned width, unsigned height); - ~caret_descriptor(); - void set_active(bool); - core_window_t* window() const; - void position(int x, int y); - void effective_range(::nana::rectangle); - ::nana::point position() const; - void visible(bool isshow); - bool visible() const; - ::nana::size size() const; - void size(const ::nana::size&); + void activate(bool activity); + basic_window* owner() const noexcept; void update(); + public: + //Implement caret_interface functions + + //This function is useless for class caret, see caret_proxy. + void disable_throw() noexcept override; + void effective_range(const rectangle& r) override; + void position(const point& pos) override; + nana::point position() const override; + size dimension() const override; + void dimension(const size& s); + void visible(bool visibility) override; + bool visible() const override; private: - core_window_t* wd_; - ::nana::point point_; - ::nana::size size_; - ::nana::size paint_size_; - visible_state visible_state_; - bool out_of_range_; - ::nana::rectangle effective_range_; - };//end class caret_descriptor + basic_window * owner_; + point position_; + size size_; + size visual_size_; + visible_state visibility_{ visible_state::invisible }; + bool out_of_range_{ false }; + rectangle effect_range_; + };//end class caret /// Define some constant about tab category, these flags can be combine with operator | struct tab_type @@ -70,6 +75,8 @@ namespace detail }; }; + class caret; + /// a window data structure descriptor struct basic_window : public events_holder @@ -107,7 +114,9 @@ namespace detail /// bind a native window and baisc_window void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&); +#ifndef WIDGET_FRAME_DEPRECATED void frame_window(native_window_type); +#endif bool is_ancestor_of(const basic_window* wd) const; bool visible_parents() const; @@ -174,13 +183,15 @@ namespace detail mouse_action action_before; }flags; - struct + + struct annex_components { - caret_descriptor* caret; + caret* caret_ptr{ nullptr }; + + //The following pointers refer to the widget's object. std::shared_ptr events_ptr; - }together; - - widget_geometrics* scheme{ nullptr }; + widget_geometrics* scheme{ nullptr }; + }annex; struct { @@ -191,11 +202,13 @@ namespace detail struct other_tag { +#ifndef WIDGET_FRAME_DEPRECATED struct attr_frame_tag { native_window_type container{nullptr}; std::vector attach; }; +#endif struct attr_root_tag { @@ -223,7 +236,9 @@ namespace detail union { attr_root_tag * root; +#ifndef WIDGET_FRAME_DEPRECATED attr_frame_tag * frame; +#endif }attribute; other_tag(category::flags); diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 32a812ad..cda91c98 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -82,9 +82,7 @@ namespace detail void define_state_cursor(core_window_t*, nana::cursor, thread_context*); void undefine_state_cursor(core_window_t*, thread_context*); - widget_geometrics& get_scheme_template(scheme_factory_interface&&); - widget_geometrics* make_scheme(scheme_factory_interface&&); - + color_schemes& scheme(); events_operation& evt_operation(); window_manager& wd_manager(); diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index 26061033..e313c172 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -14,7 +14,6 @@ #define NANA_GUI_DETAIL_DRAWER_HPP #include -#include #include "general_events.hpp" #include #include @@ -29,14 +28,23 @@ namespace nana } class drawer_trigger - : ::nana::noncopyable, ::nana::nonmovable { friend class detail::drawer; + + //Noncopyable + drawer_trigger(const drawer_trigger&) = delete; + drawer_trigger& operator=(const drawer_trigger&) = delete; + + //Nonmovable + drawer_trigger(drawer_trigger&&) = delete; + drawer_trigger& operator=(drawer_trigger&&) = delete; + public: using widget_reference = widget&; using graph_reference = paint::graphics&; - virtual ~drawer_trigger(); + drawer_trigger() = default; + virtual ~drawer_trigger() = default; virtual void attached(widget_reference, graph_reference); //none-const virtual void detached(); //none-const @@ -73,21 +81,11 @@ namespace nana { struct basic_window; - namespace dynamic_drawing - { - //declaration - class object; - } - //@brief: Every window has a drawer, the drawer holds a drawer_trigger for // a widget. class drawer : nana::noncopyable, nana::nonmovable { - enum{ - event_size = static_cast(event_code::end) - }; - enum class method_state { pending, @@ -95,6 +93,7 @@ namespace nana not_overrided }; public: + drawer(); ~drawer(); void bind(basic_window*); @@ -136,21 +135,21 @@ namespace nana void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr) { const int pos = static_cast(evt_code); - if (realizer_ && (method_state::not_overrided != mth_state_[pos])) + if (data_impl_->realizer && (method_state::not_overrided != data_impl_->mth_state[pos])) { _m_bground_pre(); - if (method_state::pending == mth_state_[pos]) + if (method_state::pending == data_impl_->mth_state[pos]) { - (realizer_->*mfptr)(graphics, arg); + (data_impl_->realizer->*mfptr)(graphics, arg); //Check realizer, when the window is closed in that event handler, the drawer will be //detached and realizer will be a nullptr - if(realizer_) - mth_state_[pos] = (realizer_->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); + if (data_impl_->realizer) + data_impl_->mth_state[pos] = (data_impl_->realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); } else - (realizer_->*mfptr)(graphics, arg); + (data_impl_->realizer->*mfptr)(graphics, arg); if (_m_lazy_decleared()) { @@ -162,11 +161,9 @@ namespace nana public: nana::paint::graphics graphics; private: - basic_window* core_window_{nullptr}; - drawer_trigger* realizer_{nullptr}; - std::vector dynamic_drawing_objects_; - bool refreshing_{false}; - method_state mth_state_[event_size]; + struct data_implement; + + data_implement * const data_impl_; }; }//end namespace detail }//end namespace nana diff --git a/include/nana/gui/detail/effects_renderer.hpp b/include/nana/gui/detail/effects_renderer.hpp index f7bd7d03..155fcb78 100644 --- a/include/nana/gui/detail/effects_renderer.hpp +++ b/include/nana/gui/detail/effects_renderer.hpp @@ -174,12 +174,12 @@ namespace nana{ good_r.x = good_r.y = 1; good_r.width = r.width - 2; good_r.height = r.height - 2; - pixbuf.rectangle(good_r, wd->scheme->activated.get_color(), 0.95, false); + pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.95, false); good_r.x = good_r.y = 0; good_r.width = r.width; good_r.height = r.height; - pixbuf.rectangle(good_r, wd->scheme->activated.get_color(), 0.4, false); + pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.4, false); pixbuf.pixel(0, 0, px0); pixbuf.pixel(r.width - 1, 0, px1); diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index cab6ecb1..d2a83d3e 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -94,10 +94,12 @@ namespace detail core_window_t* create_root(core_window_t*, bool nested, rectangle, const appearance&, widget*); core_window_t* create_widget(core_window_t*, const rectangle&, bool is_lite, widget*); +#ifndef WIDGET_FRAME_DEPRECATED core_window_t* create_frame(core_window_t*, const rectangle&, widget*); bool insert_frame(core_window_t* frame, native_window); bool insert_frame(core_window_t* frame, core_window_t*); +#endif void close(core_window_t*); //destroy diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 23d5aee8..62125e65 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -80,8 +80,9 @@ namespace API window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached); window create_widget(window, const rectangle&, widget* attached); window create_lite_widget(window, const rectangle&, widget* attached); +#ifndef WIDGET_FRAME_DEPRECATED window create_frame(window, const rectangle&, widget* attached); - +#endif paint::graphics* window_graphics(window); void delay_restore(bool); @@ -201,9 +202,12 @@ namespace API void fullscreen(window, bool); bool enabled_double_click(window, bool); + +#ifndef WIDGET_FRAME_DEPRECATED bool insert_frame(window frame, native_window_type); native_window_type frame_container(window frame); native_window_type frame_element(window frame, unsigned index); +#endif void close_window(window); void show_window(window, bool show); ///< Sets a window visible state. void restore_window(window); @@ -334,15 +338,18 @@ namespace API color activated_color(window); color activated_color(window, const color&); - void create_caret(window, unsigned width, unsigned height); + void create_caret(window, const size&); void destroy_caret(window); - void caret_effective_range(window, const rectangle&); - void caret_pos(window, const ::nana::point&); - nana::point caret_pos(window); - nana::size caret_size(window); - void caret_size(window, const size&); - void caret_visible(window, bool is_show); - bool caret_visible(window); + + /// Opens an existing caret of a window. + /** + * This function returns an object to operate caret. The object doesn't create or destroy the caret. + * When you are finished with the caret, be sure to reset the pointer. + * + * @param window_handle A handle to a window whose caret is to be retrieved + * @return a pointer to the caret proxy. nullptr if the window doesn't have a caret. + */ + ::std::unique_ptr open_caret(window window_handle, bool disable_throw = false); /// Enables that the user can give input focus to the specified window using TAB key. void tabstop(window); diff --git a/include/nana/gui/widgets/form.hpp b/include/nana/gui/widgets/form.hpp index 66047576..77972a8b 100644 --- a/include/nana/gui/widgets/form.hpp +++ b/include/nana/gui/widgets/form.hpp @@ -14,9 +14,12 @@ #define NANA_GUI_WIDGET_FORM_HPP #include "widget.hpp" +#include namespace nana { + class place; + namespace drawerbase { namespace form @@ -29,12 +32,29 @@ namespace nana private: widget* wd_{nullptr}; }; + + class form_base + : public widget_object + { + public: + form_base(window owner, bool nested, const rectangle&, const appearance&); + + //place methods + + place & get_place(); + void div(const char* div_text); + place::field_reference operator[](const char* field_name); + void collocate() noexcept; + private: + std::unique_ptr place_; + }; }//end namespace form }//end namespace drawerbase /// \brief Pop-up window. Is different from other window widgets: its default constructor create the window. /// \see nana::appearance - class form: public widget_object + class form + : public drawerbase::form::form_base { public: using appear = ::nana::appear; @@ -50,7 +70,8 @@ namespace nana void wait_for_this(); }; - class nested_form : public widget_object + class nested_form + : public drawerbase::form::form_base { public: using appear = ::nana::appear; diff --git a/include/nana/gui/widgets/frame.hpp b/include/nana/gui/widgets/frame.hpp index 6cc91dce..82a53d95 100644 --- a/include/nana/gui/widgets/frame.hpp +++ b/include/nana/gui/widgets/frame.hpp @@ -16,6 +16,8 @@ #define NANA_GUI_WIDGET_FRAME_HPP #include "widget.hpp" + +#ifndef WIDGET_FRAME_DEPRECATED namespace nana { /** @@ -51,3 +53,4 @@ namespace nana }; }//end namespace nana #endif +#endif diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 92b6a5ac..c1fb06fa 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -308,7 +308,8 @@ namespace nana{ namespace widgets void _m_offset_y(int y); - unsigned _m_char_by_pixels(const wchar_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl); + unsigned _m_char_by_pixels(const unicode_bidi::entity&, unsigned pos); + unsigned _m_pixels_by_char(const ::std::wstring&, std::size_t pos) const; void _handle_move_key(const arg_keyboard& arg); @@ -316,6 +317,7 @@ namespace nana{ namespace widgets std::unique_ptr behavior_; undoable undo_; nana::window window_; + std::unique_ptr caret_; graph_reference graph_; const text_editor_scheme* scheme_; event_interface * event_handler_{ nullptr }; diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 952cd2a4..5e1ad652 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -14,7 +14,6 @@ #define NANA_GUI_WIDGET_HPP #include -#include #include "../programming_interface.hpp" #include #include @@ -391,33 +390,6 @@ namespace nana { return API::window_outline_size(handle()); } - - place & get_place() - { - if (this->empty()) - throw std::runtime_error("form::get_plac: the form has destroyed."); - - if (!place_) - place_.reset(new place{ *this }); - - return *place_; - } - - void div(const char* div_text) - { - get_place().div(div_text); - } - - place::field_reference operator[](const char* field_name) - { - return get_place()[field_name]; - } - - void collocate() noexcept - { - if (place_) - place_->collocate(); - } protected: DrawerTrigger& get_drawer_trigger() { @@ -447,9 +419,9 @@ namespace nana DrawerTrigger trigger_; std::shared_ptr events_; std::unique_ptr scheme_; - std::unique_ptr place_; };//end class widget_object +#ifndef WIDGET_FRAME_DEPRECATED /// Base class of all the classes defined as a frame window. \see nana::frame template class widget_object: public widget{}; @@ -509,6 +481,7 @@ namespace nana std::shared_ptr events_; std::unique_ptr scheme_; };//end class widget_object +#endif }//end namespace nana #include diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 5c149ec3..a7cbd2e6 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -17,188 +17,194 @@ namespace nana { namespace detail { - //class caret_descriptor - caret_descriptor::caret_descriptor(core_window_t* wd, unsigned width, unsigned height) - :wd_(wd), size_(width, height), visible_state_(visible_state::invisible), out_of_range_(false) + //class caret + caret::caret(basic_window* owner, const size& size): + owner_(owner), + size_(size) {} - caret_descriptor::~caret_descriptor() + caret::~caret() { - if(wd_) native_interface::caret_destroy(wd_->root); + if (owner_) + native_interface::caret_destroy(owner_->root); } - void caret_descriptor::set_active(bool active) + void caret::activate(bool activity) { - if(wd_) + if (owner_) { - if(active) + if (activity) { - native_interface::caret_create(wd_->root, size_); + native_interface::caret_create(owner_->root, size_); - visible_state_ = visible_state::invisible; - this->position(point_.x, point_.y); + visibility_ = visible_state::invisible; + this->position(position_); } else - native_interface::caret_destroy(wd_->root); + native_interface::caret_destroy(owner_->root); - wd_->root_widget->other.attribute.root->ime_enabled = active; + owner_->root_widget->other.attribute.root->ime_enabled = activity; } } - auto caret_descriptor::window() const ->core_window_t* + basic_window* caret::owner() const noexcept { - return wd_; + return owner_; } - void caret_descriptor::position(int x, int y) + void caret::update() { - point_.x = x; - point_.y = y; + auto pos = position_; + auto size = size_; - update(); - } - - void caret_descriptor::effective_range(nana::rectangle rect) - { - //Chech rect - if (rect.width && rect.height && rect.right() > 0 && rect.bottom() > 0) - { - if(rect.x < 0) - { - rect.width += rect.x; - rect.x = 0; - } - - if(rect.y < 0) - { - rect.height += rect.y; - rect.y = 0; - } - - if(effective_range_ != rect) - { - effective_range_ = rect; - update(); - } - } - } - - nana::point caret_descriptor::position() const - { - return point_; - } - - void caret_descriptor::visible(bool is_show) - { - auto pre_displayed = (visible_state::displayed == visible_state_); - - if (is_show) - { - visible_state_ = visible_state::visible; - if (wd_->displayed() && (! out_of_range_)) - visible_state_ = visible_state::displayed; - } - else - visible_state_ = visible_state::invisible; - - if (pre_displayed != (visible_state::displayed == visible_state_)) - native_interface::caret_visible(wd_->root, !pre_displayed); - } - - bool caret_descriptor::visible() const - { - return (visible_state::invisible != visible_state_); - } - - nana::size caret_descriptor::size() const - { - return size_; - } - - void caret_descriptor::size(const nana::size& s) - { - size_ = s; - update(); - - if (visible_state::invisible != visible_state_) - visible(true); - } - - void caret_descriptor::update() - { - nana::point pos = point_; - nana::size size = size_; - - nana::rectangle rect = effective_range_; - if(0 == effective_range_.width || 0 == effective_range_.height) + auto rect = effect_range_; + if (0 == effect_range_.width || 0 == effect_range_.height) { rect.x = rect.y = 0; - rect = wd_->dimension; + rect = owner_->dimension; } else { - pos.x += effective_range_.x; - pos.y += effective_range_.y; + pos += effect_range_.position(); } - if( (pos.x + static_cast(size.width) <= rect.x) || (pos.x >= rect.right()) || + if ((pos.x + static_cast(size.width) <= rect.x) || (pos.x >= rect.right()) || (pos.y + static_cast(size.height) <= rect.y) || (pos.y >= rect.bottom()) ) {//Out of Range without overlap - if(false == out_of_range_) + if (false == out_of_range_) { out_of_range_ = true; - if (visible_state::invisible != visible_state_) + if (visible_state::invisible != visibility_) visible(false); } } else { - if(pos.x < rect.x) + if (pos.x < rect.x) { size.width -= (rect.x - pos.x); pos.x = rect.x; } - else if(pos.x + static_cast(size.width) > rect.right()) + else if (pos.x + static_cast(size.width) > rect.right()) { size.width -= pos.x + size.width - rect.right(); } - if(pos.y < rect.y) + if (pos.y < rect.y) { size.width -= (rect.y - pos.y); pos.y = rect.y; } - else if(pos.y + static_cast(size.height) > rect.bottom()) + else if (pos.y + static_cast(size.height) > rect.bottom()) size.height -= pos.y + size.height - rect.bottom(); - if(out_of_range_) + if (out_of_range_) { - if (paint_size_ == size) + if (visual_size_ == size) visible(true); out_of_range_ = false; } - if(paint_size_ != size) + if (visual_size_ != size) { - bool vs = (visible_state::invisible != visible_state_); - native_interface::caret_destroy(wd_->root); - native_interface::caret_create(wd_->root, size); + bool vs = (visible_state::invisible != visibility_); + native_interface::caret_destroy(owner_->root); + native_interface::caret_create(owner_->root, size); - visible_state_ = visible_state::invisible; + visibility_ = visible_state::invisible; if (vs) visible(true); - paint_size_ = size; + visual_size_ = size; } - - native_interface::caret_pos(wd_->root, wd_->pos_root + pos); + + native_interface::caret_pos(owner_->root, owner_->pos_root + pos); } } - //end class caret_descriptor + + //Implement caret_interface functions + void caret::disable_throw() noexcept + { + //This function is useless for class caret, see caret_proxy. + } + + void caret::effective_range(const rectangle& r) + { + auto range = r; + //Chech rect + if (range.width && range.height && range.right() > 0 && range.bottom() > 0) + { + if (range.x < 0) + { + range.width += range.x; + range.x = 0; + } + + if (range.y < 0) + { + range.height += range.y; + range.y = 0; + } + + if (effect_range_ != range) + { + effect_range_ = range; + update(); + } + } + } + + void caret::position(const point& pos) + { + position_ = pos; + update(); + } + + point caret::position() const + { + return position_; + } + + size caret::dimension() const + { + return size_; + } + + void caret::dimension(const size& s) + { + size_ = s; + update(); + + if (visible_state::invisible != visibility_) + visible(true); + } + + void caret::visible(bool visibility) + { + auto pre_displayed = (visible_state::displayed == visibility_); + + if (visibility) + { + visibility_ = visible_state::visible; + if (owner_->displayed() && (!out_of_range_)) + visibility_ = visible_state::displayed; + } + else + visibility_ = visible_state::invisible; + + if (pre_displayed != (visible_state::displayed == visibility_)) + native_interface::caret_visible(owner_->root, !pre_displayed); + } + + bool caret::visible() const + { + return (visible_state::invisible != visibility_); + } + //end class caret //struct basic_window //struct basic_window::other_tag @@ -210,9 +216,11 @@ namespace nana case category::flags::root: attribute.root = new attr_root_tag; break; +#ifndef WIDGET_FRAME_DEPRECATED case category::flags::frame: attribute.frame = new attr_frame_tag; break; +#endif default: attribute.root = nullptr; } @@ -220,6 +228,7 @@ namespace nana basic_window::other_tag::~other_tag() { +#ifndef WIDGET_FRAME_DEPRECATED switch(category) { case category::flags::root: @@ -230,6 +239,9 @@ namespace nana break; default: break; } +#endif + if (category::flags::root == category) + delete attribute.root; } //end struct basic_window::other_tag @@ -245,8 +257,8 @@ namespace nana basic_window::~basic_window() { - delete together.caret; - together.caret = nullptr; + delete annex.caret_ptr; + annex.caret_ptr = nullptr; delete effect.bground; effect.bground = nullptr; @@ -268,11 +280,13 @@ namespace nana } } +#ifndef WIDGET_FRAME_DEPRECATED void basic_window::frame_window(native_window_type wd) { if(category::flags::frame == this->other.category) other.attribute.frame->container = wd; } +#endif bool basic_window::is_ancestor_of(const basic_window* wd) const { @@ -312,7 +326,7 @@ namespace nana const basic_window* get_child_caret(const basic_window* wd, bool this_is_a_child) { - if (this_is_a_child && wd->together.caret) + if (this_is_a_child && wd->annex.caret_ptr) return wd; for (auto child : wd->children) @@ -412,8 +426,6 @@ namespace nana effect.bground = nullptr; effect.bground_fade_rate = 0; - together.caret = nullptr; - extra_width = extra_height = 0; //The window must keep its thread_id same as its parent if it is a child. @@ -425,15 +437,15 @@ namespace nana bool basic_window::set_events(const std::shared_ptr& p) { - if (together.events_ptr) + if (annex.events_ptr) return false; - together.events_ptr = p; + annex.events_ptr = p; return true; } general_events * basic_window::get_events() const { - return together.events_ptr.get(); + return annex.events_ptr.get(); } //end struct basic_window }//end namespace detail diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 087fed6d..c0e37ae4 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -129,16 +129,16 @@ namespace nana arg.window_handle = reinterpret_cast(wd); if (emit(event_code::expose, wd, arg, false, get_thread_context())) { - const core_window_t * caret_wd = (wd->together.caret ? wd : wd->child_caret()); + const core_window_t * caret_wd = (wd->annex.caret_ptr ? wd : wd->child_caret()); if (caret_wd) { if (exposed) { if (wd->root_widget->other.attribute.root->focus == caret_wd) - caret_wd->together.caret->visible(true); + caret_wd->annex.caret_ptr->visible(true); } else - caret_wd->together.caret->visible(false); + caret_wd->annex.caret_ptr->visible(false); } if (!exposed) @@ -148,8 +148,10 @@ namespace nana //find an ancestor until it is not a lite_widget wd = wd->seek_non_lite_widget_ancestor(); } +#ifndef WIDGET_FRAME_DEPRECATED else if (category::flags::frame == wd->other.category) wd = wd_manager().find_window(wd->root, wd->pos_root.x, wd->pos_root.y); +#endif } wd_manager().refresh_tree(wd); @@ -201,24 +203,21 @@ namespace nana { if (root_wd->flags.enabled && root_wd->flags.take_active) { - if (focused && focused->together.caret) - focused->together.caret->set_active(true); + if (focused && focused->annex.caret_ptr) + focused->annex.caret_ptr->activate(true); if (!emit(event_code::focus, focused, arg, true, get_thread_context())) this->wd_manager().set_focus(root_wd, true, arg_focus::reason::general); } } - else + else if (root_wd->other.attribute.root->focus) { - if (root_wd->other.attribute.root->focus) + if (emit(event_code::focus, focused, arg, true, get_thread_context())) { - if (emit(event_code::focus, focused, arg, true, get_thread_context())) - { - if (focused->together.caret) - focused->together.caret->set_active(false); - } - close_menu_if_focus_other_window(receiver); + if (focused->annex.caret_ptr) + focused->annex.caret_ptr->activate(false); } + close_menu_if_focus_other_window(receiver); } } @@ -353,19 +352,14 @@ namespace nana return pi_data_->shortkey_occurred; } - widget_geometrics& bedrock::get_scheme_template(scheme_factory_interface&& factory) + color_schemes& bedrock::scheme() { - return pi_data_->scheme.scheme_template(std::move(factory)); - } - - widget_geometrics* bedrock::make_scheme(scheme_factory_interface&& factory) - { - return pi_data_->scheme.create(std::move(factory)); + return pi_data_->scheme; } void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg) { - auto retain = wd->together.events_ptr; + auto retain = wd->annex.events_ptr; auto evts_ptr = retain.get(); switch (evt_code) diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 1ac30c25..c959b01c 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -385,7 +385,7 @@ namespace detail delete msg.u.mouse_drop.files; arg.pos.x = msg.u.mouse_drop.x - msgwd->pos_root.x; arg.pos.y = msg.u.mouse_drop.y - msgwd->pos_root.y; - msgwd->together.events_ptr->mouse_dropfiles.emit(arg, reinterpret_cast(msgwd)); + msgwd->annex.events_ptr->mouse_dropfiles.emit(arg, reinterpret_cast(msgwd)); brock.wd_manager().do_lazy_refresh(msgwd, false); } break; @@ -594,7 +594,7 @@ namespace detail } } - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; context.event_window = msgwnd; pressed_wd = nullptr; @@ -632,7 +632,7 @@ namespace detail nana::point mspos{xevent.xbutton.x, xevent.xbutton.y}; while(msgwnd) { - if(msgwnd->together.events_ptr->mouse_wheel.length() != 0) + if(msgwnd->annex.events_ptr->mouse_wheel.length() != 0) { mspos -= msgwnd->pos_root; arg_wheel arg; @@ -653,7 +653,7 @@ namespace detail msgwnd->set_action(mouse_action::normal); if(msgwnd->flags.enabled) { - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; ::nana::arg_mouse arg; assign_arg(arg, msgwnd, message, xevent); @@ -682,7 +682,7 @@ namespace detail if(hit) msgwnd->set_action(mouse_action::hovered); - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; auto evt_ptr = retain.get(); arg.evt_code = event_code::mouse_up; @@ -698,7 +698,7 @@ namespace detail } } else if(click_arg.window_handle) - msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast(msgwnd)); + msgwnd->annex.events_ptr->click.emit(click_arg, reinterpret_cast(msgwnd)); wd_manager.do_lazy_refresh(msgwnd, false); } @@ -895,7 +895,7 @@ namespace detail msgwnd->set_action(mouse_action::pressed); pressed_wd_space = msgwnd; - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; draw_invoker(&drawer::mouse_down, msgwnd, arg, &context); wd_manager.do_lazy_refresh(msgwnd, false); @@ -987,7 +987,7 @@ namespace detail arg.evt_code = event_code::key_char; arg.window_handle = reinterpret_cast(msgwnd); brock.get_key_state(arg); - msgwnd->together.events_ptr->key_char.emit(arg, reinterpret_cast(msgwnd)); + msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast(msgwnd)); if(arg.ignore == false && wd_manager.available(msgwnd)) draw_invoker(&drawer::key_char, msgwnd, arg, &context); } @@ -1031,7 +1031,7 @@ namespace detail click_arg.mouse_args = nullptr; click_arg.window_handle = reinterpret_cast(msgwnd); - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) { arg_mouse arg; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 798d662c..d6019428 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -947,7 +947,7 @@ namespace detail assign_arg(arg, msgwnd, message, pmdec); msgwnd->set_action(mouse_action::pressed); - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; if (brock.emit(event_code::mouse_down, msgwnd, arg, true, &context)) { //If a root_window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event. @@ -986,7 +986,7 @@ namespace detail msgwnd->set_action(mouse_action::normal); if(msgwnd->flags.enabled) { - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; ::nana::arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); @@ -1121,7 +1121,7 @@ namespace detail auto evt_wd = scrolled_wd; while (evt_wd) { - if (evt_wd->together.events_ptr->mouse_wheel.length() != 0) + if (evt_wd->annex.events_ptr->mouse_wheel.length() != 0) { def_window_proc = false; nana::point mspos{ scr_pos.x, scr_pos.y }; @@ -1198,7 +1198,7 @@ namespace detail wd_manager.calc_window_point(msgwnd, dropfiles.pos); dropfiles.window_handle = reinterpret_cast(msgwnd); - msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast(msgwnd)); + msgwnd->annex.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast(msgwnd)); wd_manager.do_lazy_refresh(msgwnd, false); } } @@ -1422,7 +1422,7 @@ namespace detail msgwnd->set_action(mouse_action::pressed); pressed_wd_space = msgwnd; - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; draw_invoker(&drawer::mouse_down, msgwnd, arg, &context); wd_manager.do_lazy_refresh(msgwnd, false); @@ -1468,7 +1468,7 @@ namespace detail brock.get_key_state(arg); arg.ignore = false; - msgwnd->together.events_ptr->key_char.emit(arg, reinterpret_cast(msgwnd)); + msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast(msgwnd)); if ((false == arg.ignore) && wd_manager.available(msgwnd)) draw_invoker(&drawer::key_char, msgwnd, arg, &context); @@ -1496,7 +1496,7 @@ namespace detail click_arg.mouse_args = nullptr; click_arg.window_handle = reinterpret_cast(msgwnd); - auto retain = msgwnd->together.events_ptr; + auto retain = msgwnd->annex.events_ptr; if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) { arg_mouse arg; diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index c7605538..e741692b 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -26,7 +26,6 @@ namespace nana typedef detail::edge_nimbus_renderer edge_nimbus_renderer_t; //class drawer_trigger - drawer_trigger::~drawer_trigger(){} void drawer_trigger::attached(widget_reference, graph_reference){} void drawer_trigger::detached(){} //none-const void drawer_trigger::typeface_changed(graph_reference){} @@ -136,23 +135,43 @@ namespace nana typedef bedrock bedrock_type; //class drawer + + enum{ + event_size = static_cast(event_code::end) + }; + + struct drawer::data_implement + { + bool refreshing{ false }; + basic_window* window_handle{ nullptr }; + drawer_trigger* realizer{ nullptr }; + method_state mth_state[event_size]; + std::vector draws; + }; + + drawer::drawer() + : data_impl_{ new data_implement } + {} + drawer::~drawer() { - for(auto p : dynamic_drawing_objects_) + for(auto p : data_impl_->draws) { delete p; } + + delete data_impl_; } void drawer::bind(basic_window* cw) { - core_window_ = cw; + data_impl_->window_handle = cw; } void drawer::typeface_changed() { - if(realizer_) - realizer_->typeface_changed(graphics); + if(data_impl_->realizer) + data_impl_->realizer->typeface_changed(graphics); } void drawer::click(const arg_click& arg) @@ -245,7 +264,7 @@ namespace nana if(wd) { auto iwd = reinterpret_cast(wd); - bool owns_caret = (iwd->together.caret) && (iwd->together.caret->visible()); + bool owns_caret = (iwd->annex.caret_ptr) && (iwd->annex.caret_ptr->visible()); //The caret in X11 is implemented by Nana, it is different from Windows' //the caret in X11 is asynchronous, it is hard to hide and show the caret @@ -254,7 +273,7 @@ namespace nana if(owns_caret) { #ifndef NANA_X11 - iwd->together.caret->visible(false); + iwd->annex.caret_ptr->visible(false); #else owns_caret = nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, false); #endif @@ -265,7 +284,7 @@ namespace nana if(owns_caret) { #ifndef NANA_X11 - iwd->together.caret->visible(true); + iwd->annex.caret_ptr->visible(true); #else nana::detail::platform_spec::instance().caret_update(iwd->root, *iwd->root_graph, true); #endif @@ -275,39 +294,39 @@ namespace nana void drawer::refresh() { - if(realizer_ && (refreshing_ == false)) + if (data_impl_->realizer && !data_impl_->refreshing) { - refreshing_ = true; + data_impl_->refreshing = true; _m_bground_pre(); - realizer_->refresh(graphics); + data_impl_->realizer->refresh(graphics); _m_draw_dynamic_drawing_object(); _m_bground_end(); graphics.flush(); - refreshing_ = false; + data_impl_->refreshing = false; } } drawer_trigger* drawer::realizer() const { - return realizer_; + return data_impl_->realizer; } void drawer::attached(widget& wd, drawer_trigger& realizer) { - for (auto i = std::begin(mth_state_), end = std::end(mth_state_); i != end; ++i) + for (auto i = std::begin(data_impl_->mth_state), end = std::end(data_impl_->mth_state); i != end; ++i) *i = method_state::pending; - realizer_ = &realizer; + data_impl_->realizer = &realizer; realizer._m_reset_overrided(); realizer.attached(wd, graphics); } drawer_trigger* drawer::detached() { - if(realizer_) + if (data_impl_->realizer) { - auto rmp = realizer_; - realizer_ = nullptr; + auto rmp = data_impl_->realizer; + data_impl_->realizer = nullptr; rmp->detached(); return rmp; } @@ -317,7 +336,7 @@ namespace nana void drawer::clear() { std::vector then; - for(auto p : dynamic_drawing_objects_) + for (auto p : data_impl_->draws) { if(p->diehard()) then.push_back(p); @@ -325,7 +344,7 @@ namespace nana delete p; } - then.swap(dynamic_drawing_objects_); + then.swap(data_impl_->draws); } void* drawer::draw(std::function && f, bool diehard) @@ -333,7 +352,7 @@ namespace nana if(f) { auto p = new dynamic_drawing::user_draw_function(std::move(f), diehard); - dynamic_drawing_objects_.push_back(p); + data_impl_->draws.push_back(p); return (diehard ? p : nullptr); } return nullptr; @@ -343,11 +362,11 @@ namespace nana { if(p) { - for (auto i = dynamic_drawing_objects_.begin(); i != dynamic_drawing_objects_.end(); ++i) + for (auto i = data_impl_->draws.begin(); i != data_impl_->draws.end(); ++i) if (*i == p) { delete (*i); - dynamic_drawing_objects_.erase(i); + data_impl_->draws.erase(i); break; } } @@ -355,25 +374,25 @@ namespace nana void drawer::_m_bground_pre() { - if(core_window_->effect.bground && core_window_->effect.bground_fade_rate < 0.01) - core_window_->other.glass_buffer.paste(graphics, 0, 0); + if (data_impl_->window_handle->effect.bground && data_impl_->window_handle->effect.bground_fade_rate < 0.01) + data_impl_->window_handle->other.glass_buffer.paste(graphics, 0, 0); } void drawer::_m_bground_end() { - if(core_window_->effect.bground && core_window_->effect.bground_fade_rate >= 0.01) - core_window_->other.glass_buffer.blend(::nana::rectangle{ core_window_->other.glass_buffer.size() }, graphics, nana::point(), core_window_->effect.bground_fade_rate); + if (data_impl_->window_handle->effect.bground && data_impl_->window_handle->effect.bground_fade_rate >= 0.01) + data_impl_->window_handle->other.glass_buffer.blend(::nana::rectangle{ data_impl_->window_handle->other.glass_buffer.size() }, graphics, nana::point(), data_impl_->window_handle->effect.bground_fade_rate); } void drawer::_m_draw_dynamic_drawing_object() { - for(auto * dw : dynamic_drawing_objects_) + for (auto * dw : data_impl_->draws) dw->draw(graphics); } bool drawer::_m_lazy_decleared() const { - return (basic_window::update_state::refresh == core_window_->other.upd_state); + return (basic_window::update_state::refresh == data_impl_->window_handle->other.upd_state); } }//end namespace detail }//end namespace nana diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 509e3142..ea574baa 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -66,6 +66,7 @@ namespace nana nana::point p_src; for (auto & el : blocks) { +#ifndef WIDGET_FRAME_DEPRECATED if (category::flags::frame == el.window->other.category) { native_window_type container = el.window->other.attribute.frame->container; @@ -73,6 +74,7 @@ namespace nana graph.bitblt(el.r, container); } else +#endif { p_src.x = el.r.x - el.window->pos_root.x; p_src.y = el.r.y - el.window->pos_root.y; diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 0d173e0c..0af79eb8 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -237,7 +237,7 @@ namespace detail switch(evtid) { case event_code::mouse_drop: - wd->flags.dropable = (is_make || (0 != wd->together.events_ptr->mouse_dropfiles.length())); + wd->flags.dropable = (is_make || (0 != wd->annex.events_ptr->mouse_dropfiles.length())); break; default: break; @@ -277,8 +277,12 @@ namespace detail if (owner->flags.destroying) throw std::runtime_error("the specified owner is destory"); +#ifndef WIDGET_FRAME_DEPRECATED native = (category::flags::frame == owner->other.category ? owner->other.attribute.frame->container : owner->root_widget->root); +#else + native = owner->root_widget->root; +#endif r.x += owner->pos_root.x; r.y += owner->pos_root.y; } @@ -311,8 +315,10 @@ namespace detail wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph); impl_->wd_register.insert(wd, wd->thread_id); +#ifndef WIDGET_FRAME_DEPRECATED if (owner && (category::flags::frame == owner->other.category)) insert_frame(owner, wd); +#endif bedrock::inc_window(wd->thread_id); this->icon(wd, impl_->default_icon_small, impl_->default_icon_big); @@ -321,6 +327,7 @@ namespace detail return nullptr; } +#ifndef WIDGET_FRAME_DEPRECATED window_manager::core_window_t* window_manager::create_frame(core_window_t* parent, const rectangle& r, widget* wdg) { //Thread-Safe Required! @@ -337,6 +344,7 @@ namespace detail return (wd); } + bool window_manager::insert_frame(core_window_t* frame, native_window wd) { if(frame) @@ -367,6 +375,7 @@ namespace detail } return false; } +#endif window_manager::core_window_t* window_manager::create_widget(core_window_t* parent, const rectangle& r, bool is_lite, widget* wdg) { @@ -461,7 +470,11 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd) == false) return; +#ifndef WIDGET_FRAME_DEPRECATED if((category::flags::root == wd->other.category) || (category::flags::frame != wd->other.category)) +#else + if (category::flags::root == wd->other.category) +#endif { impl_->misc_register.erase(wd->root); impl_->wd_register.remove(wd); @@ -498,6 +511,7 @@ namespace detail if(visible != wd->visible) { +#ifndef WIDGET_FRAME_DEPRECATED native_window_type nv = nullptr; switch(wd->other.category) { @@ -508,6 +522,9 @@ namespace detail default: //category::widget_tag, category::lite_widget_tag break; } +#else + auto nv = (category::flags::root == wd->other.category ? wd->root : nullptr); +#endif if(visible && wd->effect.bground) window_layer::make_bground(wd); @@ -717,12 +734,14 @@ namespace detail if(false == passive) native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)); } +#ifndef WIDGET_FRAME_DEPRECATED else if(category::flags::frame == wd->other.category) { native_interface::window_size(wd->other.attribute.frame->container, sz); for(auto natwd : wd->other.attribute.frame->attach) native_interface::window_size(natwd, sz); } +#endif else { //update the bground buffer of glass window. @@ -943,8 +962,8 @@ namespace detail if (impl_->wd_register.available(prev_focus)) { - if(prev_focus->together.caret) - prev_focus->together.caret->set_active(false); + if(prev_focus->annex.caret_ptr) + prev_focus->annex.caret_ptr->activate(false); arg.getting = false; arg.window_handle = reinterpret_cast(prev_focus); @@ -961,8 +980,8 @@ namespace detail return prev_focus; //no new focus_window - if(wd->together.caret) - wd->together.caret->set_active(true); + if(wd->annex.caret_ptr) + wd->annex.caret_ptr->activate(true); arg.window_handle = reinterpret_cast(wd); arg.getting = true; @@ -1446,6 +1465,7 @@ namespace detail } } +#ifndef WIDGET_FRAME_DEPRECATED if (category::flags::frame == wd->other.category) { //remove the frame handle from the WM frames manager. @@ -1454,6 +1474,7 @@ namespace detail if (established) pa_root_attr->frames.push_back(wd); } +#endif if (established) { @@ -1507,11 +1528,11 @@ namespace detail wd->flags.destroying = true; - if(wd->together.caret) + if(wd->annex.caret_ptr) { //The deletion of caret wants to know whether the window is destroyed under SOME platform. Such as X11 - delete wd->together.caret; - wd->together.caret = nullptr; + delete wd->annex.caret_ptr; + wd->annex.caret_ptr = nullptr; } arg_destroy arg; @@ -1552,6 +1573,7 @@ namespace detail wd->drawer.detached(); wd->widget_notifier->destroy(); +#ifndef WIDGET_FRAME_DEPRECATED if(category::flags::frame == wd->other.category) { //The frame widget does not have an owner, and close their element windows without activating owner. @@ -1561,6 +1583,7 @@ namespace detail native_interface::close_window(wd->other.attribute.frame->container); } +#endif if(wd->other.category != category::flags::root) //Not a root window impl_->wd_register.remove(wd); @@ -1571,13 +1594,18 @@ namespace detail if(category::flags::root != wd->other.category) //A root widget always starts at (0, 0) and its childs are not to be changed { wd->pos_root += delta; +#ifndef WIDGET_FRAME_DEPRECATED if (category::flags::frame != wd->other.category) { - if (wd->together.caret && wd->together.caret->visible()) - wd->together.caret->update(); + if (wd->annex.caret_ptr && wd->annex.caret_ptr->visible()) + wd->annex.caret_ptr->update(); } else native_interface::move_window(wd->other.attribute.frame->container, wd->pos_root.x, wd->pos_root.y); +#else + if (wd->annex.caret_ptr && wd->annex.caret_ptr->visible()) + wd->annex.caret_ptr->update(); +#endif if (wd->displayed() && wd->effect.bground) window_layer::make_bground(wd); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index ffcec9a0..4485b260 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -57,7 +57,7 @@ namespace API { ::nana::widget_geometrics* make_scheme(::nana::detail::scheme_factory_interface&& factory) { - return restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_interface&&>(factory)); + return restrict::bedrock.scheme().create(static_cast<::nana::detail::scheme_factory_interface&&>(factory)); } bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg) @@ -89,7 +89,7 @@ namespace API if (!restrict::wd_manager().available(reinterpret_cast(wd))) return nullptr; - return reinterpret_cast(wd)->together.events_ptr.get(); + return reinterpret_cast(wd)->annex.events_ptr.get(); } }//end namespace detail @@ -200,14 +200,14 @@ namespace API auto iwd = reinterpret_cast(wd); internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) - iwd->scheme = wdg_geom; + iwd->annex.scheme = wdg_geom; } widget_geometrics* get_scheme(window wd) { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; - return (restrict::wd_manager().available(iwd) ? iwd->scheme : nullptr); + return (restrict::wd_manager().available(iwd) ? iwd->annex.scheme : nullptr); } void attach_drawer(widget& wd, drawer_trigger& dr) @@ -217,7 +217,7 @@ namespace API if(restrict::wd_manager().available(iwd)) { iwd->drawer.graphics.make(iwd->dimension); - iwd->drawer.graphics.rectangle(true, iwd->scheme->background.get_color()); + iwd->drawer.graphics.rectangle(true, iwd->annex.scheme->background.get_color()); iwd->drawer.attached(wd, dr); iwd->drawer.refresh(); //Always redrawe no matter it is visible or invisible. This can make the graphics data correctly. } @@ -266,10 +266,12 @@ namespace API return reinterpret_cast(restrict::wd_manager().create_widget(reinterpret_cast(parent), r, true, wdg)); } +#ifndef WIDGET_FRAME_DEPRECATED window create_frame(window parent, const rectangle& r, widget* wdg) { return reinterpret_cast(restrict::wd_manager().create_frame(reinterpret_cast(parent), r, wdg)); } +#endif paint::graphics* window_graphics(window wd) { @@ -546,6 +548,7 @@ namespace API reinterpret_cast(wd)->flags.fullscreen = v; } +#ifndef WIDGET_FRAME_DEPRECATED bool insert_frame(window frame, native_window_type native_window) { return restrict::wd_manager().insert_frame(reinterpret_cast(frame), native_window); @@ -571,6 +574,7 @@ namespace API } return nullptr; } +#endif void close_window(window wd) { @@ -1022,7 +1026,7 @@ namespace API { internal_scope_guard lock; if (restrict::wd_manager().available(reinterpret_cast(wd))) - return reinterpret_cast(wd)->scheme->foreground.get_color(); + return reinterpret_cast(wd)->annex.scheme->foreground.get_color(); return{}; } @@ -1032,10 +1036,10 @@ namespace API internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) { - auto prev = iwd->scheme->foreground.get_color(); + auto prev = iwd->annex.scheme->foreground.get_color(); if (prev != clr) { - iwd->scheme->foreground = clr; + iwd->annex.scheme->foreground = clr; restrict::wd_manager().update(iwd, true, false); } return prev; @@ -1047,7 +1051,7 @@ namespace API { internal_scope_guard lock; if (restrict::wd_manager().available(reinterpret_cast(wd))) - return reinterpret_cast(wd)->scheme->background.get_color(); + return reinterpret_cast(wd)->annex.scheme->background.get_color(); return{}; } @@ -1057,10 +1061,10 @@ namespace API internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) { - auto prev = iwd->scheme->background.get_color(); + auto prev = iwd->annex.scheme->background.get_color(); if (prev != clr) { - iwd->scheme->background = clr; + iwd->annex.scheme->background = clr; //If the bground mode of this window is basic, it should remake the background if (iwd->effect.bground && iwd->effect.bground_fade_rate < 0.01) // fade rate < 0.01 means it is basic mode @@ -1077,7 +1081,7 @@ namespace API { internal_scope_guard lock; if (restrict::wd_manager().available(reinterpret_cast(wd))) - return reinterpret_cast(wd)->scheme->activated.get_color(); + return reinterpret_cast(wd)->annex.scheme->activated.get_color(); return{}; } @@ -1087,10 +1091,10 @@ namespace API internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) { - auto prev = iwd->scheme->activated.get_color(); + auto prev = iwd->annex.scheme->activated.get_color(); if (prev != clr) { - iwd->scheme->activated = clr; + iwd->annex.scheme->activated = clr; restrict::wd_manager().update(iwd, true, false); } return prev; @@ -1099,12 +1103,99 @@ namespace API return{}; } - void create_caret(window wd, unsigned width, unsigned height) + class caret_proxy + : public caret_interface + { + public: + caret_proxy(basic_window* wd) + : window_{ wd } + {} + + void disable_throw() noexcept override + { + throw_ = false; + } + + void effective_range(const rectangle& range) override + { + internal_scope_guard lock; + auto caret = _m_caret(); + if (caret) + caret->effective_range(range); + } + + void position(const point& pos) override + { + internal_scope_guard lock; + auto caret = _m_caret(); + if (caret) + caret->position(pos); + } + + point position() const override + { + internal_scope_guard lock; + auto caret = _m_caret(); + if (caret) + return caret->position(); + + return{}; + } + + void dimension(const size& size) override + { + internal_scope_guard lock; + auto caret = _m_caret(); + if (caret) + caret->dimension(size); + } + + size dimension() const override + { + internal_scope_guard lock; + auto caret = _m_caret(); + if (caret) + return caret->dimension(); + + return{}; + } + + void visible(bool visibility) override + { + internal_scope_guard lock; + auto caret = _m_caret(); + if (caret) + caret->visible(visibility); + } + + bool visible() const override + { + internal_scope_guard lock; + auto caret = _m_caret(); + return (caret && caret->visible()); + } + private: + caret_interface* _m_caret() const + { + if (restrict::wd_manager().available(window_) && window_->annex.caret_ptr) + return window_->annex.caret_ptr; + + if (throw_) + throw std::runtime_error("nana.api: access invalid caret"); + + return nullptr; + } + private: + basic_window* const window_; + bool throw_{ true }; + }; + + void create_caret(window wd, const size& caret_size) { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && (nullptr == iwd->together.caret)) - iwd->together.caret = new ::nana::detail::caret_descriptor(iwd, width, height); + if (restrict::wd_manager().available(iwd) && !(iwd->annex.caret_ptr)) + iwd->annex.caret_ptr = new ::nana::detail::caret(iwd, caret_size); } void destroy_caret(window wd) @@ -1113,72 +1204,19 @@ namespace API internal_scope_guard lock; if(restrict::wd_manager().available(iwd)) { - auto p = iwd->together.caret; - iwd->together.caret = nullptr; + auto p = iwd->annex.caret_ptr; + iwd->annex.caret_ptr = nullptr; delete p; } } - void caret_pos(window wd, const point& pos) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - iwd->together.caret->position(pos.x, pos.y); - } + std::unique_ptr open_caret(window window_handle, bool disable_throw) + { + auto p = new caret_proxy{ reinterpret_cast(window_handle) }; + if (disable_throw) + p->disable_throw(); - nana::point caret_pos(window wd) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - return iwd->together.caret->position(); - - return{}; - } - - void caret_effective_range(window wd, const nana::rectangle& rect) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - iwd->together.caret->effective_range(rect); - } - - void caret_size(window wd, const nana::size& sz) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard isg; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - iwd->together.caret->size(sz); - } - - nana::size caret_size(window wd) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - return iwd->together.caret->size(); - - return{}; - } - - void caret_visible(window wd, bool is_show) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - iwd->together.caret->visible(is_show); - } - - bool caret_visible(window wd) - { - auto iwd = reinterpret_cast(wd); - internal_scope_guard lock; - if(restrict::wd_manager().available(iwd) && iwd->together.caret) - return iwd->together.caret->visible(); - - return false; + return std::unique_ptr{ p }; } void tabstop(window wd) diff --git a/source/gui/widgets/form.cpp b/source/gui/widgets/form.cpp index af43ea37..7f8247ff 100644 --- a/source/gui/widgets/form.cpp +++ b/source/gui/widgets/form.cpp @@ -28,27 +28,61 @@ namespace nana { graph.rectangle(true, API::bgcolor(*wd_)); } + //end class trigger + + //class form_base + form_base::form_base(window owner, bool nested, const rectangle& r, const appearance& app) + : widget_object(owner, nested, r, app) + {} + + place & form_base::get_place() + { + if (this->empty()) + throw std::runtime_error("form::get_plac: the form has destroyed."); + + if (!place_) + place_.reset(new place{ *this }); + + return *place_; + } + + void form_base::div(const char* div_text) + { + get_place().div(div_text); + } + + place::field_reference form_base::operator[](const char* field_name) + { + return get_place()[field_name]; + } + + void form_base::collocate() noexcept + { + if (place_) + place_->collocate(); + } + //end class form_base }//end namespace form }//end namespace drawerbase //class form - typedef widget_object form_base_t; + using form_base = drawerbase::form::form_base; form::form(const form& fm, const ::nana::size& sz, const appearance& apr) - : form_base_t(fm.handle(), false, API::make_center(fm.handle(), sz.width, sz.height), apr) + : form_base(fm.handle(), false, API::make_center(fm.handle(), sz.width, sz.height), apr) { } form::form(const rectangle& r, const appearance& apr) - : form_base_t(nullptr, false, r, apr) + : form_base(nullptr, false, r, apr) {} form::form(window owner, const ::nana::size& sz, const appearance& apr) - : form_base_t(owner, false, API::make_center(owner, sz.width, sz.height), apr) + : form_base(owner, false, API::make_center(owner, sz.width, sz.height), apr) {} form::form(window owner, const rectangle& r, const appearance& apr) - : form_base_t(owner, false, r, apr) + : form_base(owner, false, r, apr) {} void form::modality() const @@ -64,21 +98,21 @@ namespace nana //class nested_form nested_form::nested_form(const form& fm, const rectangle& r, const appearance& apr) - : form_base_t(fm.handle(), true, r, apr) + : form_base(fm.handle(), true, r, apr) { } nested_form::nested_form(const nested_form& fm, const rectangle& r, const appearance& apr) - : form_base_t(fm.handle(), true, r, apr) + : form_base(fm.handle(), true, r, apr) { } nested_form::nested_form(window owner, const appearance& apr) - : form_base_t(owner, true, rectangle(), apr) + : form_base(owner, true, rectangle(), apr) {} nested_form::nested_form(window owner, const rectangle& r, const appearance& apr) - : form_base_t(owner, true, r, apr) + : form_base(owner, true, r, apr) {} //end nested_form }//end namespace nana diff --git a/source/gui/widgets/frame.cpp b/source/gui/widgets/frame.cpp index 27121345..7b9e7af2 100644 --- a/source/gui/widgets/frame.cpp +++ b/source/gui/widgets/frame.cpp @@ -13,6 +13,8 @@ #include +#ifndef WIDGET_FRAME_DEPRECATED + namespace nana { //class frame:: public widget_object @@ -45,3 +47,5 @@ namespace nana //end class frame }//end namespace nana +#endif + diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 32bd6e6a..341fa22d 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -376,9 +376,7 @@ namespace nana{ namespace widgets auto str_px = static_cast(editor_._m_text_extent_size(ent.begin, len).width); if (scrpos.x < str_px) { - std::unique_ptr pxbuf(new unsigned[len]); - - res.x = editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, is_right_text(ent)); + res.x = editor_._m_char_by_pixels(ent, static_cast(scrpos.x)); res.x += static_cast(ent.begin - lnstr.data()); return res; } @@ -837,9 +835,7 @@ namespace nana{ namespace widgets auto str_px = static_cast(editor_._m_text_extent_size(ent.begin, len).width); if (scrpos.x < str_px) { - std::unique_ptr pxbuf(new unsigned[len]); - - res.x += editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, is_right_text(ent)); + res.x += editor_._m_char_by_pixels(ent, scrpos.x); res.x += static_cast(ent.begin - str); return res; } @@ -1281,7 +1277,9 @@ namespace nana{ namespace widgets //class text_editor text_editor::text_editor(window wd, graph_reference graph, const text_editor_scheme* schm) : behavior_(new behavior_normal(*this)), - window_(wd), graph_(graph), + window_(wd), + caret_(API::open_caret(wd, true)), + graph_(graph), scheme_(schm), keywords_(new keywords) { text_area_.area = graph.size(); @@ -1295,7 +1293,7 @@ namespace nana{ namespace widgets select_.mode_selection = selection::mode::no_selected; select_.ignore_press = false; - API::create_caret(wd, 1, line_height()); + API::create_caret(wd, { 1, line_height() }); API::bgcolor(wd, colors::white); API::fgcolor(wd, colors::black); @@ -1864,18 +1862,17 @@ namespace nana{ namespace widgets { visible = true; if (line_bottom > _m_end_pos(false)) - API::caret_size(window_, nana::size(1, line_pixels - (line_bottom - _m_end_pos(false)))); - else if (API::caret_size(window_).height != line_pixels) + caret_->dimension(nana::size(1, line_pixels - (line_bottom - _m_end_pos(false)))); + else if (caret_->dimension().height != line_pixels) reset_caret_pixels(); } if(!attributes_.editable) visible = false; - API::caret_visible(window_, visible); - + caret_->visible(visible); if(visible) - API::caret_pos(window_, pos); + caret_->position(pos); } void text_editor::move_caret_end() @@ -1887,7 +1884,7 @@ namespace nana{ namespace widgets void text_editor::reset_caret_pixels() const { - API::caret_size(window_, nana::size(1, line_height())); + caret_->dimension({ 1, line_height() }); } void text_editor::reset_caret() @@ -1898,7 +1895,7 @@ namespace nana{ namespace widgets void text_editor::show_caret(bool isshow) { if(isshow == false || API::is_focus_ready(window_)) - API::caret_visible(window_, isshow); + caret_->visible(isshow); } bool text_editor::selected() const @@ -2004,7 +2001,7 @@ namespace nana{ namespace widgets if (attributes_.line_wrapped) exclude_px = text_area_.vscroll; else - exclude_px = API::caret_size(window_).width; + exclude_px = caret_->dimension().width; return (text_area_.area.width > exclude_px ? text_area_.area.width - exclude_px : 0); } @@ -3452,42 +3449,48 @@ namespace nana{ namespace widgets points_.offset.y = y; } - unsigned text_editor::_m_char_by_pixels(const wchar_t* str, std::size_t len, unsigned * pxbuf, int str_px, int pixels, bool is_rtl) + unsigned text_editor::_m_char_by_pixels(const unicode_bidi::entity& ent, unsigned pos) { - if (graph_.glyph_pixels(str, len, pxbuf)) - { - if (is_rtl) - { //RTL - for (std::size_t u = 0; u < len; ++u) - { - auto px = static_cast(pxbuf[u]); - auto chbeg = str_px - px; - if (chbeg <= pixels && pixels < str_px) - { - if ((px < 2) || (pixels <= chbeg + (px >> 1))) - return static_cast(u + 1); + unsigned len = ent.end - ent.begin; - return static_cast(u); + std::unique_ptr pxbuf(new unsigned[len]); + if (graph_.glyph_pixels(ent.begin, len, pxbuf.get())) + { + const auto px_end = pxbuf.get() + len; + + if (is_right_text(ent)) + { + auto total_px = std::accumulate(pxbuf.get(), px_end, static_cast(0)); + + for (auto p = pxbuf.get(); p != px_end; ++p) + { + auto chpos = total_px - *p; + if ((chpos <= pos) && (pos < total_px)) + { + if ((*p < 2) || (pos <= chpos + (*p >> 1))) + return static_cast(p - pxbuf.get()) + 1; + + return static_cast(p - pxbuf.get()); } - str_px = chbeg; + total_px = chpos; } } else { - //LTR - for (std::size_t u = 0; u < len; ++u) + for (auto p = pxbuf.get(); p != px_end; ++p) { - auto px = static_cast(pxbuf[u]); - if (pixels < px) + if (pos < *p) { - if ((px > 1) && (pixels > (px >> 1))) - return static_cast(u + 1); - return static_cast(u); + if ((*p > 1) && (pos >(*p >> 1))) + return static_cast(p - pxbuf.get()) + 1; + return static_cast(p - pxbuf.get()); } - pixels -= px; + + pos -= *p; } } } + return 0; } diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index 23a8b4e5..f29c4068 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -48,6 +48,7 @@ namespace nana{ namespace paint struct pixel_buffer::pixel_buffer_storage : private nana::noncopyable { + pixel_buffer_storage(const pixel_buffer_storage& other) = delete; pixel_buffer_storage& operator=(const pixel_buffer_storage&) = delete; bool _m_alloc() @@ -112,18 +113,6 @@ namespace nana{ namespace paint } }img_pro; - pixel_buffer_storage(const pixel_buffer_storage& other) : - drawable{ other.drawable }, - valid_r{ other.valid_r }, - pixel_size{ other.pixel_size }, - bytes_per_line{ other.bytes_per_line }, - alpha_channel{ other.alpha_channel }, - img_pro{ other.img_pro } - { - if (_m_alloc()) - std::memcpy(raw_pixel_buffer, other.raw_pixel_buffer, pixel_size.width * pixel_size.height); - } - pixel_buffer_storage(std::size_t width, std::size_t height) : drawable(nullptr), valid_r(0, 0, static_cast(width), static_cast(height)), From f093f14c378150e22638eae5ec57e5ef23c8ebb6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 01:54:59 +0800 Subject: [PATCH 230/309] fix incomplete type warning --- include/nana/gui/detail/drawer.hpp | 30 +++++++++++------------ source/gui/detail/drawer.cpp | 38 +++++++++++++++++------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index e313c172..472f822e 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -126,36 +126,36 @@ namespace nana void* draw(std::function &&, bool diehard); void erase(void* diehard); private: - void _m_bground_pre(); - void _m_bground_end(); - void _m_draw_dynamic_drawing_object(); + void _m_effect_bground(bool before); bool _m_lazy_decleared() const; + method_state& _m_mth_state(int pos); template void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr) { const int pos = static_cast(evt_code); - if (data_impl_->realizer && (method_state::not_overrided != data_impl_->mth_state[pos])) - { - _m_bground_pre(); - if (method_state::pending == data_impl_->mth_state[pos]) + auto realizer = this->realizer(); + auto & mth_state = _m_mth_state(pos); + + if (realizer && (method_state::not_overrided != mth_state)) + { + _m_effect_bground(true); + + if (method_state::pending == mth_state) { - (data_impl_->realizer->*mfptr)(graphics, arg); + (realizer->*mfptr)(graphics, arg); //Check realizer, when the window is closed in that event handler, the drawer will be //detached and realizer will be a nullptr - if (data_impl_->realizer) - data_impl_->mth_state[pos] = (data_impl_->realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); + if (realizer) + mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); } else - (data_impl_->realizer->*mfptr)(graphics, arg); + (realizer->*mfptr)(graphics, arg); if (_m_lazy_decleared()) - { - _m_draw_dynamic_drawing_object(); - _m_bground_end(); - } + _m_effect_bground(false); } } public: diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index e741692b..fdf569aa 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -1,7 +1,7 @@ /* * A Drawer Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -297,10 +297,9 @@ namespace nana if (data_impl_->realizer && !data_impl_->refreshing) { data_impl_->refreshing = true; - _m_bground_pre(); + _m_effect_bground(true); data_impl_->realizer->refresh(graphics); - _m_draw_dynamic_drawing_object(); - _m_bground_end(); + _m_effect_bground(false); graphics.flush(); data_impl_->refreshing = false; } @@ -372,27 +371,32 @@ namespace nana } } - void drawer::_m_bground_pre() - { - if (data_impl_->window_handle->effect.bground && data_impl_->window_handle->effect.bground_fade_rate < 0.01) - data_impl_->window_handle->other.glass_buffer.paste(graphics, 0, 0); - } - - void drawer::_m_bground_end() - { - if (data_impl_->window_handle->effect.bground && data_impl_->window_handle->effect.bground_fade_rate >= 0.01) - data_impl_->window_handle->other.glass_buffer.blend(::nana::rectangle{ data_impl_->window_handle->other.glass_buffer.size() }, graphics, nana::point(), data_impl_->window_handle->effect.bground_fade_rate); - } - - void drawer::_m_draw_dynamic_drawing_object() + void drawer::_m_effect_bground(bool before) { for (auto * dw : data_impl_->draws) dw->draw(graphics); + + auto & effect = data_impl_->window_handle->effect; + if (effect.bground) + { + if (before) + { + if (effect.bground_fade_rate < 0.01) + data_impl_->window_handle->other.glass_buffer.paste(graphics, 0, 0); + } + else if (effect.bground_fade_rate >= 0.01) + data_impl_->window_handle->other.glass_buffer.blend(::nana::rectangle{ data_impl_->window_handle->other.glass_buffer.size() }, graphics, nana::point(), effect.bground_fade_rate); + } } bool drawer::_m_lazy_decleared() const { return (basic_window::update_state::refresh == data_impl_->window_handle->other.upd_state); } + + drawer::method_state& drawer::_m_mth_state(int pos) + { + return data_impl_->mth_state[pos]; + } }//end namespace detail }//end namespace nana From 2f86b2607536029027e89c381d024c45818bea0e Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 03:17:33 +0800 Subject: [PATCH 231/309] update CMakeLists.txt --- CMakeLists.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 487d837f..2ca11efe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ #https://cmake.org/cmake-tutorial/ #https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption -# use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir +# use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir # if your changes don't execute # It seems that project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES. @@ -320,7 +320,7 @@ if (NANA_CMAKE_BUILD_DEMOS) enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - set (demos calculator helloworld_demo notepad ) + set (demos calculator file_explorer helloworld_demo notepad ) foreach ( demo ${demos}) add_executable(${demo} "../nana-demo/${demo}.cpp") @@ -335,7 +335,6 @@ if (NANA_CMAKE_BUILD_DEMOS) message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) - set (demos widget_show widget_show2 ) #if (NANA_CMAKE_BUILD_FreeMe) @@ -355,12 +354,10 @@ if (NANA_CMAKE_BUILD_DEMOS) message("... to build: ../nana-demo/${demo}.cpp" ) endforeach( demo ${demos}) -endif (NANA_CMAKE_BUILD_FreeMe) - set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked decore dock drag-button draw example.button example_combox example_listbox example_menu - filebox-txt folder_tree folder_tree_nana framework_design_1 framework_design_2 framework_design_3 + filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image threading thread-pool various_events window-dragger windows-subclassing From 5ba6d52774f76aa315d714c10bd4e273faf0cc45 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 11:48:15 +0800 Subject: [PATCH 232/309] debug a crash for travis --- build/makefile/makefile | 54 ++++++++++++++++++++++++----------------- include/nana/config.hpp | 2 +- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/build/makefile/makefile b/build/makefile/makefile index db31cf6e..9f0fb052 100644 --- a/build/makefile/makefile +++ b/build/makefile/makefile @@ -1,43 +1,53 @@ #Nana C++ Library # -#Makefile created by Jinhao(cnjinhao@hotmail.com) +#Makefile created by sarrow104(sarrow104@gmail.com) GCC = g++ INCROOT = ../../include SRCROOT = ../../source EXTRLIB = ../../extrlib NANA_INC= $(INCROOT)/nana +OUTROOT = out +#CXXFLAGS= -g -std=c++11 -Wall +CXXFLAGS= -g -fexceptions -std=c++11 -Wall -Wextra -Wunused-variable -Wfatal-errors INCS = -I$(INCROOT) -I/usr/include/freetype2 -I$(EXTRLIB) BIN = libnana.a -SRC_NANA = $(wildcard $(SRCROOT)/*.cpp) -SRC_DETAIL = $(wildcard $(SRCROOT)/detail/*.cpp) -SRC_FILESYSTEM = $(wildcard $(SRCROOT)/filesystem/*.cpp) -SRC_AUDIO = $(wildcard $(SRCROOT)/audio/*.cpp) -SRC_AUDIO_DETAIL = $(wildcard $(SRCROOT)/audio/detail/*.cpp) -SRC_GUI = $(wildcard $(SRCROOT)/gui/*.cpp) -SRC_GUI_DETAIL = $(wildcard $(SRCROOT)/gui/detail/*.cpp) -SRC_GUI_WIDGETS = $(wildcard $(SRCROOT)/gui/widgets/*.cpp) -SRC_GUI_WIDGETS_SKELETONS = $(wildcard $(SRCROOT)/gui/widgets/skeletons/*.cpp) -SRC_PAINT = $(wildcard $(SRCROOT)/paint/*.cpp) -SRC_PAINT_DETAIL = $(wildcard $(SRCROOT)/paint/detail/*.cpp) -SRC_SYSTEM = $(wildcard $(SRCROOT)/system/*.cpp) -SRC_THREADS= $(wildcard $(SRCROOT)/threads/*.cpp) +TARGET = ../bin/$(BIN) -SOURCES = $(SRC_NANA) $(SRC_DETAIL) $(SRC_FILESYSTEM) $(SRC_AUDIO) $(SRC_AUDIO_DETAIL) $(SRC_GUI) $(SRC_GUI_DETAIL) $(SRC_GUI_WIDGETS) $(SRC_GUI_WIDGETS_SKELETONS) $(SRC_PAINT) $(SRC_PAINT_DETAIL) $(SRC_SYSTEM) $(SRC_THREADS) +.PHONY: all clean install print -LINKOBJ = $(SOURCES:.cpp=.o) +all: $(TARGET) -$(BIN): $(LINKOBJ) - ar r ../bin/$(BIN) $(LINKOBJ) - ranlib ../bin/$(BIN) +define walk +$(wildcard $(1)) $(foreach e, $(wildcard $(1)/*), $(call walk, $(e))) +endef -.cpp.o: - $(GCC) -g -c $< -o $@ $(INCS) -std=c++11 -Wall +SRCFILES := $(filter %.cpp,$(patsubst ./%,%,$(filter-out .,$(call walk, $(SRCROOT))))) + +LINKOBJ = $(patsubst $(SRCROOT)/%.cpp,$(OUTROOT)/objs/%.o,$(SRCFILES)) + +print: + @echo $(LINKOBJ) + +$(TARGET): $(LINKOBJ) + mkdir -p $(dir $@) + ar rus $@ $? + ranlib $@ + +$(OUTROOT)/objs/%.o: $(SRCROOT)/%.cpp + @mkdir -p $(dir $@) + $(GCC) -o $@ -c $< $(INCS) $(CXXFLAGS) clean: rm -f $(LINKOBJ) - rm -f ../bin/$(BIN) + rm -f $(TARGET) +install: + @mkdir -p $(INSTALL_PREFIX)/include + @mkdir -p $(INSTALL_PREFIX)/bin + @mkdir -p $(INSTALL_PREFIX)/lib + cp -rfl $(INCROOT)/* $(INSTALL_PREFIX)/include + cp -rfl $(TARGET) $(INSTALL_PREFIX)/lib/ diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 0969af25..15bbaf70 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -95,7 +95,7 @@ //This marco is defined since 1.4 and until 1.5 for deprecating frame widget. //This marco and class frame will be removed in version 1.5 -#define WIDGET_FRAME_DEPRECATED +//#define WIDGET_FRAME_DEPRECATED /////////////////// // Support for NANA_AUTOMATIC_GUI_TESTING From 208626a27fb287a540a16b2245fcf6037468eebe Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 12:02:38 +0800 Subject: [PATCH 233/309] debug a crash for travis --- CMakeLists.txt | 4 ++-- include/nana/config.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ca11efe..e46796a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,10 +141,10 @@ endif(UNIX) if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall") # Clang + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall -g") # Clang else ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall") # GNU + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -g") # GNU endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 15bbaf70..0969af25 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -95,7 +95,7 @@ //This marco is defined since 1.4 and until 1.5 for deprecating frame widget. //This marco and class frame will be removed in version 1.5 -//#define WIDGET_FRAME_DEPRECATED +#define WIDGET_FRAME_DEPRECATED /////////////////// // Support for NANA_AUTOMATIC_GUI_TESTING From dbd08c2aa72fa666108bafd8e7f4c93ebdefb014 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 12:20:35 +0800 Subject: [PATCH 234/309] debug crash for travis --- source/gui/detail/window_manager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 0af79eb8..715d252b 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -23,6 +23,8 @@ #include #include +#include //debug travis + namespace nana { @@ -92,6 +94,7 @@ namespace detail { void operator()(basic_window* wd) const { + std::cout << "delete basic_window " << wd << std::endl; delete wd; } }; From 5294b4662dab72833cd001fca2245a4c543cf5d1 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 12:30:33 +0800 Subject: [PATCH 235/309] debug travis --- CMakeLists.txt | 41 +--------------------------- source/gui/detail/window_manager.cpp | 3 +- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e46796a8..6f01f493 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,48 +320,9 @@ if (NANA_CMAKE_BUILD_DEMOS) enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - set (demos calculator file_explorer helloworld_demo notepad ) - - foreach ( demo ${demos}) - add_executable(${demo} "../nana-demo/${demo}.cpp") - set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} - #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) - #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) - #add_test(${demo} COMMAND ${demo}) - #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ../nana-demo/${demo}.cpp" ) - endforeach( demo ${demos}) - - set (demos widget_show widget_show2 ) - - #if (NANA_CMAKE_BUILD_FreeMe) - # add_definitions(-DBUILD_FreeMe) - #endif (NANA_CMAKE_BUILD_FreeMe) - - # if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - # list(APPEND demos ) # ?? FreeMe - # endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) - - foreach ( demo ${demos}) - add_executable(${demo} "../nana-demo/${demo}.cpp") - set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} - install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ../nana-demo/${demo}.cpp" ) - endforeach( demo ${demos}) - set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked - decore dock drag-button draw example.button example_combox example_listbox example_menu - filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 - group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 - main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image - threading thread-pool various_events window-dragger windows-subclassing - ) + set (demos main ) # Pending: foreach ( demo ${demos}) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 715d252b..f685c83b 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -94,8 +94,9 @@ namespace detail { void operator()(basic_window* wd) const { - std::cout << "delete basic_window " << wd << std::endl; + std::cout << "delete basic_window " << wd <<" category="<(wd->other.category)<< std::endl; delete wd; + std::cout << " delete successfully" << std::endl; } }; From eb1ae644567950ba16a5c7a575c7ffdade29803f Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 12:36:09 +0800 Subject: [PATCH 236/309] debug travis --- .travis.yml | 51 +-------------------------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/.travis.yml b/.travis.yml index c5ff05f4..5043b5dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,55 +82,6 @@ script: - mv -v bin/ nana-demo/ - cd nana-demo/bin - ls - - ./a_group_impl - - ./animate-bmp - - ./audio_player - - ./background-effects - #- ./calculator - - ./categ - - ./clicked - - ./decore - - ./dock - - ./drag-button - - ./draw - #- ./file_explorer - #- ./example_menu - - ./example_listbox - #- ./example_combox - - ./example.button - #- ./folder_tree_nana - #- ./folder_tree_std - - ./framework_design_1 - - ./framework_design_2 - - ./framework_design_3 - - ./group - - ./HelloWord - #- ./helloword_quit - #- ./inputbox - - ./label_listener - #- ./lambda_event.cpp11 - - ./listbox_inline_widget - - ./listbox_Resolver - - ./loader_1 - #- ./loader_2 - - ./mbox - - ./menu_debug - #- ./MontiHall - #- ./helloworld_demo - #- ./notepad - - ./menu_debug - - ./menu_popuper - #- ./modal_form - #- ./widget_show2 - #- ./widget_show - - ./place_login - - ./png - #- ./screen - - ./stretch_image - - ./threading - #- ./thread-pool - - ./various_events - #- ./window-dragger - - ./windows-subclassing + - ./main From ae442cc80d781d45eaa9270beafdfe512c033d71 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 12:43:46 +0800 Subject: [PATCH 237/309] debug travis --- source/gui/detail/basic_window.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index a7cbd2e6..fa368b27 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -13,6 +13,8 @@ #include #include +#include //debug travis + namespace nana { namespace detail @@ -215,6 +217,7 @@ namespace nana { case category::flags::root: attribute.root = new attr_root_tag; + std::cout<<"basic_window: create attr root "< Date: Fri, 24 Jun 2016 12:53:17 +0800 Subject: [PATCH 238/309] debug travis --- source/gui/detail/basic_window.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index fa368b27..314f1d5b 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -246,7 +246,8 @@ namespace nana if (category::flags::root == category) { - std::cout<<"basic_window: delete attr root"<effects_edge_numbus.size()< Date: Fri, 24 Jun 2016 12:59:28 +0800 Subject: [PATCH 239/309] debug travis --- source/gui/detail/basic_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 314f1d5b..0a5542fe 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -247,7 +247,7 @@ namespace nana if (category::flags::root == category) { std::cout<<"basic_window: delete attr root "<effects_edge_numbus.size()<effects_edge_nimbus.size()< Date: Fri, 24 Jun 2016 13:42:23 +0800 Subject: [PATCH 240/309] debug travis --- source/gui/detail/basic_window.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 0a5542fe..873a32ae 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -216,6 +216,8 @@ namespace nana switch(categ) { case category::flags::root: + attribute.root = new attr_root_tag; + delete attribute.root; attribute.root = new attr_root_tag; std::cout<<"basic_window: create attr root "< Date: Fri, 24 Jun 2016 13:48:28 +0800 Subject: [PATCH 241/309] debug travis --- include/nana/gui/detail/drawer.hpp | 4 ++-- source/gui/detail/basic_window.cpp | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index 472f822e..02fc90cb 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -148,8 +148,8 @@ namespace nana //Check realizer, when the window is closed in that event handler, the drawer will be //detached and realizer will be a nullptr - if (realizer) - mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); + //if (realizer) + // mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); } else (realizer->*mfptr)(graphics, arg); diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 873a32ae..0a5542fe 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -216,8 +216,6 @@ namespace nana switch(categ) { case category::flags::root: - attribute.root = new attr_root_tag; - delete attribute.root; attribute.root = new attr_root_tag; std::cout<<"basic_window: create attr root "< Date: Fri, 24 Jun 2016 14:22:04 +0200 Subject: [PATCH 242/309] using explicit namespaces --- include/nana/filesystem/filesystem.hpp | 4 +-- include/nana/filesystem/filesystem_ext.hpp | 17 +++++++++-- source/filesystem/filesystem.cpp | 19 ++++++------ source/gui/filebox.cpp | 35 ++++++++++------------ source/paint/image.cpp | 10 ++++--- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index a62a5707..33799b74 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -241,8 +241,8 @@ namespace nana { namespace experimental { namespace filesystem //observers file_status status() const; - operator const filesystem::path&() const; - const filesystem::path& path() const; + operator const path&() const { return path_; }; + const path& path() const; private: filesystem::path path_; }; diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index feb68fa9..526f3370 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -18,7 +18,11 @@ #include #include -namespace nana {namespace experimental {namespace filesystem {namespace ext { +namespace nana +{ +namespace filesystem_ext +{ + #if defined(NANA_WINDOWS) constexpr auto def_root = "C:"; constexpr auto def_rootstr = "C:\\"; @@ -153,6 +157,13 @@ inline std::string pretty_file_date(const std::experimental::filesystem::path& p { try { auto ftime = std::experimental::filesystem::last_write_time(path); + + // crash: VS2015 will not read the time for some files (for example: C:/hiberfil.sys) + // and will return file_time_type(-1) without throwing + // https://msdn.microsoft.com/en-us/library/dn823784.aspx + + if (ftime == ((std::experimental::filesystem::file_time_type::min)())) return {}; + std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); std::stringstream tm; tm << std::put_time(std::localtime(&cftime), "%Y-%m-%d, %H:%M:%S"); @@ -163,5 +174,7 @@ inline std::string pretty_file_date(const std::experimental::filesystem::path& p } } -}}}} +} // filesystem_ext +} // nana + #endif //NANA_FILESYSTEM_EXT_HPP diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index 69f467cf..7377fa70 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -36,6 +36,7 @@ #include #endif +namespace nana_fs = nana::experimental::filesystem; namespace nana { namespace experimental { namespace filesystem { @@ -143,7 +144,7 @@ namespace nana { namespace experimental { namespace filesystem path path::parent_path() const { - return{filesystem::parent_path(pathstr_)}; + return{nana_fs::parent_path(pathstr_)}; } file_type path::what() const @@ -342,17 +343,17 @@ namespace nana { namespace experimental { namespace filesystem } //class directory_entry - directory_entry::directory_entry(const filesystem::path& p) + directory_entry::directory_entry(const nana_fs::path& p) :path_{ p } {} //modifiers - void directory_entry::assign(const filesystem::path& p) + void directory_entry::assign(const nana_fs::path& p) { path_ = p; } - void directory_entry::replace_filename(const filesystem::path& p) + void directory_entry::replace_filename(const nana_fs::path& p) { path_ = path_.parent_path() / p; } @@ -360,13 +361,13 @@ namespace nana { namespace experimental { namespace filesystem //observers file_status directory_entry::status() const { - return filesystem::status(path_); + return nana_fs::status(path_); } - directory_entry::operator const filesystem::path&() const - { - return path_; - } + //directory_entry::operator const nana_fs::path&() const + //{ + // return path_; + //} const path& directory_entry::path() const { diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index 5f8f1311..bc697d24 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -30,6 +30,8 @@ #include #endif +namespace fs = nana::experimental::filesystem; + namespace nana { #if defined(NANA_POSIX) @@ -142,7 +144,7 @@ namespace nana auto path = path_.caption(); auto root = path.substr(0, path.find('/')); if(root == "HOME") - path.replace(0, 4, nana::experimental::filesystem::path_user().native()); + path.replace(0, 4, fs::path_user().native()); else if(root == "FILESYSTEM") path.erase(0, 10); else @@ -344,7 +346,7 @@ namespace nana else dir = saved_selected_path; - _m_load_cat_path(dir.size() ? dir : nana::experimental::filesystem::path_user().native()); + _m_load_cat_path(dir.size() ? dir : fs::path_user().native()); tb_file_.caption(file_with_path_removed); } @@ -427,8 +429,6 @@ namespace nana nodes_.filesystem = tree_.insert("FS.ROOT", "Filesystem"); nodes_.filesystem.value(kind::filesystem); - namespace fs = ::nana::experimental::filesystem; - std::vector paths; paths.emplace_back(fs::path_user().native()); paths.emplace_back("/"); @@ -474,7 +474,7 @@ namespace nana { auto begstr = path.substr(0, pos); if(begstr == "FS.HOME") - path.replace(0, 7, nana::experimental::filesystem::path_user().native()); + path.replace(0, 7, fs::path_user().native()); else path.erase(0, pos); return begstr; @@ -490,8 +490,6 @@ namespace nana file_container_.clear(); - namespace fs = ::nana::experimental::filesystem; - fs::directory_iterator end; for(fs::directory_iterator i(path); i != end; ++i) { @@ -508,13 +506,13 @@ namespace nana { m.bytes = fs::file_size(path + m.name); m.directory = fs::is_directory(fattr); - ::nana::experimental::filesystem::modified_file_time(path + m.name, m.modified_time); + fs::modified_file_time(path + m.name, m.modified_time); } else { m.bytes = 0; m.directory = fs::is_directory(*i); - ::nana::experimental::filesystem::modified_file_time(path + i->path().filename().native(), m.modified_time); + fs::modified_file_time(path + i->path().filename().native(), m.modified_time); } file_container_.push_back(m); @@ -530,11 +528,13 @@ namespace nana if((path.size() == 0) || (path[path.size() - 1] != '/')) path += '/'; + namespace fs = ::nana::experimental::filesystem; + auto beg_node = tree_.selected(); while(!beg_node.empty() && (beg_node != nodes_.home) && (beg_node != nodes_.filesystem)) beg_node = beg_node.owner(); - auto head = nana::experimental::filesystem::path_user().native(); + auto head = fs::path_user().native(); if(path.size() >= head.size() && (path.substr(0, head.size()) == head)) {//This is HOME path_.caption("HOME"); @@ -552,7 +552,6 @@ namespace nana if(head.size() == 0 || head[head.size() - 1] != '/') head += '/'; - namespace fs = ::nana::experimental::filesystem; fs::directory_iterator end; for(fs::directory_iterator i(head); i != end; ++i) @@ -649,20 +648,20 @@ namespace nana return; } - using file_type = nana::experimental::filesystem::file_type; + using file_type = fs::file_type; - experimental::filesystem::path fspath(fb_.addr_.filesystem + path); + fs::path fspath(fb_.addr_.filesystem + path); - auto fs = experimental::filesystem::status(fspath); + auto fst = fs::status(fspath); - if(fs.type() != file_type::not_found && fs.type() != file_type::none) + if(fst.type() != file_type::not_found && fst.type() != file_type::none) { mb<path = ipstr; } diff --git a/source/paint/image.cpp b/source/paint/image.cpp index a1e2c889..f9b6f6cf 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -36,6 +36,8 @@ #include "image_accessor.hpp" +namespace fs = nana::experimental::filesystem; + namespace nana { namespace paint @@ -60,7 +62,7 @@ namespace paint //class image_ico image_ico::image_ico(bool is_ico): is_ico_(is_ico){} - bool image_ico::open(const nana::experimental::filesystem::path& file) + bool image_ico::open(const fs::path& file) { close(); #if defined(NANA_WINDOWS) @@ -231,7 +233,7 @@ namespace paint return *this; } - std::shared_ptr create_image(const ::nana::experimental::filesystem::path & p) + std::shared_ptr create_image(const fs::path & p) { std::shared_ptr ptr; @@ -314,14 +316,14 @@ namespace paint bool image::open(const ::std::string& file) { - ::nana::experimental::filesystem::path path(file); + fs::path path(file); image_ptr_ = create_image(path); return (image_ptr_ ? image_ptr_->open(path) : false); } bool image::open(const std::wstring& file) { - ::nana::experimental::filesystem::path path(file); + fs::path path(file); image_ptr_ = create_image(path); return (image_ptr_ ? image_ptr_->open(path) : false); } From 70b1b0b9eec009d56dba38955890831f20211fd6 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 24 Jun 2016 14:26:17 +0200 Subject: [PATCH 243/309] travis point to nana-demo.dev_nana_fs --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c5ff05f4..ed1b44de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=1 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=1 --branch=dev_nana_fs https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From aee106206adbf51d86e8f7d54bd1d3a901c73a17 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 23:30:07 +0800 Subject: [PATCH 244/309] debug travis --- include/nana/gui/detail/basic_window.hpp | 28 ++++++++++++++++++---- include/nana/gui/detail/drawer.hpp | 4 ++-- include/nana/gui/detail/window_manager.hpp | 4 ++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 01ccb589..517f9c3f 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -64,6 +64,7 @@ namespace detail rectangle effect_range_; };//end class caret + /// Define some constant about tab category, these flags can be combine with operator | struct tab_type { @@ -75,7 +76,6 @@ namespace detail }; }; - class caret; /// a window data structure descriptor struct basic_window @@ -212,9 +212,18 @@ namespace detail struct attr_root_tag { + attr_root_tag(const attr_root_tag&) = delete; + attr_root_tag(attr_root_tag&&) = delete; +#ifndef WIDGET_FRAME_DEPRECATED container frames; ///< initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame - container tabstop; - std::vector effects_edge_nimbus; +#endif + //Following p_xxx pointers are used for debugging + container * p_tabstop; + std::vector * p_effects; + std::function * p_draw_through; + + container& tabstop; + std::vector& effects_edge_nimbus; basic_window* focus{nullptr}; basic_window* menubar{nullptr}; bool ime_enabled{false}; @@ -224,7 +233,18 @@ namespace detail cursor state_cursor{nana::cursor::arrow}; basic_window* state_cursor_window{ nullptr }; - std::function draw_through; ///< A draw through renderer for root widgets. + std::function& draw_through; ///< A draw through renderer for root widgets. + + attr_root_tag(): + p_tabstop(new container), + p_effects(new std::vector), + p_draw_through(new std::function), + tabstop(*p_tabstop), + effects_edge_nimbus(*p_effects), + draw_through(*p_draw_through) + { + + } }; const category::flags category; diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index 02fc90cb..472f822e 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -148,8 +148,8 @@ namespace nana //Check realizer, when the window is closed in that event handler, the drawer will be //detached and realizer will be a nullptr - //if (realizer) - // mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); + if (realizer) + mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided); } else (realizer->*mfptr)(graphics, arg); diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index d2a83d3e..e7cbf5ca 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -10,8 +10,8 @@ * @file: nana/gui/detail/window_manager.hpp * * - * destroy method destroys a window handle and the handles of its children, but it doesn't delete the handle which type is a root window or a frame - * destroy_handle method just destroys the handle which type is a root window or a frame + * destroy method destroys a window handle and the handles of its children, but it doesn't delete the handle which type is a root window + * destroy_handle method just destroys the handle which type is a root window * */ From cbf4b88956b1c968e95efea29899555b1da53431 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Jun 2016 23:39:03 +0800 Subject: [PATCH 245/309] debug travis --- include/nana/gui/detail/basic_window.hpp | 5 +++-- source/gui/detail/basic_window.cpp | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 517f9c3f..ce06da4e 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -242,9 +242,10 @@ namespace detail tabstop(*p_tabstop), effects_edge_nimbus(*p_effects), draw_through(*p_draw_through) - { - + {} } + + ~attr_root_tag(); }; const category::flags category; diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 0a5542fe..ef550a1f 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -209,6 +209,10 @@ namespace nana //end class caret //struct basic_window + basic_window::other_tag::attr_root_tag::~attr_root_tag() + { + std::cout<<"~attr_root_tag "< Date: Fri, 24 Jun 2016 23:42:47 +0800 Subject: [PATCH 246/309] debug travis --- include/nana/gui/detail/basic_window.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index ce06da4e..5a2763c5 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -243,7 +243,6 @@ namespace detail effects_edge_nimbus(*p_effects), draw_through(*p_draw_through) {} - } ~attr_root_tag(); }; From 484b84189f51759082a3cf4a411aa9f14c327636 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 25 Jun 2016 04:40:53 +0800 Subject: [PATCH 247/309] debug travis --- source/gui/detail/basic_window.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index ef550a1f..5856952f 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -236,6 +236,7 @@ namespace nana basic_window::other_tag::~other_tag() { #ifndef WIDGET_FRAME_DEPRECATED + std::cout<<"~other_tag "< Date: Sat, 25 Jun 2016 04:55:06 +0800 Subject: [PATCH 248/309] fix crash that deprecation is included in NANA_IGNORE_CONF it crashs when build with CMake --- include/nana/config.hpp | 10 +++++----- include/nana/gui/detail/basic_window.hpp | 25 +++--------------------- source/gui/detail/basic_window.cpp | 23 +++++++--------------- 3 files changed, 15 insertions(+), 43 deletions(-) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 0969af25..47ab4e4a 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -25,7 +25,11 @@ #include "c++defines.hpp" -//The basic configurations are ignored when NANA_IGNORE_CONF is defined. +//This marco is defined since 1.4 and until 1.5 for deprecating frame widget. +//This marco and class frame will be removed in version 1.5 +#define WIDGET_FRAME_DEPRECATED + +//The following basic configurations are ignored when NANA_IGNORE_CONF is defined. //The NANA_IGNORE_CONF may be specified by CMake generated makefile. #ifndef NANA_IGNORE_CONF @@ -93,10 +97,6 @@ #endif #endif -//This marco is defined since 1.4 and until 1.5 for deprecating frame widget. -//This marco and class frame will be removed in version 1.5 -#define WIDGET_FRAME_DEPRECATED - /////////////////// // Support for NANA_AUTOMATIC_GUI_TESTING // Will cause the program to self-test the GUI. A default automatic GUI test diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 5a2763c5..280d015b 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -212,18 +212,11 @@ namespace detail struct attr_root_tag { - attr_root_tag(const attr_root_tag&) = delete; - attr_root_tag(attr_root_tag&&) = delete; #ifndef WIDGET_FRAME_DEPRECATED container frames; ///< initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame #endif - //Following p_xxx pointers are used for debugging - container * p_tabstop; - std::vector * p_effects; - std::function * p_draw_through; - - container& tabstop; - std::vector& effects_edge_nimbus; + container tabstop; + std::vector effects_edge_nimbus; basic_window* focus{nullptr}; basic_window* menubar{nullptr}; bool ime_enabled{false}; @@ -233,18 +226,7 @@ namespace detail cursor state_cursor{nana::cursor::arrow}; basic_window* state_cursor_window{ nullptr }; - std::function& draw_through; ///< A draw through renderer for root widgets. - - attr_root_tag(): - p_tabstop(new container), - p_effects(new std::vector), - p_draw_through(new std::function), - tabstop(*p_tabstop), - effects_edge_nimbus(*p_effects), - draw_through(*p_draw_through) - {} - - ~attr_root_tag(); + std::function draw_through; ///< A draw through renderer for root widgets. }; const category::flags category; @@ -262,7 +244,6 @@ namespace detail }attribute; other_tag(category::flags); - ~other_tag(); }other; native_window_type root; ///< root Window handle diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 5856952f..faf0b553 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -13,8 +13,6 @@ #include #include -#include //debug travis - namespace nana { namespace detail @@ -209,34 +207,33 @@ namespace nana //end class caret //struct basic_window - basic_window::other_tag::attr_root_tag::~attr_root_tag() - { - std::cout<<"~attr_root_tag "<effects_edge_nimbus.size()< Date: Fri, 24 Jun 2016 23:48:53 +0200 Subject: [PATCH 249/309] FIX crash in VS consistently using filesysten_ext --- include/nana/c++defines.hpp | 1 + include/nana/filesystem/filesystem.hpp | 16 +++++++----- include/nana/filesystem/filesystem_ext.hpp | 2 ++ .../nana/filesystem/filesystem_selector.hpp | 10 ++++---- include/nana/gui/filebox.hpp | 25 +++++++++++-------- .../paint/detail/image_impl_interface.hpp | 4 +-- include/nana/paint/graphics.hpp | 3 ++- source/filesystem/filesystem.cpp | 7 ++++-- source/gui/filebox.cpp | 7 ++---- source/paint/detail/image_bmp.hpp | 4 +-- source/paint/detail/image_ico.hpp | 4 +-- source/paint/image.cpp | 4 +-- 12 files changed, 49 insertions(+), 38 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 071f984f..29cb0e0f 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -59,6 +59,7 @@ # define constexpr const //no support of constexpr until Visual C++ 2015 ? const ?? # endif +# undef STD_FILESYSTEM_NOT_SUPPORTED #elif defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ < 6) # define noexcept //no support of noexcept until GCC 4.6 diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 33799b74..7fddc3bb 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -30,6 +30,9 @@ #ifndef NANA_FILESYSTEM_HPP #define NANA_FILESYSTEM_HPP +//#undef NANA_USING_NANA_FILESYSTEM +#if NANA_USING_NANA_FILESYSTEM + #include #include @@ -233,18 +236,18 @@ namespace nana { namespace experimental { namespace filesystem { public: directory_entry() = default; - explicit directory_entry(const path&); + explicit directory_entry(const ::nana::experimental::filesystem::path&); //modifiers - void assign(const path&); - void replace_filename(const path&); + void assign(const ::nana::experimental::filesystem::path&); + void replace_filename(const ::nana::experimental::filesystem::path&); //observers file_status status() const; - operator const path&() const { return path_; }; - const path& path() const; + operator const filesystem::path&() const { return path_; }; + const filesystem::path& path() const; private: - filesystem::path path_; + ::nana::experimental::filesystem::path path_; }; /// InputIterator that iterate over the sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator @@ -414,3 +417,4 @@ namespace nana { namespace experimental { namespace filesystem #include #endif +#endif diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 526f3370..3711eb59 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -15,7 +15,9 @@ #ifndef NANA_FILESYSTEM_EXT_HPP #define NANA_FILESYSTEM_EXT_HPP +#include #include + #include namespace nana diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp index 5ccfabc5..0d9c78dd 100644 --- a/include/nana/filesystem/filesystem_selector.hpp +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -35,6 +35,8 @@ #if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) ) +#undef NANA_USING_NANA_FILESYSTEM +#define NANA_USING_NANA_FILESYSTEM true # include namespace std { @@ -46,14 +48,14 @@ namespace std { # else using namespace nana::experimental::filesystem::v1; # endif -#undef NANA_USING_NANA_FILESYSTEM -#define NANA_USING_NANA_FILESYSTEM true } // filesystem } // experimental } // std #elif (defined(BOOST_FILESYSTEM_AVAILABLE) && ( defined(BOOST_FILESYSTEM_FORCE) || ( defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(STD_FILESYSTEM_FORCE) ) )) +#undef NANA_USING_BOOST_FILESYSTEM +#define NANA_USING_BOOST_FILESYSTEM true # include // add boost::filesystem into std::experimental::filesystem @@ -61,17 +63,15 @@ namespace std { namespace experimental { namespace filesystem { using namespace boost::filesystem; -#undef NANA_USING_BOOST_FILESYSTEM -#define NANA_USING_BOOST_FILESYSTEM true } // filesystem } // experimental } // std #else -# include #undef NANA_USING_STD_FILESYSTEM #define NANA_USING_STD_FILESYSTEM true +# include #endif #ifndef __cpp_lib_experimental_filesystem diff --git a/include/nana/gui/filebox.hpp b/include/nana/gui/filebox.hpp index 3a9b9f4c..561dc5b7 100644 --- a/include/nana/gui/filebox.hpp +++ b/include/nana/gui/filebox.hpp @@ -1,4 +1,4 @@ -/* +/** * Filebox * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,7 +7,9 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/filebox.hpp + * @file nana/gui/filebox.hpp + * @author Jinhao + * @brief a dialog to chose file(s), implemented "native" in windows but using nana for X11 */ #ifndef NANA_GUI_FILEBOX_HPP @@ -37,18 +39,20 @@ namespace nana /// Change owner window void owner(window); - /// specify a title for the dialog + /// Set a new title for the dialog /// @param string a text for title - /// @return old title. - ::std::string title( ::std::string new_title); ///< . Set a new title for the dialog and \return the old title + /// @return the old title. + ::std::string title( ::std::string new_title); - /** @brief specify a suggestion directory - * @param string a path of initial directory + /** @brief Suggest initial path used to locate a directory when the filebox starts. + * @param string initial_directory a path of initial directory * @note the behavior of init_path is different between Win7 and Win2K/XP/Vista, but its behavior under Linux is conformed with Win7. */ - filebox& init_path(const ::std::string&); ///< Suggested init path used to locate a directory when the filebox starts. + filebox& init_path(const ::std::string& initial_directory); + filebox& init_file(const ::std::string&); ///< Init file, if it contains a path, the init path is replaced by the path of init file. - /// \brief Add a filetype filter. + + /// \brief Add a filetype filter. /// To specify multiple filter in a single description, use a semicolon to separate the patterns(for example,"*.TXT;*.DOC;*.BAK"). filebox& add_filter(const ::std::string& description, ///< for example. "Text File" const ::std::string& filetype ///< filter pattern(for example, "*.TXT") @@ -68,8 +72,7 @@ namespace nana /// Display the filebox dialog bool show() const; - /// Display the filebox dialog - /// A function object method alternative to show() + /// a function object method alternative to show() to display the filebox dialog, bool operator()() const { return show(); diff --git a/include/nana/paint/detail/image_impl_interface.hpp b/include/nana/paint/detail/image_impl_interface.hpp index 4a0a1722..3e75d18e 100644 --- a/include/nana/paint/detail/image_impl_interface.hpp +++ b/include/nana/paint/detail/image_impl_interface.hpp @@ -2,7 +2,7 @@ #define NANA_PAINT_DETAIL_IMAGE_IMPL_INTERFACE_HPP #include "../image.hpp" -#include +#include namespace nana{ namespace paint{ @@ -16,7 +16,7 @@ namespace nana{ namespace paint{ public: typedef nana::paint::graphics& graph_reference; virtual ~image_impl_interface() = 0; //The destructor is defined in ../image.cpp - virtual bool open(const nana::experimental::filesystem::path& file) = 0; + virtual bool open(const std::experimental::filesystem::path& file) = 0; virtual bool open(const void* data, std::size_t bytes) = 0; // reads image from memory virtual bool alpha_channel() const = 0; virtual bool empty() const = 0; diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index fec075ab..7102c500 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -13,10 +13,11 @@ #ifndef NANA_PAINT_GRAPHICS_HPP #define NANA_PAINT_GRAPHICS_HPP +#include + #include "../basic_types.hpp" #include "../gui/basis.hpp" #include "pixel_buffer.hpp" -#include namespace nana { diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index 7377fa70..fec154d2 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -11,7 +11,8 @@ * provide some interface for file managment */ -#include +#include +#if NANA_USING_NANA_FILESYSTEM #include #if defined(NANA_WINDOWS) #include @@ -369,7 +370,7 @@ namespace nana { namespace experimental { namespace filesystem // return path_; //} - const path& directory_entry::path() const + const nana_fs::path& directory_entry::path() const { return path_; } @@ -888,3 +889,5 @@ namespace nana { namespace experimental { namespace filesystem }//end namespace filesystem } //end namespace experimental }//end namespace nana +#endif + diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index bc697d24..2644d910 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #if defined(NANA_WINDOWS) #include @@ -24,13 +24,12 @@ #include #include #include - #include #include #include #include #endif -namespace fs = nana::experimental::filesystem; +namespace fs = std::experimental::filesystem; namespace nana { @@ -528,8 +527,6 @@ namespace nana if((path.size() == 0) || (path[path.size() - 1] != '/')) path += '/'; - namespace fs = ::nana::experimental::filesystem; - auto beg_node = tree_.selected(); while(!beg_node.empty() && (beg_node != nodes_.home) && (beg_node != nodes_.filesystem)) beg_node = beg_node.owner(); diff --git a/source/paint/detail/image_bmp.hpp b/source/paint/detail/image_bmp.hpp index da86c0a3..23d7907e 100644 --- a/source/paint/detail/image_bmp.hpp +++ b/source/paint/detail/image_bmp.hpp @@ -13,8 +13,8 @@ #ifndef NANA_PAINT_DETAIL_IMAGE_BMP_HPP #define NANA_PAINT_DETAIL_IMAGE_BMP_HPP -#include "image_pixbuf.hpp" #include +#include "image_pixbuf.hpp" namespace nana{ namespace paint { @@ -309,7 +309,7 @@ namespace nana{ namespace paint return true; } - bool open(const nana::experimental::filesystem::path& filename) override + bool open(const std::experimental::filesystem::path& filename) override { std::ifstream ifs(filename.string(), std::ios::binary); if(ifs) diff --git a/source/paint/detail/image_ico.hpp b/source/paint/detail/image_ico.hpp index debabac5..44b49191 100644 --- a/source/paint/detail/image_ico.hpp +++ b/source/paint/detail/image_ico.hpp @@ -1,8 +1,8 @@ #ifndef NANA_PAINT_DETAIL_IMAGE_ICO_HPP #define NANA_PAINT_DETAIL_IMAGE_ICO_HPP +#include #include -#include namespace nana{ namespace paint { @@ -24,7 +24,7 @@ namespace nana{ namespace paint image_ico(bool is_ico); - bool open(const ::nana::experimental::filesystem::path& filename) override; + bool open(const std::experimental::filesystem::path& filename) override; bool open(const void* data, std::size_t bytes) override; bool alpha_channel() const override; bool empty() const override; diff --git a/source/paint/image.cpp b/source/paint/image.cpp index f9b6f6cf..b654ca6a 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #if defined(NANA_ENABLE_JPEG) #include "detail/image_jpeg.hpp" @@ -36,7 +36,7 @@ #include "image_accessor.hpp" -namespace fs = nana::experimental::filesystem; +namespace fs = std::experimental::filesystem; namespace nana { From 4a6331e62554aa5d99ea9d0c8ed061ce17ade059 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 25 Jun 2016 06:00:40 +0800 Subject: [PATCH 250/309] fix missing ~other_tag, remove some warings --- include/nana/gui/detail/basic_window.hpp | 1 + source/deploy.cpp | 2 +- source/gui/widgets/listbox.cpp | 2 +- source/gui/widgets/skeletons/text_editor.cpp | 2 +- source/paint/text_renderer.cpp | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 280d015b..038acdbb 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -244,6 +244,7 @@ namespace detail }attribute; other_tag(category::flags); + ~other_tag(); }other; native_window_type root; ///< root Window handle diff --git a/source/deploy.cpp b/source/deploy.cpp index 7f098148..7f715ef9 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -449,7 +449,7 @@ namespace std //template< > std::string put_time/**/(const std::tm* tmb, const char* fmt) { - unsigned sz = 200; + std::size_t sz = 200; std::string str(sz, '\0'); sz = std::strftime(&str[0], str.size() - 1, fmt, tmb); str.resize(sz); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 9c710901..8cf10cbc 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2078,7 +2078,7 @@ namespace nana unsigned x_offset() const { - return (h.empty() ? 0 : h.value()); + return static_cast(h.empty() ? 0 : h.value()); } index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 341fa22d..3062b445 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -3451,7 +3451,7 @@ namespace nana{ namespace widgets unsigned text_editor::_m_char_by_pixels(const unicode_bidi::entity& ent, unsigned pos) { - unsigned len = ent.end - ent.begin; + auto len = static_cast(ent.end - ent.begin); std::unique_ptr pxbuf(new unsigned[len]); if (graph_.glyph_pixels(ent.begin, len, pxbuf.get())) diff --git a/source/paint/text_renderer.cpp b/source/paint/text_renderer.cpp index 1716b34c..825639c6 100644 --- a/source/paint/text_renderer.cpp +++ b/source/paint/text_renderer.cpp @@ -627,7 +627,7 @@ namespace nana std::unique_ptr pixels(new unsigned[text.size()]); graph_.glyph_pixels(text.c_str(), text.size(), pixels.get()); - unsigned substr_len = 0; + std::size_t substr_len = 0; unsigned substr_px = 0; if (align::right == text_align_ex_) From 1365e1f4e0e78593ddeba49c24e147a50a5960c1 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 25 Jun 2016 06:05:59 +0800 Subject: [PATCH 251/309] restore travis and CMakeLists --- .travis.yml | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- CMakeLists.txt | 41 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5043b5dd..c5ff05f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,6 +82,55 @@ script: - mv -v bin/ nana-demo/ - cd nana-demo/bin - ls - - ./main + - ./a_group_impl + - ./animate-bmp + - ./audio_player + - ./background-effects + #- ./calculator + - ./categ + - ./clicked + - ./decore + - ./dock + - ./drag-button + - ./draw + #- ./file_explorer + #- ./example_menu + - ./example_listbox + #- ./example_combox + - ./example.button + #- ./folder_tree_nana + #- ./folder_tree_std + - ./framework_design_1 + - ./framework_design_2 + - ./framework_design_3 + - ./group + - ./HelloWord + #- ./helloword_quit + #- ./inputbox + - ./label_listener + #- ./lambda_event.cpp11 + - ./listbox_inline_widget + - ./listbox_Resolver + - ./loader_1 + #- ./loader_2 + - ./mbox + - ./menu_debug + #- ./MontiHall + #- ./helloworld_demo + #- ./notepad + - ./menu_debug + - ./menu_popuper + #- ./modal_form + #- ./widget_show2 + #- ./widget_show + - ./place_login + - ./png + #- ./screen + - ./stretch_image + - ./threading + #- ./thread-pool + - ./various_events + #- ./window-dragger + - ./windows-subclassing diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f01f493..e46796a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,9 +320,48 @@ if (NANA_CMAKE_BUILD_DEMOS) enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + set (demos calculator file_explorer helloworld_demo notepad ) + + foreach ( demo ${demos}) + add_executable(${demo} "../nana-demo/${demo}.cpp") + set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} + #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) + #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) + #add_test(${demo} COMMAND ${demo}) + #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") + message("... to build: ../nana-demo/${demo}.cpp" ) + endforeach( demo ${demos}) + + set (demos widget_show widget_show2 ) + + #if (NANA_CMAKE_BUILD_FreeMe) + # add_definitions(-DBUILD_FreeMe) + #endif (NANA_CMAKE_BUILD_FreeMe) + + # if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + # list(APPEND demos ) # ?? FreeMe + # endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) + + foreach ( demo ${demos}) + add_executable(${demo} "../nana-demo/${demo}.cpp") + set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} + install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") + message("... to build: ../nana-demo/${demo}.cpp" ) + endforeach( demo ${demos}) - set (demos main ) + set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked + decore dock drag-button draw example.button example_combox example_listbox example_menu + filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 + group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 + main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image + threading thread-pool various_events window-dragger windows-subclassing + ) # Pending: foreach ( demo ${demos}) From 82d999ecf26109a8456e5af2714e1ec69b4577b8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 03:18:17 +0200 Subject: [PATCH 252/309] FIX filebox in linux with fs_ext --- include/nana/filesystem/filesystem.hpp | 2 - include/nana/filesystem/filesystem_ext.hpp | 61 +------- source/filesystem/filesystem.cpp | 164 +++++++++++++++------ source/gui/filebox.cpp | 22 +-- 4 files changed, 132 insertions(+), 117 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 7fddc3bb..1a447abf 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -359,7 +359,6 @@ namespace nana { namespace experimental { namespace filesystem bool create_directory(const path& p, const path& attributes); //bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept; - bool modified_file_time(const path& p, struct tm&); ///< extention ? /// The time of last data modification of p, determined as if by the value of the POSIX /// stat structure member st_mtime obtained as if by POSIX stat(). @@ -367,7 +366,6 @@ namespace nana { namespace experimental { namespace filesystem /// returns file_time_type::min() if an error occurs //file_time_type last_write_time(const path& p, error_code& ec) noexcept; - path path_user(); ///< extention ? path current_path(); //path current_path(error_code& ec); diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 3711eb59..115c3dd1 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -34,15 +34,14 @@ namespace filesystem_ext constexpr auto def_rootstr = "/"; constexpr auto def_rootname = "Root/"; #endif - -// nana::experimental::filesystem::path_user()); + +std::experimental::filesystem::path path_user(); ///< extention ? inline bool is_directory(const std::experimental::filesystem::directory_entry& dir) noexcept { return is_directory(dir.status()); } - //template // DI = directory_iterator from std, boost, or nana : return directory_entry class directory_only_iterator : public std::experimental::filesystem::directory_iterator { @@ -84,7 +83,6 @@ inline directory_only_iterator end(const directory_only_iterator&) noexcept return{}; } - //template // DI = directory_iterator from std, boost, or nana : value_type directory_entry class regular_file_only_iterator : public std::experimental::filesystem::directory_iterator { @@ -121,60 +119,11 @@ inline regular_file_only_iterator end(const regular_file_only_iterator&) noexcep return{}; } -inline std::string pretty_file_size(const std::experimental::filesystem::path& path) // todo: move to .cpp -{ - try { - auto bytes = std::experimental::filesystem::file_size ( path ); - const char * ustr[] = { " KB", " MB", " GB", " TB" }; - std::stringstream ss; - if (bytes < 1024) - ss << bytes << " Bytes"; - else - { - double cap = bytes / 1024.0; - std::size_t uid = 0; - while ((cap >= 1024.0) && (uid < sizeof(ustr) / sizeof(char *))) - { - cap /= 1024.0; - ++uid; - } - ss << cap; - auto s = ss.str(); - auto pos = s.find('.'); - if (pos != s.npos) - { - if (pos + 2 < s.size()) - s.erase(pos + 2); - } - return s + ustr[uid]; - } +std::string pretty_file_size(const std::experimental::filesystem::path& path); - return ss.str(); - } - catch (...) {} - return {}; -} +std::string pretty_file_date(const std::experimental::filesystem::path& path); -inline std::string pretty_file_date(const std::experimental::filesystem::path& path) // todo: move to .cpp -{ - try { - auto ftime = std::experimental::filesystem::last_write_time(path); - - // crash: VS2015 will not read the time for some files (for example: C:/hiberfil.sys) - // and will return file_time_type(-1) without throwing - // https://msdn.microsoft.com/en-us/library/dn823784.aspx - - if (ftime == ((std::experimental::filesystem::file_time_type::min)())) return {}; - - std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); - std::stringstream tm; - tm << std::put_time(std::localtime(&cftime), "%Y-%m-%d, %H:%M:%S"); - return tm.str(); - } - catch (...) { - return {}; - } -} +bool modified_file_time(const std::experimental::filesystem::path& p, struct tm&); ///< extention ? } // filesystem_ext } // nana diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index fec154d2..8a810f3a 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -12,7 +12,6 @@ */ #include -#if NANA_USING_NANA_FILESYSTEM #include #if defined(NANA_WINDOWS) #include @@ -37,6 +36,120 @@ #include #endif +namespace fs = std::experimental::filesystem; + +namespace nana +{ + namespace filesystem_ext + { + + fs::path path_user() + { +#if defined(NANA_WINDOWS) + wchar_t pstr[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, pstr))) + return pstr; +#elif defined(NANA_LINUX) || defined(NANA_MACOS) + const char * pstr = ::getenv("HOME"); + if (pstr) + return pstr; +#endif + return fs::path(); + } + + std::string pretty_file_size(const fs::path& path) + { + try { + auto bytes = fs::file_size(path); + const char * ustr[] = { " KB", " MB", " GB", " TB" }; + std::stringstream ss; + if (bytes < 1024) + ss << bytes << " Bytes"; + else + { + double cap = bytes / 1024.0; + std::size_t uid = 0; + while ((cap >= 1024.0) && (uid < sizeof(ustr) / sizeof(char *))) + { + cap /= 1024.0; + ++uid; + } + ss << cap; + auto s = ss.str(); + auto pos = s.find('.'); + if (pos != s.npos) + { + if (pos + 2 < s.size()) + s.erase(pos + 2); + } + return s + ustr[uid]; + } + + return ss.str(); + } + catch (...) {} + return{}; + } + + std::string pretty_file_date(const fs::path& path) // todo: move to .cpp + { + try { + auto ftime = fs::last_write_time(path); + + // crash: VS2015 will not read the time for some files (for example: C:/hiberfil.sys) + // and will return file_time_type(-1) without throwing + // https://msdn.microsoft.com/en-us/library/dn823784.aspx + + if (ftime == ((fs::file_time_type::min)())) return{}; + + std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); + std::stringstream tm; + tm << std::put_time(std::localtime(&cftime), "%Y-%m-%d, %H:%M:%S"); + return tm.str(); + } + catch (...) { + return{}; + } + } + + bool modified_file_time(const fs::path& p, struct tm& t) + { +#if defined(NANA_WINDOWS) + WIN32_FILE_ATTRIBUTE_DATA attr; + if (::GetFileAttributesEx(p.c_str(), GetFileExInfoStandard, &attr)) + { + FILETIME local_file_time; + if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time)) + { + SYSTEMTIME st; + ::FileTimeToSystemTime(&local_file_time, &st); + t.tm_year = st.wYear - 1900; + t.tm_mon = st.wMonth - 1; + t.tm_mday = st.wDay; + t.tm_wday = st.wDayOfWeek - 1; + t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); + + t.tm_hour = st.wHour; + t.tm_min = st.wMinute; + t.tm_sec = st.wSecond; + return true; + } + } +#elif defined(NANA_POSIX) + struct stat attr; + if (0 == ::stat(p.c_str(), &attr)) + { + t = *(::localtime(&attr.st_ctime)); + return true; + } +#endif + return false; + } + } +} + +#if NANA_USING_NANA_FILESYSTEM + namespace nana_fs = nana::experimental::filesystem; namespace nana { namespace experimental { namespace filesystem @@ -753,44 +866,11 @@ namespace nana { namespace experimental { namespace filesystem #endif } - bool modified_file_time(const path& p, struct tm& t) - { -#if defined(NANA_WINDOWS) - WIN32_FILE_ATTRIBUTE_DATA attr; - if (::GetFileAttributesEx(p.c_str(), GetFileExInfoStandard, &attr)) - { - FILETIME local_file_time; - if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time)) - { - SYSTEMTIME st; - ::FileTimeToSystemTime(&local_file_time, &st); - t.tm_year = st.wYear - 1900; - t.tm_mon = st.wMonth - 1; - t.tm_mday = st.wDay; - t.tm_wday = st.wDayOfWeek - 1; - t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); - - t.tm_hour = st.wHour; - t.tm_min = st.wMinute; - t.tm_sec = st.wSecond; - return true; - } - } -#elif defined(NANA_POSIX) - struct stat attr; - if (0 == ::stat(p.c_str(), &attr)) - { - t = *(::localtime(&attr.st_ctime)); - return true; - } -#endif - return false; - } file_time_type last_write_time(const path& p) { struct tm t; - modified_file_time(p, t); + nana::filesystem_ext::modified_file_time(p, t); std::chrono::system_clock::time_point dateTime =std::chrono::system_clock::from_time_t( mktime(&t) ); return dateTime; } @@ -823,20 +903,6 @@ namespace nana { namespace experimental { namespace filesystem return detail::rm_file(p); } - path path_user() - { -#if defined(NANA_WINDOWS) - wchar_t pstr[MAX_PATH]; - if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, pstr))) - return pstr; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - const char * pstr = ::getenv("HOME"); - if (pstr) - return pstr; -#endif - return path(); - } - path current_path() { #if defined(NANA_WINDOWS) diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index 2644d910..c18c7a83 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -30,6 +30,8 @@ #endif namespace fs = std::experimental::filesystem; +namespace fs_ext = nana::filesystem_ext; + namespace nana { @@ -55,7 +57,7 @@ namespace nana friend listbox::oresolver& operator<<(listbox::oresolver& ores, const item_fs& item) { std::wstringstream tm; - tm<<(item.modified_time.tm_year + 1900)<<'-'; + tm<<(item.modified_time.tm_year + 1900)<<'-'; /// \todo : use nana::filesystem_ext:: pretty_file_date _m_add(tm, item.modified_time.tm_mon + 1)<<'-'; _m_add(tm, item.modified_time.tm_mday)<<' '; @@ -88,7 +90,7 @@ namespace nana return ss; } - static std::string _m_trans(std::size_t bytes) + static std::string _m_trans(std::size_t bytes) /// \todo : use nana::filesystem_ext::pretty_file_size { const char * ustr[] = {" KB", " MB", " GB", " TB"}; std::stringstream ss; @@ -143,13 +145,13 @@ namespace nana auto path = path_.caption(); auto root = path.substr(0, path.find('/')); if(root == "HOME") - path.replace(0, 4, fs::path_user().native()); + path.replace(0, 4, fs_ext::path_user().native()); else if(root == "FILESYSTEM") path.erase(0, 10); else throw std::runtime_error("Nana.GUI.Filebox: Wrong categorize path"); - if(path.size() == 0) path = "/"; + if(path.size() == 0) path = "/"; /// \todo : use nana::filesystem_ext::def_rootstr? _m_load_cat_path(path); }); @@ -345,7 +347,7 @@ namespace nana else dir = saved_selected_path; - _m_load_cat_path(dir.size() ? dir : fs::path_user().native()); + _m_load_cat_path(dir.size() ? dir : fs_ext::path_user().native()); tb_file_.caption(file_with_path_removed); } @@ -429,7 +431,7 @@ namespace nana nodes_.filesystem.value(kind::filesystem); std::vector paths; - paths.emplace_back(fs::path_user().native()); + paths.emplace_back(fs_ext::path_user().native()); paths.emplace_back("/"); fs::directory_iterator end; @@ -473,7 +475,7 @@ namespace nana { auto begstr = path.substr(0, pos); if(begstr == "FS.HOME") - path.replace(0, 7, fs::path_user().native()); + path.replace(0, 7, fs_ext::path_user().native()); else path.erase(0, pos); return begstr; @@ -505,13 +507,13 @@ namespace nana { m.bytes = fs::file_size(path + m.name); m.directory = fs::is_directory(fattr); - fs::modified_file_time(path + m.name, m.modified_time); + fs_ext::modified_file_time(path + m.name, m.modified_time); } else { m.bytes = 0; m.directory = fs::is_directory(*i); - fs::modified_file_time(path + i->path().filename().native(), m.modified_time); + fs_ext::modified_file_time(path + i->path().filename().native(), m.modified_time); } file_container_.push_back(m); @@ -531,7 +533,7 @@ namespace nana while(!beg_node.empty() && (beg_node != nodes_.home) && (beg_node != nodes_.filesystem)) beg_node = beg_node.owner(); - auto head = fs::path_user().native(); + auto head = fs_ext::path_user().native(); if(path.size() >= head.size() && (path.substr(0, head.size()) == head)) {//This is HOME path_.caption("HOME"); From c71cccc4f6b5c52f1eb582fad8ea3d22f8057ad8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 03:27:39 +0200 Subject: [PATCH 253/309] FIX image in linux --- source/paint/detail/image_jpeg.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/paint/detail/image_jpeg.hpp b/source/paint/detail/image_jpeg.hpp index 2ae4b953..1f19373b 100644 --- a/source/paint/detail/image_jpeg.hpp +++ b/source/paint/detail/image_jpeg.hpp @@ -47,7 +47,7 @@ namespace nana } } public: - bool open(const experimental::filesystem::path& jpeg_file) override + bool open(const std::experimental::filesystem::path& jpeg_file) override { auto fp = ::fopen(to_osmbstr(to_utf8(jpeg_file.native())).c_str(), "rb"); if(nullptr == fp) return false; From a417b17e3093f888372fc0a49d95a09940c7c525 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 13:55:38 +0200 Subject: [PATCH 254/309] reorganize tests --- CMakeLists.txt | 100 ++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e46796a8..1e731c26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,7 @@ endif(UNIX) ########### Compliers # -# Using gcc: gcc 4.8 don't sopourt C++14 and make_unique. You may want to update at least to 4.9. +# Using gcc: gcc 4.8 don't support C++14 and make_unique. You may want to update at least to 4.9. # In Windows, the gcc which come with CLion was 4.8 from MinGW. You may want to install MinGW-w64 from the # TDM-GCC Compiler Suite for Windows which will update you to gcc 5.1. # gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs @@ -311,6 +311,8 @@ endif(NANA_CMAKE_INSTALL_INCLUDES) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) + + # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file if (NANA_CMAKE_BUILD_DEMOS) @@ -320,58 +322,56 @@ if (NANA_CMAKE_BUILD_DEMOS) enable_testing () endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - set (demos calculator file_explorer helloworld_demo notepad ) - - foreach ( demo ${demos}) - add_executable(${demo} "../nana-demo/${demo}.cpp") - set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} - #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - #add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} ) - #add_custom_target(do_always_${demo} ALL COMMAND ${demo}) - #add_test(${demo} COMMAND ${demo}) - #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ../nana-demo/${demo}.cpp" ) - endforeach( demo ${demos}) - - set (demos widget_show widget_show2 ) - - #if (NANA_CMAKE_BUILD_FreeMe) - # add_definitions(-DBUILD_FreeMe) - #endif (NANA_CMAKE_BUILD_FreeMe) - - # if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - # list(APPEND demos ) # ?? FreeMe - # endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe ) - - foreach ( demo ${demos}) - add_executable(${demo} "../nana-demo/${demo}.cpp") - set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} - install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ../nana-demo/${demo}.cpp" ) - endforeach( demo ${demos}) - - - set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked - decore dock drag-button draw example.button example_combox example_listbox example_menu - filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3 - group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2 - main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image - threading thread-pool various_events window-dragger windows-subclassing + + set (demos_dir ../nana-demo/) + set (demos calculator file_explorer helloworld_demo notepad widget_show widget_show2 ) + # Pending: + + set (examples_dir ../nana-demo/Examples/) + set (examples a_group_impl animate-bmp audio_player audio_player_simple + background-effects categ clicked decore + dock drag-button draw example.button + example_combox example_listbox example_menu lambda_event.Cpp11 + filebox-txt folder_tree folder_tree_nana folder_tree_std + framework_design_1 framework_design_2 framework_design_3 label_listener + group HelloWord helloword_quit listbox_inline_widget + inputbox listbox_Resolver loader_1 loader_2 + main mbox menu_debug menu_popuper modal_form + MontiHall place_login png screen + stretch_image threading thread-pool various_events + window-dragger windows-subclassing ) # Pending: - - foreach ( demo ${demos}) - add_executable(${demo} "../nana-demo/Examples/${demo}.cpp") - set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${demo} ${PROJECT_NAME}) # ${NANA_LINKS} or ${CMAKE_EXE_LINKER_FLAGS} - install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/Examples/") - message("... to build: ../nana-demo/Examples/${demo}.cpp" ) - endforeach( demo ${demos}) + if (NANA_CMAKE_BUILD_FreeMe) + add_definitions(-DBUILD_FreeMe) + endif (NANA_CMAKE_BUILD_FreeMe) + if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + list(APPEND demos ) # ?? FreeMe + endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + # Pending: FreeMe (added but really completely compiled if defined BUILD_FreeMe ) + + set (tests) + for (demo ${demos}) + set(tests ${tests} ${demos_dir}${demo}) + endforeach( demo ${demos}) + for (example ${examples}) + set(tests ${tests} ${examples_dir}${example}) + endforeach(example ${examples}) + + + foreach ( test ${tests}) + add_executable(${test} "${test}.cpp") + set_property( TARGET ${test} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${test} ${PROJECT_NAME}) + #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + #add_custom_command( TARGET ${test} POST_BUILD COMMAND ${test} ) + #add_custom_target(do_always_${test} ALL COMMAND ${test}) + #add_test(${test} COMMAND ${test}) + #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + install(TARGETS ${test} RUNTIME DESTINATION "../nana-demo/") + message("... to build: ${test}.cpp" ) + endforeach( test ${tests}) endif (NANA_CMAKE_BUILD_DEMOS) From 91da8d1772d3a293b50e7dec8d09b7109813cdc2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 13:59:10 +0200 Subject: [PATCH 255/309] foreach --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e731c26..032d82d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,10 +352,10 @@ if (NANA_CMAKE_BUILD_DEMOS) # Pending: FreeMe (added but really completely compiled if defined BUILD_FreeMe ) set (tests) - for (demo ${demos}) + foreach (demo ${demos}) set(tests ${tests} ${demos_dir}${demo}) endforeach( demo ${demos}) - for (example ${examples}) + foreach (example ${examples}) set(tests ${tests} ${examples_dir}${example}) endforeach(example ${examples}) From 502171cc4f5d4c019a24eb0726de4030fef8a07f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 14:50:25 +0200 Subject: [PATCH 256/309] function(set_nana_test dir files) --- CMakeLists.txt | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 032d82d6..23ac57d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -351,27 +351,23 @@ if (NANA_CMAKE_BUILD_DEMOS) endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) # Pending: FreeMe (added but really completely compiled if defined BUILD_FreeMe ) - set (tests) - foreach (demo ${demos}) - set(tests ${tests} ${demos_dir}${demo}) - endforeach( demo ${demos}) - foreach (example ${examples}) - set(tests ${tests} ${examples_dir}${example}) - endforeach(example ${examples}) + function(set_nana_test dir files) + foreach ( test ${files}) + add_executable(${test} "${dir}${test}.cpp") + set_property( TARGET ${test} PROPERTY CXX_STANDARD 14 ) + target_link_libraries(${test} ${PROJECT_NAME}) + #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + #add_custom_command( TARGET ${test} POST_BUILD COMMAND ${test} ) + #add_custom_target(do_always_${test} ALL COMMAND ${test}) + #add_test(${test} COMMAND ${test}) + #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + install(TARGETS ${test} RUNTIME DESTINATION "../nana-demo/") + message("... to build: ${dir}${test}.cpp" ) + endforeach( test ${files}) + function(set_nana_test) - - foreach ( test ${tests}) - add_executable(${test} "${test}.cpp") - set_property( TARGET ${test} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${test} ${PROJECT_NAME}) - #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - #add_custom_command( TARGET ${test} POST_BUILD COMMAND ${test} ) - #add_custom_target(do_always_${test} ALL COMMAND ${test}) - #add_test(${test} COMMAND ${test}) - #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - install(TARGETS ${test} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ${test}.cpp" ) - endforeach( test ${tests}) + set_nana_test(demos_dir demos) + set_nana_test(examples_dir examples) endif (NANA_CMAKE_BUILD_DEMOS) From c99759ca67770979621013a79fd1b9cf9314def2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 18:11:42 +0200 Subject: [PATCH 257/309] endfunction --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23ac57d1..888ed1f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,7 +364,7 @@ if (NANA_CMAKE_BUILD_DEMOS) install(TARGETS ${test} RUNTIME DESTINATION "../nana-demo/") message("... to build: ${dir}${test}.cpp" ) endforeach( test ${files}) - function(set_nana_test) + endfunction(set_nana_test) set_nana_test(demos_dir demos) set_nana_test(examples_dir examples) From 55360a40e3f06e80da0d0b490253b64a352a5c3a Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 18:19:31 +0200 Subject: [PATCH 258/309] foreach ( test ${${files}}) --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 888ed1f1..e620b7e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,8 +352,8 @@ if (NANA_CMAKE_BUILD_DEMOS) # Pending: FreeMe (added but really completely compiled if defined BUILD_FreeMe ) function(set_nana_test dir files) - foreach ( test ${files}) - add_executable(${test} "${dir}${test}.cpp") + foreach ( test ${${files}}) + add_executable(${test} "${${dir}}${test}.cpp") set_property( TARGET ${test} PROPERTY CXX_STANDARD 14 ) target_link_libraries(${test} ${PROJECT_NAME}) #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) @@ -362,8 +362,8 @@ if (NANA_CMAKE_BUILD_DEMOS) #add_test(${test} COMMAND ${test}) #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) install(TARGETS ${test} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ${dir}${test}.cpp" ) - endforeach( test ${files}) + message("... to build: ${${dir}}${test}.cpp" ) + endforeach( test ${${files}}) endfunction(set_nana_test) set_nana_test(demos_dir demos) From 88c29e7ac1c8d66210a33c7b77012a59943f6cb9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 18:34:36 +0200 Subject: [PATCH 259/309] Add a new example; textbox_line_number --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e620b7e4..9ebc78bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,7 +329,7 @@ if (NANA_CMAKE_BUILD_DEMOS) set (examples_dir ../nana-demo/Examples/) set (examples a_group_impl animate-bmp audio_player audio_player_simple - background-effects categ clicked decore + background-effects categ clicked windows-subclassing dock drag-button draw example.button example_combox example_listbox example_menu lambda_event.Cpp11 filebox-txt folder_tree folder_tree_nana folder_tree_std @@ -337,9 +337,9 @@ if (NANA_CMAKE_BUILD_DEMOS) group HelloWord helloword_quit listbox_inline_widget inputbox listbox_Resolver loader_1 loader_2 main mbox menu_debug menu_popuper modal_form - MontiHall place_login png screen + MontiHall place_login png textbox_line_number stretch_image threading thread-pool various_events - window-dragger windows-subclassing + window-dragger screen decore ) # Pending: From c747ebed47a7a135285442c901bec09e1ad7d4e0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 18:37:41 +0200 Subject: [PATCH 260/309] test all --- .travis.yml | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed1b44de..21dbcd30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,51 +86,52 @@ script: - ./animate-bmp - ./audio_player - ./background-effects - #- ./calculator + - ./calculator - ./categ - ./clicked - ./decore - ./dock - ./drag-button - ./draw - #- ./file_explorer - #- ./example_menu + - ./file_explorer + - ./example_menu - ./example_listbox - #- ./example_combox + - ./example_combox - ./example.button - #- ./folder_tree_nana - #- ./folder_tree_std + - ./folder_tree_nana + - ./folder_tree_std - ./framework_design_1 - ./framework_design_2 - ./framework_design_3 - ./group - ./HelloWord - #- ./helloword_quit - #- ./inputbox + - ./helloword_quit + - ./inputbox - ./label_listener - #- ./lambda_event.cpp11 + - ./lambda_event.cpp11 - ./listbox_inline_widget - ./listbox_Resolver - ./loader_1 - #- ./loader_2 + - ./loader_2 - ./mbox - ./menu_debug - #- ./MontiHall - #- ./helloworld_demo - #- ./notepad + - ./MontiHall + - ./helloworld_demo + - ./notepad - ./menu_debug - ./menu_popuper - #- ./modal_form - #- ./widget_show2 - #- ./widget_show + - ./modal_form + - ./widget_show2 + - ./widget_show - ./place_login - ./png - #- ./screen + - ./screen - ./stretch_image - ./threading - #- ./thread-pool + - ./thread-pool - ./various_events - #- ./window-dragger + - ./window-dragger - ./windows-subclassing + - ./textbox_line_number From cb33acf2c39e4131791865ce9a989bf546857757 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 19:34:59 +0200 Subject: [PATCH 261/309] 13 of 52 don't pass --- .travis.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21dbcd30..f1ebf4f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,7 +86,7 @@ script: - ./animate-bmp - ./audio_player - ./background-effects - - ./calculator + #- ./calculator # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1159 - ./categ - ./clicked - ./decore @@ -94,38 +94,38 @@ script: - ./drag-button - ./draw - ./file_explorer - - ./example_menu + #- ./example_menu # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1348 - ./example_listbox - - ./example_combox + #- ./example_combox # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1378 - ./example.button - - ./folder_tree_nana - - ./folder_tree_std + #- ./folder_tree_nana # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1408 + #- ./folder_tree_std # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1421 - ./framework_design_1 - ./framework_design_2 - ./framework_design_3 - ./group - ./HelloWord - - ./helloword_quit - - ./inputbox + #- ./helloword_quit # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1572 + #- ./inputbox # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1585 - ./label_listener - - ./lambda_event.cpp11 + - ./lambda_event.Cpp11 - ./listbox_inline_widget - ./listbox_Resolver - ./loader_1 - - ./loader_2 + #- ./loader_2 # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1732 - ./mbox - ./menu_debug - - ./MontiHall - - ./helloworld_demo - - ./notepad + #- ./MontiHall # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1775 + #- ./helloworld_demo # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1786 + #- ./notepad # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1799 - ./menu_debug - ./menu_popuper - - ./modal_form + #- ./modal_form # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1846 - ./widget_show2 - ./widget_show - ./place_login - ./png - - ./screen + #- ./screen # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1909 - ./stretch_image - ./threading - ./thread-pool From 8596da05874250f36eff06102229d87ac6dcf371 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 19:52:59 +0200 Subject: [PATCH 262/309] 16 of 52 don't pass --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f1ebf4f1..58908c54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -121,16 +121,16 @@ script: - ./menu_debug - ./menu_popuper #- ./modal_form # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1846 - - ./widget_show2 - - ./widget_show + #- ./widget_show2 # https://travis-ci.org/qPCR4vir/nana/jobs/140245437#L1730 + #- ./widget_show # https://travis-ci.org/qPCR4vir/nana/jobs/140245437#L1740 - ./place_login - ./png #- ./screen # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1909 - ./stretch_image - - ./threading + - ./threading # https://travis-ci.org/qPCR4vir/nana/jobs/140245437#L1826 ? - ./thread-pool - ./various_events - - ./window-dragger + #- ./window-dragger # https://travis-ci.org/qPCR4vir/nana/jobs/140245438#L1820 - ./windows-subclassing - ./textbox_line_number From 3dd9c7738ed628828c9b556515c3c686ca1de4cd Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 20:16:52 +0200 Subject: [PATCH 263/309] 3 more. 16 of 55 failed, 2 sometimes- threading and thread-pool --- .travis.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 58908c54..d749188c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -75,6 +75,22 @@ before_script : - mkdir bin - cd bin + + + + + + + + + + + + + + + + script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make @@ -98,6 +114,8 @@ script: - ./example_listbox #- ./example_combox # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1378 - ./example.button + - ./filebox-txt + - ./folder_tree #- ./folder_tree_nana # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1408 #- ./folder_tree_std # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1421 - ./framework_design_1 @@ -114,7 +132,9 @@ script: - ./loader_1 #- ./loader_2 # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1732 - ./mbox + - ./main - ./menu_debug + - ./modal_form #- ./MontiHall # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1775 #- ./helloworld_demo # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1786 #- ./notepad # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1799 @@ -128,7 +148,7 @@ script: #- ./screen # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1909 - ./stretch_image - ./threading # https://travis-ci.org/qPCR4vir/nana/jobs/140245437#L1826 ? - - ./thread-pool + - ./thread-pool # https://travis-ci.org/qPCR4vir/nana/jobs/140247564#L1782 - ./various_events #- ./window-dragger # https://travis-ci.org/qPCR4vir/nana/jobs/140245438#L1820 - ./windows-subclassing From e134f34930d8a4004ad1603ebd0fd18229dee42b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 20:27:05 +0200 Subject: [PATCH 264/309] 18 of 55 failed, sometimes- threading and thread-pool too --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d749188c..eaaa0455 100644 --- a/.travis.yml +++ b/.travis.yml @@ -114,7 +114,7 @@ script: - ./example_listbox #- ./example_combox # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1378 - ./example.button - - ./filebox-txt + #- ./filebox-txt # https://travis-ci.org/qPCR4vir/nana/jobs/140250744#L1393 - ./folder_tree #- ./folder_tree_nana # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1408 #- ./folder_tree_std # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1421 @@ -134,7 +134,7 @@ script: - ./mbox - ./main - ./menu_debug - - ./modal_form + #- ./modal_form # https://travis-ci.org/qPCR4vir/nana/jobs/140250744#L1736 #- ./MontiHall # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1775 #- ./helloworld_demo # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1786 #- ./notepad # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1799 From 5d094e286412cf6b84de7f07cfeaba9af26d3180 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sat, 25 Jun 2016 20:35:51 +0200 Subject: [PATCH 265/309] 20 of 55 failed, why sometimes- threading and thread-pool too --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index eaaa0455..4bd87dfd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -147,8 +147,8 @@ script: - ./png #- ./screen # https://travis-ci.org/qPCR4vir/nana/jobs/140238537#L1909 - ./stretch_image - - ./threading # https://travis-ci.org/qPCR4vir/nana/jobs/140245437#L1826 ? - - ./thread-pool # https://travis-ci.org/qPCR4vir/nana/jobs/140247564#L1782 + #- ./threading # https://travis-ci.org/qPCR4vir/nana/jobs/140245437#L1826 ? + #- ./thread-pool # https://travis-ci.org/qPCR4vir/nana/jobs/140247564#L1782 - ./various_events #- ./window-dragger # https://travis-ci.org/qPCR4vir/nana/jobs/140245438#L1820 - ./windows-subclassing From 59922e7b78b8fb3f4b7286c7f9df19c62e874dc6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 26 Jun 2016 05:33:38 +0800 Subject: [PATCH 266/309] remove debug information --- .travis.yml | 2 +- source/gui/detail/window_manager.cpp | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed1b44de..34fe24fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,7 +86,7 @@ script: - ./animate-bmp - ./audio_player - ./background-effects - #- ./calculator + - ./calculator - ./categ - ./clicked - ./decore diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index f685c83b..0af79eb8 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -23,8 +23,6 @@ #include #include -#include //debug travis - namespace nana { @@ -94,9 +92,7 @@ namespace detail { void operator()(basic_window* wd) const { - std::cout << "delete basic_window " << wd <<" category="<(wd->other.category)<< std::endl; delete wd; - std::cout << " delete successfully" << std::endl; } }; From 1aca8c9506411d126b99d19a805034f0cabde298 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 26 Jun 2016 06:01:21 +0800 Subject: [PATCH 267/309] restore travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 34fe24fc..ed1b44de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,7 +86,7 @@ script: - ./animate-bmp - ./audio_player - ./background-effects - - ./calculator + #- ./calculator - ./categ - ./clicked - ./decore From 1eb1ac3a2848d19e4048044a4321d7e444a9926c Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 26 Jun 2016 00:30:10 +0200 Subject: [PATCH 268/309] don't use VS2013 filesytem --- include/nana/c++defines.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 29cb0e0f..609f0eeb 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -58,8 +58,9 @@ # define noexcept //no support of noexcept until Visual C++ 2015 # define constexpr const //no support of constexpr until Visual C++ 2015 ? const ?? -# endif +# else # undef STD_FILESYSTEM_NOT_SUPPORTED +# endif #elif defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ < 6) # define noexcept //no support of noexcept until GCC 4.6 From 24c63e020d3617dce07b0c4949d34be5b1005734 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Sun, 26 Jun 2016 13:55:33 +0200 Subject: [PATCH 269/309] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cd9a692d..a8b4aec5 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Nana C++ Library -[Linux (gcc 5.2.1 and 4.9.2)![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) including [(nana-demos)](https://github.com/qPCR4vir/nana-demo) +[Linux (gcc 5.4.0 and 4.9.2)![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) including [(nana-demos)](https://github.com/qPCR4vir/nana-demo) -[Windows (Microsoft (R) Build Engine version 14.0.24720.0) ![AppVeyor uild status](https://ci.appveyor.com/api/projects/status/5j79p9fi887usv7h?svg=true)](https://ci.appveyor.com/project/qPCR4vir/nana) +[Windows (Microsoft (R) Build Engine version 14.0.24720.0) ![AppVeyor build status](https://ci.appveyor.com/api/projects/status/5j79p9fi887usv7h?svg=true)](https://ci.appveyor.com/project/qPCR4vir/nana) [![Licence](https://img.shields.io/badge/license-BSL-blue.svg?style=flat)](LICENSE_1_0.txt) -Nana is a C++ library designed to allow developers to easily create cross-platform GUI applications with modern C++11 style, currently it can work on Linux(X11) and Windows. The nana repository contains the entire source of library, you can browse the source code and submit your pull request for contributing. +Nana is a C++ library designed to allow developers to easily create cross-platform GUI applications with modern C++11 style. Currently it can work on Linux(X11) and Windows. The [nana repository](https://github.com/cnjinhao/nana) contains the entire source of the library. You can browse the source code and submit your pull request for contributing. ## License @@ -24,7 +24,7 @@ The best way to get help with Nana library is by visiting http://nanapro.org/hel ## Sending a Pull Request ? -This project is encourage you to contribute it through sending a pull request! There is a simple rule, please **don't** directly commit your contributions to the **master** branch. According to your commits, please choose the **hotfixes** branch or the **develop** branch. Thank you! +This project encourage you to contribute through sending a pull request! There is a simple rule: please **don't** directly commit your contributions to the **master** branch. According to your commits, please choose the **hotfixes** branch or the **develop** branch. Thank you! ## Introduction to the Repository From 1845b41019cd73ac2c0b1720f75548e235d87e01 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 27 Jun 2016 00:35:04 +0800 Subject: [PATCH 270/309] remove filesystem_selector --- include/nana/c++defines.hpp | 2 +- include/nana/config.hpp | 2 +- include/nana/filesystem/filesystem.hpp | 71 +++++++++++++-- include/nana/filesystem/filesystem_ext.hpp | 32 ++++--- .../nana/filesystem/filesystem_selector.hpp | 87 ------------------- source/filesystem/filesystem.cpp | 11 ++- 6 files changed, 91 insertions(+), 114 deletions(-) delete mode 100644 include/nana/filesystem/filesystem_selector.hpp diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 609f0eeb..8007666b 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -59,7 +59,7 @@ # define constexpr const //no support of constexpr until Visual C++ 2015 ? const ?? # else -# undef STD_FILESYSTEM_NOT_SUPPORTED +# undef STD_FILESYSTEM_NOT_SUPPORTED # endif #elif defined(__GNUC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ < 6) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 47ab4e4a..17c5cdc2 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -49,7 +49,7 @@ //# The library maybe available in the std library in use or from Boost(almost compatible) //# http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm //# or you can choose to use the(partial, but functional) implementation provided by nana. -//# If you include the file +//# If you include the file //# the selected option will be set by nana into std::experimental::filesystem //# By default Nana will try to use the STD.If not available will try //# to use boost if available.Nana own implementation will be use only none of them are available. diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 1a447abf..836b7778 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -8,7 +8,7 @@ * http://www.boost.org/LICENSE_1_0.txt) * * @file nana/filesystem/filesystem.hpp - * @author Jinhao, conributed: Ariel Vina-Rodriguez + * @author Ariel Vina-Rodriguez, Jinhao * @brief Mimic std::experimental::filesystem::v1 (boost v3) * and need VC2015 or a C++11 compiler. With a few correction can be compiler by VC2013 */ @@ -29,12 +29,54 @@ #ifndef NANA_FILESYSTEM_HPP #define NANA_FILESYSTEM_HPP - -//#undef NANA_USING_NANA_FILESYSTEM -#if NANA_USING_NANA_FILESYSTEM - #include +//Filesystem Selection +#include + +#if defined(NANA_USING_NANA_FILESYSTEM) || defined(NANA_USING_STD_FILESYSTEM) || defined(NANA_USING_BOOST_FILESYSTEM) +#undef NANA_USING_NANA_FILESYSTEM +#undef NANA_USING_STD_FILESYSTEM +#undef NANA_USING_BOOST_FILESYSTEM +#endif + +#define NANA_USING_NANA_FILESYSTEM 0 +#define NANA_USING_STD_FILESYSTEM 0 +#define NANA_USING_BOOST_FILESYSTEM 0 + +#if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) ) + +#undef NANA_USING_NANA_FILESYSTEM +#define NANA_USING_NANA_FILESYSTEM 1 + +#elif (defined(BOOST_FILESYSTEM_AVAILABLE) && ( defined(BOOST_FILESYSTEM_FORCE) || ( defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(STD_FILESYSTEM_FORCE) ) )) + +#undef NANA_USING_BOOST_FILESYSTEM +#define NANA_USING_BOOST_FILESYSTEM 1 +# include + +// add boost::filesystem into std::experimental::filesystem +namespace std { + namespace experimental { + namespace filesystem { + using namespace boost::filesystem; + } // filesystem + } // experimental +} // std + +#else + +#undef NANA_USING_STD_FILESYSTEM +#define NANA_USING_STD_FILESYSTEM 1 +# include +#endif + +#ifndef __cpp_lib_experimental_filesystem +# define __cpp_lib_experimental_filesystem 1 +#endif + +#if NANA_USING_NANA_FILESYSTEM + #include #include #include @@ -413,6 +455,21 @@ namespace nana { namespace experimental { namespace filesystem //namespace filesystem = experimental::filesystem; } //end namespace nana + +namespace std { + namespace experimental { + namespace filesystem { + +# ifdef CXX_NO_INLINE_NAMESPACE + using namespace nana::experimental::filesystem; +# else + using namespace nana::experimental::filesystem::v1; +# endif + } // filesystem + } // experimental +} // std + +#endif //NANA_USING_NANA_FILESYSTEM + #include -#endif -#endif +#endif //NANA_FILESYSTEM_HPP diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp index 115c3dd1..39fc4a07 100644 --- a/include/nana/filesystem/filesystem_ext.hpp +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -15,10 +15,7 @@ #ifndef NANA_FILESYSTEM_EXT_HPP #define NANA_FILESYSTEM_EXT_HPP -#include -#include - -#include +#include namespace nana { @@ -45,7 +42,8 @@ inline bool is_directory(const std::experimental::filesystem::directory_entry& d //template // DI = directory_iterator from std, boost, or nana : return directory_entry class directory_only_iterator : public std::experimental::filesystem::directory_iterator { - using DI = std::experimental::filesystem::directory_iterator; + using directory_iterator = std::experimental::filesystem::directory_iterator; + directory_only_iterator& find_first() { auto end = directory_only_iterator{}; @@ -53,22 +51,22 @@ class directory_only_iterator : public std::experimental::filesystem::directory_ { if (is_directory((**this).status())) return *this; - this->DI::operator++(); + this->directory_iterator::operator++(); } return *this; } public: - directory_only_iterator(){} + directory_only_iterator() = default; - template - directory_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) + template + directory_only_iterator(Arg&& arg, Args&&... args) : directory_iterator(arg, std::forward(args)...) { find_first(); } directory_only_iterator& operator++() { - this->DI::operator++(); + this->directory_iterator::operator++(); return find_first(); } }; @@ -86,25 +84,25 @@ inline directory_only_iterator end(const directory_only_iterator&) noexcept //template // DI = directory_iterator from std, boost, or nana : value_type directory_entry class regular_file_only_iterator : public std::experimental::filesystem::directory_iterator { - using DI = std::experimental::filesystem::directory_iterator; + using directory_iterator = std::experimental::filesystem::directory_iterator; regular_file_only_iterator& find_first() { - while(( (*this) != DI{}) && !is_regular_file((**this).status())) - this->DI::operator++(); + while (((*this) != directory_iterator{}) && !is_regular_file((**this).status())) + this->directory_iterator::operator++(); return (*this); } public: - regular_file_only_iterator() : DI() {} + regular_file_only_iterator() = default; - template - regular_file_only_iterator(Arg&&... arg ): DI(std::forward(arg)...) + template + regular_file_only_iterator(Arg&& arg, Args&&... args) : directory_iterator(std::forward(arg), std::forward(args)...) { find_first(); } regular_file_only_iterator& operator++() { - this->DI::operator++(); + this->directory_iterator::operator++(); return find_first(); } }; diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp deleted file mode 100644 index 0d9c78dd..00000000 --- a/include/nana/filesystem/filesystem_selector.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/** -* Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) -* -* Distributed under the Boost Software License, Version 1.0. -* (See accompanying file LICENSE_1_0.txt or copy at -* http://www.boost.org/LICENSE_1_0.txt) -* -* @file nana\filesystem\filesystem_selector.hpp -* @autor by Ariel Vina-Rodriguez: -* @brief A "ISO C++" filesystem Implementation selector -* -* The ISO C++ File System Technical Specification(ISO - TS, or STD) is optional. -* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf -* This is not a workaround, but an user option. -* The library maybe available in the std library in use or from Boost(almost compatible) -* http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm -* or you can choose to use the(partial, but functional) implementation provided by nana. -* If you include the file -* the selected option will be set by nana into std::experimental::filesystem -* By default Nana will try to use the STD. If not available will try -* to use boost if available. Nana own implementation will be use only if none of them are available. -* nana Now mimic std::experimental::filesystem::v1 (boost v3) -* -*/ - -#ifndef NANA_FILESYSTEM_SELECTOR -#define NANA_FILESYSTEM_SELECTOR - -#include - -#define NANA_USING_NANA_FILESYSTEM false -#define NANA_USING_STD_FILESYSTEM false -#define NANA_USING_BOOST_FILESYSTEM false - -#if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) ) - -#undef NANA_USING_NANA_FILESYSTEM -#define NANA_USING_NANA_FILESYSTEM true -# include - -namespace std { - namespace experimental { - namespace filesystem { - -# ifdef CXX_NO_INLINE_NAMESPACE - using namespace nana::experimental::filesystem; -# else - using namespace nana::experimental::filesystem::v1; -# endif - } // filesystem - } // experimental -} // std - -#elif (defined(BOOST_FILESYSTEM_AVAILABLE) && ( defined(BOOST_FILESYSTEM_FORCE) || ( defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(STD_FILESYSTEM_FORCE) ) )) - -#undef NANA_USING_BOOST_FILESYSTEM -#define NANA_USING_BOOST_FILESYSTEM true -# include - - // add boost::filesystem into std::experimental::filesystem -namespace std { - namespace experimental { - namespace filesystem { - using namespace boost::filesystem; - } // filesystem - } // experimental -} // std - -#else - -#undef NANA_USING_STD_FILESYSTEM -#define NANA_USING_STD_FILESYSTEM true -# include -#endif - -#ifndef __cpp_lib_experimental_filesystem -# define __cpp_lib_experimental_filesystem 1 -#endif - - -#endif // NANA_FILESYSTEM_SELECTOR - - - - - diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index 8a810f3a..745a52a2 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -13,6 +13,9 @@ #include #include +#include +#include //put_time + #if defined(NANA_WINDOWS) #include @@ -102,7 +105,13 @@ namespace nana if (ftime == ((fs::file_time_type::min)())) return{}; - std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); + //std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); + + //A workaround for VC2013 + using time_point = decltype(ftime); + + auto cftime = time_point::clock::to_time_t(ftime); + std::stringstream tm; tm << std::put_time(std::localtime(&cftime), "%Y-%m-%d, %H:%M:%S"); return tm.str(); From 3cf10ef940ce4e3207622bca6cd9e51e7234eaf5 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 27 Jun 2016 07:07:50 +0800 Subject: [PATCH 271/309] fix verbose_preprocessor --- include/nana/verbose_preprocessor.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp index aa0cf104..07b306f8 100644 --- a/include/nana/verbose_preprocessor.hpp +++ b/include/nana/verbose_preprocessor.hpp @@ -95,8 +95,8 @@ #pragma message ( SHOW_VALUE(NANA_USING_STD_FILESYSTEM) ) #pragma message ( SHOW_VALUE(NANA_USING_BOOST_FILESYSTEM) ) - #pragma message ( "\n#include " ) - #include + #pragma message ( "\n#include " ) + #include #pragma message ( SHOW_VALUE(STD_MAKE_UNIQUE_NOT_SUPPORTED) ) #pragma message ( SHOW_VALUE(STD_FILESYSTEM_NOT_SUPPORTED) ) From 11bd0bcf88b6b56cce319020218898700e42e9b7 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 01:24:19 +0200 Subject: [PATCH 272/309] remove filesystem_selector --- build/vc2015/nana.vcxproj | 3 --- build/vc2015/nana.vcxproj.filters | 5 ----- 2 files changed, 8 deletions(-) diff --git a/build/vc2015/nana.vcxproj b/build/vc2015/nana.vcxproj index ce428ef7..e9c0aa02 100644 --- a/build/vc2015/nana.vcxproj +++ b/build/vc2015/nana.vcxproj @@ -249,9 +249,6 @@ - - - diff --git a/build/vc2015/nana.vcxproj.filters b/build/vc2015/nana.vcxproj.filters index aaac3c60..4fcfbb6b 100644 --- a/build/vc2015/nana.vcxproj.filters +++ b/build/vc2015/nana.vcxproj.filters @@ -283,9 +283,4 @@ Source Files\gui\detail - - - Header Files\filesystem - - \ No newline at end of file From a68155c7d70c2e5d05acbd0ad30b96664d27d79f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 01:25:48 +0200 Subject: [PATCH 273/309] Build build demos separately. --- .travis.yml | 22 +++++++----- CMakeLists.txt | 92 ++++---------------------------------------------- 2 files changed, 19 insertions(+), 95 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4bd87dfd..262925d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,6 @@ matrix: - alsa-oss - libx11-dev - libxft-dev - - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test - env: CXX=g++-4.9 CC=gcc-4.9 @@ -35,6 +34,7 @@ matrix: - alsa-oss - libx11-dev - libxft-dev + - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=1 --branch=dev_nana_fs https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=1 --branch=dev_nana_fs https://github.com/qPCR4vir/nana-demo.git ../nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true @@ -66,12 +66,12 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : - # travis dont have a fisical monitor. We need to instal an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/ + # travis don't have a physical monitor. We need to install an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/ - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" - sleep 3 # give xvfb some time to start - # we have: qPCR4vir/nana/nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) - #- cd nana-demo + # we have: qPCR4vir/nana/../nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) + #- cd ../nana-demo - mkdir bin - cd bin @@ -92,11 +92,15 @@ before_script : script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - - cd .. - - mv -v bin/ nana-demo/ - - cd nana-demo/bin + - cd lib + - ls + - cd ../.. + - ls + - mv -v bin/ ../nana-demo/ + - cd ../nana-demo/bin + - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - ls - ./a_group_impl - ./animate-bmp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ebc78bc..99b27e2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,10 +35,8 @@ option(NANA_CMAKE_LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) option(NANA_CMAKE_ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." ON) option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) -option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." ON) -option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON) option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) -option(NANA_CMAKE_BUILD_FreeMe "Build FreeMe (currently broken)?" OFF) + # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. @@ -84,7 +82,6 @@ add_definitions(-DNANA_IGNORE_CONF) if(WIN32) add_definitions(-DWIN32) - # set(BUILD_FreeMe ON) #"Build FreeMe only on Windows." #Global MSVC definitions. You may prefer the hand-tuned sln and projects from the nana repository. if(MSVC) option(WIN32_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON) @@ -106,8 +103,6 @@ if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) set(NANA_LINKS "${NANA_LINKS} -L/opt/X11/lib/ -liconv") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -liconv") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/opt/X11/lib/ -liconv") set(ENABLE_AUDIO OFF) elseif(UNIX) add_definitions(-Dlinux) @@ -116,13 +111,9 @@ endif(APPLE) if(UNIX) set(NANA_LINKS "${NANA_LINKS} -lX11") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lX11") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lX11") find_package(Freetype) if (FREETYPE_FOUND) include_directories( ${FREETYPE_INCLUDE_DIRS}) - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lXft") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lXft") set(NANA_LINKS "${NANA_LINKS} -lXft") endif(FREETYPE_FOUND) endif(UNIX) @@ -152,7 +143,6 @@ endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # enable static linkage if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) # GNU || CLang not MinGW - #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) @@ -169,9 +159,6 @@ if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # A set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") endif () -# set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") - - ############# Optional libraries @@ -179,10 +166,7 @@ endif () #Find PNG if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) - #set(NANA_PNG_LIB "png") set(NANA_LINKS "${NANA_LINKS} -lpng") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lpng") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpng") if(NANA_CMAKE_LIBPNG_FROM_OS) find_package(PNG) if (PNG_FOUND) @@ -195,10 +179,7 @@ endif(NANA_CMAKE_ENABLE_PNG) #Find JPEG if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) - #set(NANA_JPEG_LIB "jpeg") set(NANA_LINKS "${NANA_LINKS} -ljpeg") - # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ljpeg") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljpeg") if(NANA_CMAKE_LIBJPEG_FROM_OS) find_package(JPEG) if (JPEG_FOUND) @@ -215,8 +196,6 @@ if(NANA_CMAKE_ENABLE_AUDIO) if (ASOUND_FOUND) include_directories( ${ASOUND_INCLUDE_DIRS}) set(NANA_LINKS "${NANA_LINKS} -lasound") - # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lasound") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasound") else(ASOUND_FOUND) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) @@ -243,9 +222,7 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) if (Boost_FOUND) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) include_directories(SYSTEM "${Boost_INCLUDE_DIR}") - #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Boost_LIBRARIES}") set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add is not first - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Boost_LIBRARIES}") endif (Boost_FOUND) set(Boost_USE_STATIC_LIBS ON) @@ -255,11 +232,15 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) - if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) +if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + enable_testing () +endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -312,67 +293,6 @@ endif(NANA_CMAKE_INSTALL_INCLUDES) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) - -# TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file - -if (NANA_CMAKE_BUILD_DEMOS) - - if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) - enable_testing () - endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - - - set (demos_dir ../nana-demo/) - set (demos calculator file_explorer helloworld_demo notepad widget_show widget_show2 ) - # Pending: - - set (examples_dir ../nana-demo/Examples/) - set (examples a_group_impl animate-bmp audio_player audio_player_simple - background-effects categ clicked windows-subclassing - dock drag-button draw example.button - example_combox example_listbox example_menu lambda_event.Cpp11 - filebox-txt folder_tree folder_tree_nana folder_tree_std - framework_design_1 framework_design_2 framework_design_3 label_listener - group HelloWord helloword_quit listbox_inline_widget - inputbox listbox_Resolver loader_1 loader_2 - main mbox menu_debug menu_popuper modal_form - MontiHall place_login png textbox_line_number - stretch_image threading thread-pool various_events - window-dragger screen decore - ) - # Pending: - - if (NANA_CMAKE_BUILD_FreeMe) - add_definitions(-DBUILD_FreeMe) - endif (NANA_CMAKE_BUILD_FreeMe) - if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - list(APPEND demos ) # ?? FreeMe - endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) - # Pending: FreeMe (added but really completely compiled if defined BUILD_FreeMe ) - - function(set_nana_test dir files) - foreach ( test ${${files}}) - add_executable(${test} "${${dir}}${test}.cpp") - set_property( TARGET ${test} PROPERTY CXX_STANDARD 14 ) - target_link_libraries(${test} ${PROJECT_NAME}) - #if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - #add_custom_command( TARGET ${test} POST_BUILD COMMAND ${test} ) - #add_custom_target(do_always_${test} ALL COMMAND ${test}) - #add_test(${test} COMMAND ${test}) - #endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - install(TARGETS ${test} RUNTIME DESTINATION "../nana-demo/") - message("... to build: ${${dir}}${test}.cpp" ) - endforeach( test ${${files}}) - endfunction(set_nana_test) - - set_nana_test(demos_dir demos) - set_nana_test(examples_dir examples) - -endif (NANA_CMAKE_BUILD_DEMOS) - - - message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) From 37205f0aa998ea2d76c5f9435744faf501e292bc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 01:37:09 +0200 Subject: [PATCH 274/309] relative dir --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 262925d2..099cc05b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,7 +70,7 @@ before_script : - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" - sleep 3 # give xvfb some time to start - # we have: qPCR4vir/nana/../nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) + # we have: qPCR4vir/nana/../nana-demo and now we are in: qPCR4vir/nana/ our executable tests will access: ../nana-demo/Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) #- cd ../nana-demo - mkdir bin - cd bin @@ -94,7 +94,7 @@ before_script : script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - - cd lib + - cd ../lib - ls - cd ../.. - ls From 11bfe65044e0846d49d8b5740d7a201292f7639b Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Mon, 27 Jun 2016 01:46:05 +0200 Subject: [PATCH 275/309] no tabs --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 099cc05b..d640bb31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ matrix: - alsa-oss - libx11-dev - libxft-dev - - libboost-filesystem-dev + - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test From 6328ae0cfdbd1d73af397b4fc234ff284add6294 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 01:55:05 +0200 Subject: [PATCH 276/309] no cd ../lib --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 099cc05b..8b2fb124 100644 --- a/.travis.yml +++ b/.travis.yml @@ -94,9 +94,9 @@ before_script : script: - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - - cd ../lib - - ls - - cd ../.. + #- cd ../lib + #- ls + - cd .. - ls - mv -v bin/ ../nana-demo/ - cd ../nana-demo/bin From a8219fe760edbe8df9230c880b5a61ad096b838e Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 27 Jun 2016 10:36:08 +0800 Subject: [PATCH 277/309] modifiable mouse wheel scroll step --- include/nana/c++defines.hpp | 2 +- include/nana/gui/basis.hpp | 12 +++++ include/nana/gui/widgets/listbox.hpp | 5 +-- .../widgets/skeletons/text_editor_part.hpp | 2 + source/gui/basis.cpp | 44 ++++++++++++------- source/gui/widgets/listbox.cpp | 21 ++++++--- source/gui/widgets/skeletons/text_editor.cpp | 2 +- 7 files changed, 60 insertions(+), 28 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 8007666b..26ffe63f 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -86,7 +86,7 @@ #define NANA_LINUX #define NANA_X11 #else -# static_assert(false, "Only Windows and Unix are supported now (Mac OS is experimental)"); + static_assert(false, "Only Windows and Unix are supported now (Mac OS is experimental)"); #endif //Define a symbol for POSIX operating system. diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index a80ff3da..a13b3bac 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -284,6 +284,18 @@ that return a corresponding nana::appearance with predefined values. virtual void visible(bool visibility) = 0; virtual bool visible() const = 0; };//end class caret_interface + + namespace parameters + { + /// The system-wide parameters for mouse wheel + struct mouse_wheel + { + unsigned lines; ///< The number of lines to scroll when the vertical mouse wheel is moved. + unsigned characters; ///< The number of characters to scroll when the horizontal mouse wheel is moved. + + mouse_wheel(); + }; + } }//end namespace nana #include diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 699aec19..a21b13ec 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -575,8 +575,6 @@ namespace nana color_proxy header_floated{ static_cast(0xBABBBC)}; color_proxy item_selected{ static_cast(0xD5EFFC) }; - /// \todo how to implement some geometrical parameters ?? - /// The max column width which is generated by fit_content is allowed. It is ignored when it is 0, or a max value is passed to fit_content. unsigned max_fit_content{ 0 }; @@ -591,8 +589,7 @@ namespace nana unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO unsigned header_splitter_area_after { 3 }; ///< def=3. But 4 is better... - //void debug_print(const std::string &msg); - + ::nana::parameters::mouse_wheel mouse_wheel{}; ///< The number of lines/characters to scroll when vertical/horizontal mouse wheel is moved. }; } }//end namespace drawerbase diff --git a/include/nana/gui/widgets/skeletons/text_editor_part.hpp b/include/nana/gui/widgets/skeletons/text_editor_part.hpp index 71d8f525..0b5eb266 100644 --- a/include/nana/gui/widgets/skeletons/text_editor_part.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor_part.hpp @@ -28,6 +28,8 @@ namespace nana { color_proxy selection{static_cast(0x3399FF)}; color_proxy selection_text{colors::white}; + + parameters::mouse_wheel mouse_wheel; ///< The number of lines/characters to scroll when the vertical/horizontal mouse wheel is moved. }; class text_editor_event_interface diff --git a/source/gui/basis.cpp b/source/gui/basis.cpp index 28893fb4..3fe44813 100644 --- a/source/gui/basis.cpp +++ b/source/gui/basis.cpp @@ -14,21 +14,33 @@ #include -namespace nana +using namespace nana; +using namespace nana::parameters; + +//struct appearance +appearance::appearance() + :taskbar(true), floating(false), no_activate(false), + minimize(true), maximize(true), sizable(true), + decoration(true) +{} + +appearance::appearance(bool has_decorate, bool taskbar, bool is_float, bool no_activate, bool min, bool max, bool sizable) + : taskbar(taskbar), floating(is_float), no_activate(no_activate), + minimize(min), maximize(max), sizable(sizable), + decoration(has_decorate) +{} +//end struct appearance + +#if defined(NANA_WINDOWS) +# include +#endif + +mouse_wheel::mouse_wheel() + : lines(3), characters(3) { - //struct appearance - //@brief: Window appearance structure - appearance::appearance() - :taskbar(true), floating(false), no_activate(false), - minimize(true), maximize(true), sizable(true), - decoration(true) - {} - - appearance::appearance(bool has_decorate, bool taskbar, bool is_float, bool no_activate, bool min, bool max, bool sizable) - : taskbar(taskbar), floating(is_float), no_activate(no_activate), - minimize(min), maximize(max), sizable(sizable), - decoration(has_decorate) - {} - //end struct appearance -}//end namespace nana +#if defined(NANA_WINDOWS) + ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0); + ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &characters, 0); +#endif +} diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8cf10cbc..2c485590 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2147,8 +2147,17 @@ namespace nana } /// directly set a tested relative display pos - void set_scroll_y_dpl(const index_pair& pos_dpl) + void set_scroll_y_dpl(index_pair pos_dpl) { + if (lister.first() != pos_dpl) + { + //check the pos_dpl to make sure the last item is at bottom of listbox + const auto numbers = this->number_of_lister_items(false); + const auto distance = lister.distance(pos_dpl, lister.last()); + if (numbers > 1 && distance < numbers) + lister.backward(lister.last(), numbers - 1, pos_dpl); + } + scroll.offset_y_dpl = pos_dpl; if (pos_dpl.is_category()) scroll.offset_y_abs = pos_dpl; @@ -2161,7 +2170,7 @@ namespace nana //number_of_lister_item - /// @brief Returns the number of items that are contained in pixels + /// @brief Returns the number of items that are contained on screen. /// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels. size_type number_of_lister_items(bool with_rest) const { @@ -2509,11 +2518,11 @@ namespace nana if(scroll.v.empty() || !scroll.v.scrollable(upwards)) return false; - index_pair target; - if(upwards == false) - lister.forward(scroll.offset_y_dpl, 1, target); + index_pair target; //index for display + if (upwards == false) + lister.forward(scroll.offset_y_dpl, this->scheme_ptr->mouse_wheel.lines, target); else - lister.backward(scroll.offset_y_dpl, 1, target); + lister.backward(scroll.offset_y_dpl, this->scheme_ptr->mouse_wheel.lines, target); if (target == scroll.offset_y_dpl) return false; diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 3062b445..a63d832f 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -2584,7 +2584,7 @@ namespace nana{ namespace widgets { if(vert && attributes_.vscroll) { - attributes_.vscroll->make_step(!upwards); + attributes_.vscroll->make_step(!upwards, this->scheme_->mouse_wheel.lines); if(_m_scroll_text(true)) { render(true); From 26a2b5ac632d85919fc5cf6d70058f8fd28d1018 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 13:00:44 +0200 Subject: [PATCH 278/309] put in ../nana_lib the lib and the includes --- .travis.yml | 22 +++++++++++++++------- CMakeLists.txt | 11 ++++++++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b0781d4..24bf5051 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,7 +72,10 @@ before_script : - sleep 3 # give xvfb some time to start # we have: qPCR4vir/nana/../nana-demo and now we are in: qPCR4vir/nana/ our executable tests will access: ../nana-demo/Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) #- cd ../nana-demo - - mkdir bin + - mkdir ../nana_lib + - mkdir ../nana_demo_bin + - cd ../nana_lib + - mkdir bin - cd bin @@ -92,15 +95,20 @@ before_script : script: - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + # Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ + # and the includes files "nana" in DESTDIR/CMAKE_INSTALL_PREFIX/include/ + # we are in "... nana/../nana_lib/bin/" we need "../../nana" to get the CMakeList.txt of nana. + # Thus, make install will put the nana.lib in "... nana/../nana_lib/lib/" + # and the includes in "... nana/../nana_lib/include/" + - cmake -G"Unix Makefiles" ../../nana -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - #- cd ../lib - #- ls + - ls + - make install + - ls - cd .. - ls - - mv -v bin/ ../nana-demo/ - - cd ../nana-demo/bin - - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cd ../nana_demo_bin + - cmake -G"Unix Makefiles" ../../nana_demo_bin -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - ls - ./a_group_impl - ./animate-bmp diff --git a/CMakeLists.txt b/CMakeLists.txt index 99b27e2c..782d06cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -279,15 +279,17 @@ target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) # Headers: use INCLUDE_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) - + + # Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ +# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) # Install include directories too. if(NANA_CMAKE_INSTALL_INCLUDES) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/nana - DESTINATION include) + install(DIRECTORY ${NANA_INCLUDE_DIR} + DESTINATION .) endif(NANA_CMAKE_INSTALL_INCLUDES) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) @@ -302,6 +304,9 @@ message ( "CMAKE_STATIC_LINKER_FLAGS= " ${CMAKE_STATIC_LINKER_FLAGS}) message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "DESTDIR = " ${DESTDIR}) message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) +message ( "NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR}) +message ( "CMAKE_CURRENT_SOURCE_DIR= " ${CMAKE_CURRENT_SOURCE_DIR}) + message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO}) message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) From 4886dcd840f85b8f1d1fe956f37fd820e6da48b2 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 13:10:43 +0200 Subject: [PATCH 279/309] build ../nana_demo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 24bf5051..187c6147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,7 +108,7 @@ script: - cd .. - ls - cd ../nana_demo_bin - - cmake -G"Unix Makefiles" ../../nana_demo_bin -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" ../nana_demo -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - ls - ./a_group_impl - ./animate-bmp From 1a1e86fc922c99930ab1153e18fd2de063cd2b41 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 13:16:07 +0200 Subject: [PATCH 280/309] build ../nana-demo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 187c6147..9489d0e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,7 +108,7 @@ script: - cd .. - ls - cd ../nana_demo_bin - - cmake -G"Unix Makefiles" ../nana_demo -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - ls - ./a_group_impl - ./animate-bmp From 72f950282a17233c5561097a77e746c56d2429ee Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 14:15:29 +0200 Subject: [PATCH 281/309] make ../nana-demo --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9489d0e7..278f1de9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -109,6 +109,7 @@ script: - ls - cd ../nana_demo_bin - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - make - ls - ./a_group_impl - ./animate-bmp From b5822df1ec05420d955625afdd7dc9e2106fbb02 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 15:24:28 +0200 Subject: [PATCH 282/309] set the same options !? --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 278f1de9..f9fd896d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,7 +108,7 @@ script: - cd .. - ls - cd ../nana_demo_bin - - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - ls - ./a_group_impl From 5b74b38b1380624a9498c3c9448e3b58dfebf959 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 16:08:00 +0200 Subject: [PATCH 283/309] - mv -v nana-demo/Examples . --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f9fd896d..623ec161 100644 --- a/.travis.yml +++ b/.travis.yml @@ -107,9 +107,13 @@ script: - ls - cd .. - ls - - cd ../nana_demo_bin + - cd .. + - mv -v nana-demo/Examples . + - ls + - cd nana_demo_bin - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make + # todo: separate resources from sources (a directory for images) - ls - ./a_group_impl - ./animate-bmp From fffa89ea5c3554eb79834cfc1f4daed8d93f5be4 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 16:17:24 +0200 Subject: [PATCH 284/309] - cp -v nana-demo/Examples --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 623ec161..e93a748e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,7 +108,7 @@ script: - cd .. - ls - cd .. - - mv -v nana-demo/Examples . + - cp -v nana-demo/Examples . - ls - cd nana_demo_bin - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON From 98ed89c097d4c42d0ca984501457898e5f6e1d32 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 16:35:23 +0200 Subject: [PATCH 285/309] - cp -v ../nana-demo/Examples ../ --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e93a748e..aea4e760 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,6 +74,7 @@ before_script : #- cd ../nana-demo - mkdir ../nana_lib - mkdir ../nana_demo_bin + - cp -v ../nana-demo/Examples ../ - cd ../nana_lib - mkdir bin - cd bin @@ -108,7 +109,6 @@ script: - cd .. - ls - cd .. - - cp -v nana-demo/Examples . - ls - cd nana_demo_bin - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON From a6e8d88ae8fd83e6a0037d46612f77f1a1e2812f Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 16:59:26 +0200 Subject: [PATCH 286/309] install -DCMAKE_INSTALL_PREFIX=.. --- .travis.yml | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index aea4e760..c0501a89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,27 +74,10 @@ before_script : #- cd ../nana-demo - mkdir ../nana_lib - mkdir ../nana_demo_bin - - cp -v ../nana-demo/Examples ../ - cd ../nana_lib - mkdir bin - cd bin - - - - - - - - - - - - - - - - script: # Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ # and the includes files "nana" in DESTDIR/CMAKE_INSTALL_PREFIX/include/ @@ -103,7 +86,6 @@ script: # and the includes in "... nana/../nana_lib/include/" - cmake -G"Unix Makefiles" ../../nana -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make - - ls - make install - ls - cd .. @@ -111,7 +93,7 @@ script: - cd .. - ls - cd nana_demo_bin - - cmake -G"Unix Makefiles" ../nana-demo -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON + - cmake -G"Unix Makefiles" ../nana-demo -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make # todo: separate resources from sources (a directory for images) - ls From 1a0761c59b94fc26c42c47f7fd4b1e3ca6d45ffd Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 27 Jun 2016 17:00:36 +0200 Subject: [PATCH 287/309] - cd ../bin --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index c0501a89..3c7d5312 100644 --- a/.travis.yml +++ b/.travis.yml @@ -95,8 +95,11 @@ script: - cd nana_demo_bin - cmake -G"Unix Makefiles" ../nana-demo -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - make + - make install # todo: separate resources from sources (a directory for images) - ls + - cd ../bin + - ls - ./a_group_impl - ./animate-bmp - ./audio_player From 8b19d0d12e87239b963a014b59a8eceddfe57d88 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 28 Jun 2016 14:00:16 +0200 Subject: [PATCH 288/309] FIX compiler error SPI_GETWHEELSCROLLCHARS not found --- source/gui/basis.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/gui/basis.cpp b/source/gui/basis.cpp index 3fe44813..fc8c92eb 100644 --- a/source/gui/basis.cpp +++ b/source/gui/basis.cpp @@ -39,6 +39,9 @@ mouse_wheel::mouse_wheel() : lines(3), characters(3) { #if defined(NANA_WINDOWS) + // https://msdn.microsoft.com/en-us/library/ms997498.aspx + #define SPI_SETWHEELSCROLLCHARS 0x006D + #define SPI_GETWHEELSCROLLCHARS 0x006C ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0); ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &characters, 0); #endif From b32afa282ce20f929afcf896a805d84a7edea76c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 28 Jun 2016 21:21:47 +0800 Subject: [PATCH 289/309] minor change --- source/gui/basis.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/gui/basis.cpp b/source/gui/basis.cpp index fc8c92eb..e6742807 100644 --- a/source/gui/basis.cpp +++ b/source/gui/basis.cpp @@ -40,8 +40,10 @@ mouse_wheel::mouse_wheel() { #if defined(NANA_WINDOWS) // https://msdn.microsoft.com/en-us/library/ms997498.aspx - #define SPI_SETWHEELSCROLLCHARS 0x006D - #define SPI_GETWHEELSCROLLCHARS 0x006C + //#define SPI_SETWHEELSCROLLCHARS 0x006D +# ifndef SPI_GETWHEELSCROLLCHARS +# define SPI_GETWHEELSCROLLCHARS 0x006C +# endif ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &lines, 0); ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &characters, 0); #endif From 87d8f692c531824a8e3e93823d345ae812898602 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 30 Jun 2016 15:57:41 +0200 Subject: [PATCH 290/309] cleaning --- CMakeLists.txt | 218 +++++++++------------ include/nana/gui/detail/window_manager.hpp | 2 +- 2 files changed, 99 insertions(+), 121 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 782d06cc..338596f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,16 +13,13 @@ # generate here configurated *.h files or explicitly enumerate the sources files: anyway this CM-list # will be "touched" to force a re-run of cmake. - #https://cmake.org/cmake-tutorial/ #https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption # use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir # if your changes don't execute - # It seems that project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES. # https://bbs.archlinux.org/viewtopic.php?id=84967 - project(nana) cmake_minimum_required(VERSION 2.8) @@ -34,50 +31,37 @@ option(NANA_CMAKE_ENABLE_JPEG "Enable the use of JPEG" OFF) option(NANA_CMAKE_LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) option(NANA_CMAKE_ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." ON) -option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) +option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." OFF) option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) - - # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf # This is not a workaround, but an user option. # The library maybe available in the std library in use or from Boost (almost compatible) # http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm # or you can choose to use the (partial, but functional) implementation provided by nana. -# If you include the file -# The selected option will be set by nana into std::experimental::filesystem -# By default Nana will try to use the STD. If not available will try -# to use boost if available. Nana own implementation will be use only none of them are available. +# If you include the file or +# the selected option will be set by nana into std::experimental::filesystem +# By default Nana will try to use the STD. If STD is not available and NANA_CMAKE_FIND_BOOST_FILESYSTEM +# is set to ON nana will try to use boost if available. Nana own implementation will be use if none of +# the previus were selected or available. # You can change that default if you change one of the following # (please don't define more than one of the _XX_FORCE options): -option(NANA_CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" ON) +option(NANA_CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" OFF) option(NANA_CMAKE_NANA_FILESYSTEM_FORCE "Force nana filesystem over ISO and boost?" OFF) option(NANA_CMAKE_STD_FILESYSTEM_FORCE "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF) option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over STD)?" OFF) -# cmake will find the package self, if don't works set the following (please find the correct values): -#option(NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") -#option(NANA_CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") -#include_directories("${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") -#set(NANA_LINKS "${NANA_LINKS} ${NANA_CMAKE_BOOST_FILESYSTEM_LIB}") - - - ########### Compatibility with CMake 3.1 if(POLICY CMP0054) # http://www.cmake.org/cmake/help/v3.1/policy/CMP0054.html cmake_policy(SET CMP0054 OLD) endif() - if(POLICY CMP0004) # ignore leading space # http://www.cmake.org/cmake/help/v3.0/policy/CMP0004.html cmake_policy(SET CMP0004 OLD) endif() -add_definitions(-DNANA_IGNORE_CONF) - - ########### OS if(WIN32) @@ -119,7 +103,7 @@ if(UNIX) endif(UNIX) -########### Compliers +########### Compilers # # Using gcc: gcc 4.8 don't support C++14 and make_unique. You may want to update at least to 4.9. # In Windows, the gcc which come with CLion was 4.8 from MinGW. You may want to install MinGW-w64 from the @@ -127,8 +111,6 @@ endif(UNIX) # gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs # # see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html - -# set compile flags if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") @@ -141,29 +123,92 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") -# enable static linkage -if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) # GNU || CLang not MinGW - set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") - +# enable static linkage # GNU || CLang not MinGW +if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AND NOT MINGW + # set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") + set(NANA_LINKS "${NANA_LINKS} -static-libgcc -static-libstdc++ -pthread") + # message("Setting NANA_LINKS to -static-libgcc -static-libstdc++ -pthread or ${NANA_LINKS}") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) # IS_GNUCXX < 5.3 else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more + # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more set(NANA_LINKS "${NANA_LINKS} -lstdc++fs") endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) -endif (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT MINGW) +endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AND NOT MINGW if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") + # set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++") + set(NANA_LINKS "${NANA_LINKS} -stdlib=libstdc++") endif () +######## Nana options + +add_definitions(-DNANA_IGNORE_CONF) +if(NANA_CMAKE_VERBOSE_PREPROCESSOR) + add_definitions(-DVERBOSE_PREPROCESSOR) +endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) +if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + enable_testing () +endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + + +####################### Main setting of Nana sources, targets and install + +set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) +set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +# collect all source sub-directories in a list to avoid duplication here +set(NANA_SOURCE_SUBDIRS /. + /detail + /filesystem + /gui + /gui/detail + /gui/widgets + /gui/widgets/skeletons + /paint + /paint/detail + /system + /threads ) +if(NANA_CMAKE_ENABLE_AUDIO) + list(APPEND NANA_SOURCE_SUBDIRS + /audio + /audio/detail ) +endif(NANA_CMAKE_ENABLE_AUDIO) +# collect all source files in the source-sub-dir +# To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library +# and Use SOURCE_GROUP if all your sources are in the same directory +foreach(subdir ${NANA_SOURCE_SUBDIRS}) + aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) + # message("Subir: ${subdir}") # message("Files: ${sources}") +endforeach(subdir ${NANA_SOURCE_SUBDIRS}) + +include_directories(${NANA_INCLUDE_DIR}) +add_library(${PROJECT_NAME} ${sources} ) +target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) + + # Headers: use INCLUDE_DIRECTORIES + # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) + +# Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ +# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ +install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") +# Install the include directories too. +if(NANA_CMAKE_INSTALL_INCLUDES) + install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include ) + message("The Nana include files will be installed in ${CMAKE_INSTALL_PREFIX}/include") +endif(NANA_CMAKE_INSTALL_INCLUDES) + +set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) + ############# Optional libraries -#Find PNG +# Find PNG if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) set(NANA_LINKS "${NANA_LINKS} -lpng") @@ -176,7 +221,7 @@ if(NANA_CMAKE_ENABLE_PNG) endif(NANA_CMAKE_LIBPNG_FROM_OS) endif(NANA_CMAKE_ENABLE_PNG) -#Find JPEG +# Find JPEG if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) set(NANA_LINKS "${NANA_LINKS} -ljpeg") @@ -189,124 +234,57 @@ if(NANA_CMAKE_ENABLE_JPEG) endif(NANA_CMAKE_LIBJPEG_FROM_OS) endif(NANA_CMAKE_ENABLE_JPEG) +# Find ASOUND if(NANA_CMAKE_ENABLE_AUDIO) add_definitions(-DNANA_ENABLE_AUDIO) if(UNIX) find_package(ASOUND) if (ASOUND_FOUND) include_directories( ${ASOUND_INCLUDE_DIRS}) - set(NANA_LINKS "${NANA_LINKS} -lasound") + set(NANA_LINKS "${NANA_LINKS} -lasound") else(ASOUND_FOUND) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) endif(UNIX) endif(NANA_CMAKE_ENABLE_AUDIO) +# Find/Select filesystem if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) add_definitions(-DNANA_FILESYSTEM_FORCE) - elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE) add_definitions(-DSTD_FILESYSTEM_FORCE) - elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) - - if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) + if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) - endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) - + endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) # https://cmake.org/cmake/help/git-master/module/FindBoost.html - # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, - # even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries. - # If using Boost::thread, then Thread::Thread will also be added automatically. + # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, + # even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries. + # If using Boost::thread, then Thread::Thread will also be added automatically. find_package(Boost COMPONENTS filesystem) - if (Boost_FOUND) - add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) - include_directories(SYSTEM "${Boost_INCLUDE_DIR}") - set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add is not first - endif (Boost_FOUND) - - set(Boost_USE_STATIC_LIBS ON) - set(Boost_USE_STATIC_RUNTIME ON) # ?? - #set(Boost_USE_MULTITHREADED ON) - + if (Boost_FOUND) + add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) + include_directories(SYSTEM "${Boost_INCLUDE_DIR}") + set(NANA_LINKS "${NANA_LINKS} ${Boost_LIBRARIES}") ###### FIRST !!!!!!!!!!!!!!!!! add is not first + endif (Boost_FOUND) + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_STATIC_RUNTIME ON) # ?? endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) +#set(NANA_LINKS B) -if(NANA_CMAKE_VERBOSE_PREPROCESSOR) - add_definitions(-DVERBOSE_PREPROCESSOR) -endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) - -if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) - enable_testing () -endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - - -set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) -set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) - -# collect all source sub-directories in a list to avoid duplication here -set(NANA_SOURCE_SUBDIRS /. - /detail - /filesystem - /gui - /gui/detail - /gui/widgets - /gui/widgets/skeletons - /paint - /paint/detail - /system - /threads ) -if(NANA_CMAKE_ENABLE_AUDIO) - list(APPEND NANA_SOURCE_SUBDIRS - /audio - /audio/detail ) -endif() - -# collect all source files in the source-sub-dir -#To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library -#and Use SOURCE_GROUP if all your sources are in the same directory -foreach(subdir ${NANA_SOURCE_SUBDIRS}) - aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) - # message("Subir: ${subdir}") - # message("Files: ${sources}") -endforeach(subdir ${NANA_SOURCE_SUBDIRS}) - -include_directories(${NANA_INCLUDE_DIR}) -add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) - - # Headers: use INCLUDE_DIRECTORIES - # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) - - - # Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ -# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - -# Install include directories too. -if(NANA_CMAKE_INSTALL_INCLUDES) - install(DIRECTORY ${NANA_INCLUDE_DIR} - DESTINATION .) -endif(NANA_CMAKE_INSTALL_INCLUDES) - -set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) - - +# Just for information: message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) -message ( "CMAKE_STATIC_LINKER_FLAGS= " ${CMAKE_STATIC_LINKER_FLAGS}) +message ( "CMAKE_STATIC_LINKER_FLAGS=" ${CMAKE_STATIC_LINKER_FLAGS}) message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "DESTDIR = " ${DESTDIR}) message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) message ( "NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR}) message ( "CMAKE_CURRENT_SOURCE_DIR= " ${CMAKE_CURRENT_SOURCE_DIR}) - message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO}) message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index e7cbf5ca..268547c0 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -1,4 +1,4 @@ -/* +/** * Window Manager Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) From b5706bab175e7f05eed6bfc6fad5d2be0ad70e00 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 30 Jun 2016 16:05:47 +0200 Subject: [PATCH 291/309] make install only (in travis) --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c7d5312..766f5b2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,7 +85,6 @@ script: # Thus, make install will put the nana.lib in "... nana/../nana_lib/lib/" # and the includes in "... nana/../nana_lib/include/" - cmake -G"Unix Makefiles" ../../nana -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - - make - make install - ls - cd .. @@ -94,7 +93,6 @@ script: - ls - cd nana_demo_bin - cmake -G"Unix Makefiles" ../nana-demo -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - - make - make install # todo: separate resources from sources (a directory for images) - ls From bb79dcbefc469217aafd82e12ccc768d0cf507ac Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 30 Jun 2016 16:35:11 +0200 Subject: [PATCH 292/309] return optional librarirs first in cmake --- CMakeLists.txt | 124 ++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 338596f3..5c9c9c97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,68 +144,6 @@ if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # A endif () -######## Nana options - -add_definitions(-DNANA_IGNORE_CONF) -if(NANA_CMAKE_VERBOSE_PREPROCESSOR) - add_definitions(-DVERBOSE_PREPROCESSOR) -endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) -if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) - enable_testing () -endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - - -####################### Main setting of Nana sources, targets and install - -set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) -set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) -# collect all source sub-directories in a list to avoid duplication here -set(NANA_SOURCE_SUBDIRS /. - /detail - /filesystem - /gui - /gui/detail - /gui/widgets - /gui/widgets/skeletons - /paint - /paint/detail - /system - /threads ) -if(NANA_CMAKE_ENABLE_AUDIO) - list(APPEND NANA_SOURCE_SUBDIRS - /audio - /audio/detail ) -endif(NANA_CMAKE_ENABLE_AUDIO) -# collect all source files in the source-sub-dir -# To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library -# and Use SOURCE_GROUP if all your sources are in the same directory -foreach(subdir ${NANA_SOURCE_SUBDIRS}) - aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) - # message("Subir: ${subdir}") # message("Files: ${sources}") -endforeach(subdir ${NANA_SOURCE_SUBDIRS}) - -include_directories(${NANA_INCLUDE_DIR}) -add_library(${PROJECT_NAME} ${sources} ) -target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) - - # Headers: use INCLUDE_DIRECTORIES - # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) - -# Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ -# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ -install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) -message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") -# Install the include directories too. -if(NANA_CMAKE_INSTALL_INCLUDES) - install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include ) - message("The Nana include files will be installed in ${CMAKE_INSTALL_PREFIX}/include") -endif(NANA_CMAKE_INSTALL_INCLUDES) - -set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) - - ############# Optional libraries # Find PNG @@ -271,7 +209,67 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) set(Boost_USE_STATIC_RUNTIME ON) # ?? endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) -#set(NANA_LINKS B) + +######## Nana options + +add_definitions(-DNANA_IGNORE_CONF) +if(NANA_CMAKE_VERBOSE_PREPROCESSOR) + add_definitions(-DVERBOSE_PREPROCESSOR) +endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) +if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + enable_testing () +endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + + +####################### Main setting of Nana sources, targets and install + +set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) +set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +# collect all source sub-directories in a list to avoid duplication here +set(NANA_SOURCE_SUBDIRS /. + /detail + /filesystem + /gui + /gui/detail + /gui/widgets + /gui/widgets/skeletons + /paint + /paint/detail + /system + /threads ) +if(NANA_CMAKE_ENABLE_AUDIO) + list(APPEND NANA_SOURCE_SUBDIRS + /audio + /audio/detail ) +endif(NANA_CMAKE_ENABLE_AUDIO) +# collect all source files in the source-sub-dir +# To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library +# and Use SOURCE_GROUP if all your sources are in the same directory +foreach(subdir ${NANA_SOURCE_SUBDIRS}) + aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) + # message("Subir: ${subdir}") # message("Files: ${sources}") +endforeach(subdir ${NANA_SOURCE_SUBDIRS}) + +include_directories(${NANA_INCLUDE_DIR}) +add_library(${PROJECT_NAME} ${sources} ) +target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) + + # Headers: use INCLUDE_DIRECTORIES + # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) + +# Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ +# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ +install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") +# Install the include directories too. +if(NANA_CMAKE_INSTALL_INCLUDES) + install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include ) + message("The Nana include files will be installed in ${CMAKE_INSTALL_PREFIX}/include") +endif(NANA_CMAKE_INSTALL_INCLUDES) + +set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) # Just for information: message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) From ddc88e0af073019738e89504f07bed5ca3728478 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 30 Jun 2016 17:54:51 +0200 Subject: [PATCH 293/309] travis test with nana-demo/develop branch --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 766f5b2b..170ef287 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=1 --branch=dev_nana_fs https://github.com/qPCR4vir/nana-demo.git ../nana-demo + - git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git ../nana-demo - export PATH="$HOME/bin:$PATH" - mkdir ~/bin - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true From 72768fd788a5a6efdabeec0d17594e11c12dbc02 Mon Sep 17 00:00:00 2001 From: dankan1890 Date: Thu, 30 Jun 2016 20:46:02 +0200 Subject: [PATCH 294/309] fix PNG build. --- source/paint/detail/image_png.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/paint/detail/image_png.hpp b/source/paint/detail/image_png.hpp index 9e01e8c6..30ba18e5 100644 --- a/source/paint/detail/image_png.hpp +++ b/source/paint/detail/image_png.hpp @@ -121,7 +121,7 @@ namespace nana delete[] row_ptrs; } public: - bool open(const experimental::filesystem::path& png_file) override + bool open(const std::experimental::filesystem::path& png_file) override { auto fp = ::fopen(to_osmbstr(to_utf8(png_file.native())).c_str(), "rb"); if(nullptr == fp) return false; From 8c7051566c74d32ad0808a3017547e648a9d58a8 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 1 Jul 2016 23:43:48 +0800 Subject: [PATCH 295/309] optimize binary size --- include/nana/gui/detail/handle_manager.hpp | 2 +- .../gui/widgets/skeletons/text_editor.hpp | 2 +- .../nana/gui/widgets/skeletons/textbase.hpp | 8 +- source/gui/msgbox.cpp | 2 +- source/gui/notifier.cpp | 2 +- source/gui/place.cpp | 45 ++-- source/gui/place_parts.hpp | 19 +- source/gui/tooltip.cpp | 23 +- source/gui/widgets/menu.cpp | 6 +- source/gui/widgets/menubar.cpp | 2 +- source/gui/widgets/skeletons/text_editor.cpp | 245 +++++++++--------- source/gui/widgets/spinbox.cpp | 2 +- source/internationalization.cpp | 2 +- 13 files changed, 180 insertions(+), 180 deletions(-) diff --git a/include/nana/gui/detail/handle_manager.hpp b/include/nana/gui/detail/handle_manager.hpp index 716433be..6319e319 100644 --- a/include/nana/gui/detail/handle_manager.hpp +++ b/include/nana/gui/detail/handle_manager.hpp @@ -173,7 +173,7 @@ namespace nana { is_queue::value, std::vector >::erase(handle, queue_); cacher_.insert(handle, false); - trash_.emplace_back(i->first, i->second); + trash_.push_back(*i); holder_.erase(i); } } diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index c1fb06fa..7054899a 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -310,7 +310,7 @@ namespace nana{ namespace widgets unsigned _m_char_by_pixels(const unicode_bidi::entity&, unsigned pos); - unsigned _m_pixels_by_char(const ::std::wstring&, std::size_t pos) const; + unsigned _m_pixels_by_char(const ::std::wstring&, ::std::size_t pos) const; void _handle_move_key(const arg_keyboard& arg); private: diff --git a/include/nana/gui/widgets/skeletons/textbase.hpp b/include/nana/gui/widgets/skeletons/textbase.hpp index 1c4085b2..55828351 100644 --- a/include/nana/gui/widgets/skeletons/textbase.hpp +++ b/include/nana/gui/widgets/skeletons/textbase.hpp @@ -135,7 +135,7 @@ namespace skeletons while(ifs.good()) { std::getline(ifs, str_mbs); - text_cont_.emplace_back(nana::charset(str_mbs)); + text_cont_.emplace_back(static_cast(nana::charset{ str_mbs })); if(text_cont_.back().size() > attr_max_.size) { attr_max_.size = text_cont_.back().size(); @@ -218,7 +218,7 @@ namespace skeletons byte_order_translate_4bytes(str); } - text_cont_.emplace_back(nana::charset(str, encoding)); + text_cont_.emplace_back(static_cast(nana::charset{ str, encoding })); attr_max_.size = text_cont_.back().size(); attr_max_.line = 0; @@ -236,7 +236,7 @@ namespace skeletons byte_order_translate_4bytes(str); } - text_cont_.emplace_back(nana::charset(str, encoding)); + text_cont_.emplace_back(static_cast(nana::charset{ str, encoding })); if(text_cont_.back().size() > attr_max_.size) { attr_max_.size = text_cont_.back().size(); @@ -406,7 +406,7 @@ namespace skeletons void erase_all() { - std::deque().swap(text_cont_); + text_cont_.clear(); attr_max_.reset(); text_cont_.emplace_back(); //text_cont_ must not be empty diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 7008e401..6faefc4c 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -1128,7 +1128,7 @@ namespace nana impl->browse.create(impl->dock); impl->browse.i18n(i18n_eval("Browse")); - impl->browse.events().click([wd, impl](const arg_click&) + impl->browse.events().click.connect_unignorable([wd, impl](const arg_click&) { impl->fbox.owner(wd); if (impl->fbox.show()) diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 0324919a..e46541c9 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -268,7 +268,7 @@ namespace nana #endif }); - impl_->evt_destroy = API::events(wd).destroy([this] + impl_->evt_destroy = API::events(wd).destroy.connect([this](const arg_destroy&) { close(); }); diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 01b70de1..4b9e135b 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -572,7 +572,7 @@ namespace nana //Listen to destroy of a window. The deleting a fastened window //does not change the layout. - auto evt = API::events(wd).destroy([this](const arg_destroy& arg) + auto evt = API::events(wd).destroy.connect([this](const arg_destroy& arg) { erase_element(fastened, arg.window_handle); }); @@ -1015,12 +1015,14 @@ namespace nana auto find_lowest = [&revises](double level_px) { double v = (std::numeric_limits::max)(); + for (auto i = revises.begin(); i != revises.end(); ++i) { - if (i->min_px >= 0 && i->min_px < v && i->min_px > level_px) - v = i->min_px; - else if (i->max_px >= 0 && i->max_px < v) - v = i->max_px; + auto & rev = *i; + if (rev.min_px >= 0 && rev.min_px < v && rev.min_px > level_px) + v = rev.min_px; + else if (rev.max_px >= 0 && rev.max_px < v) + v = rev.max_px; } return v; }; @@ -1639,7 +1641,7 @@ namespace nana indicator_.docker->z_order(nullptr, ::nana::z_order_action::topmost); indicator_.docker->show(); - indicator_.docker->events().destroy([this](const arg_destroy&) + indicator_.docker->events().destroy.connect([this](const arg_destroy&) { if (indicator_.dock_area) { @@ -1860,9 +1862,9 @@ namespace nana }; auto & evt = this->events(); - evt.mouse_down(grab_fn); - evt.mouse_up(grab_fn); - evt.mouse_move(grab_fn); + evt.mouse_down.connect(grab_fn); + evt.mouse_up.connect(grab_fn); + evt.mouse_move.connect(grab_fn); } void range(int begin, int end) @@ -1886,10 +1888,10 @@ namespace nana division* front() const { - for (auto i = children.cbegin(); i != children.cend(); ++i) + for (auto & child : children) { - if (i->get()->display) - return i->get(); + if (child->display) + return child.get(); } return nullptr; @@ -2181,7 +2183,7 @@ namespace nana { auto splitter = new div_splitter(tknizer.number()); children.back()->div_next = splitter; - children.emplace_back(splitter); + children.emplace_back(std::unique_ptr{ splitter }); } break; case token::div_start: @@ -2190,7 +2192,7 @@ namespace nana if (!children.empty()) children.back()->div_next = div.get(); - children.emplace_back(div.release()); + children.emplace_back(std::move(div)); } break; case token::vert: @@ -2430,7 +2432,7 @@ namespace nana auto dockpn = new div_dockpane(std::move(child->name), this, child->dir); dockpn->div_owner = child->div_owner; dockpn->weight = child->weight; - adjusted_children.emplace_back(dockpn); + adjusted_children.emplace_back(std::unique_ptr{ dockpn }); } division * next = nullptr; @@ -2646,11 +2648,11 @@ namespace nana implement::division * div_next = div_ptr->div_next; if (div_owner) { - for (auto i = div_owner->children.begin(); i != div_owner->children.end(); ++i) + for (auto& child: div_owner->children) { - if (i->get() == div_ptr) + if (child.get() == div_ptr) { - replaced = &(*i); + replaced = &child; break; } } @@ -2702,7 +2704,7 @@ namespace nana { //search the division with the specified name, //and attached the division to the field - implement::division * div = implement::search_div_name(impl_->root_division.get(), name); + auto div = implement::search_div_name(impl_->root_division.get(), name); if (div) { if (div->field && (div->field != p)) @@ -2803,12 +2805,11 @@ namespace nana //Register the factory if it has a name if (!factory_name.empty()) { - auto i = impl_->dock_factoris.find(factory_name); - if (i != impl_->dock_factoris.end()) + if (impl_->dock_factoris.find(factory_name) != impl_->dock_factoris.end()) throw std::invalid_argument("nana::place - the specified factory name(" + factory_name + ") already exists"); impl_->dock_factoris[factory_name] = dock_ptr; - dock_ptr->factories[factory_name].swap(factory); + dock_ptr->factories[factory_name] = std::move(factory); } auto div = dynamic_cast(impl_->search_div_name(impl_->root_division.get(), name)); diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index d9d7c2d7..2bd29c1d 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -164,10 +164,7 @@ namespace nana : public widget_object < category::widget_tag, dockcaption_dtrigger > { public: - void on_close(std::function fn) - { - get_drawer_trigger().on_close(std::move(fn)); - } + using widget_object::get_drawer_trigger; }; class dockarea @@ -192,7 +189,7 @@ namespace nana base_type::create(parent, true); this->caption("dockarea"); caption_.create(*this, true); - caption_.on_close([this] + caption_.get_drawer_trigger().on_close([this] { bool destroy_dockarea = true; @@ -207,7 +204,7 @@ namespace nana notifier_->request_close(); }); - this->events().resized([this](const arg_resized& arg) + this->events().resized.connect([this](const arg_resized& arg) { rectangle r{ 0, 0, arg.width, 20 }; caption_.move(r); @@ -272,9 +269,9 @@ namespace nana } }; - caption_.events().mouse_down(grab_fn); - caption_.events().mouse_move(grab_fn); - caption_.events().mouse_up(grab_fn); + caption_.events().mouse_down.connect(grab_fn); + caption_.events().mouse_move.connect(grab_fn); + caption_.events().mouse_up.connect(grab_fn); } @@ -307,7 +304,7 @@ namespace nana API::set_parent_window(handle(), container_->handle()); this->move({ 1, 1 }); - container_->events().resized([this](const arg_resized& arg) + container_->events().resized.connect([this](const arg_resized& arg) { this->size({arg.width - 2, arg.height - 2}); }); @@ -350,7 +347,7 @@ namespace nana tabbar_.reset(new tabbar_lite(*this)); tabbar_->events().selected.clear(); - tabbar_->events().selected([this] + tabbar_->events().selected.connect([this](const event_arg&) { auto handle = tabbar_->attach(tabbar_->selected()); //Set caption through a caption of window specified by handle diff --git a/source/gui/tooltip.cpp b/source/gui/tooltip.cpp index 433c247b..e4a03634 100644 --- a/source/gui/tooltip.cpp +++ b/source/gui/tooltip.cpp @@ -282,17 +282,22 @@ namespace nana } auto & events = API::events(wd); - events.mouse_enter.connect([this](const arg_mouse& arg){ - auto & pr = _m_get(arg.window_handle); - if (pr.second.size()) - this->show(pr.second); - }); - auto leave_fn = [this]{ - this->close(); + auto mouse_fn = [this](const arg_mouse& arg) + { + if (event_code::mouse_enter == arg.evt_code) + { + auto & pr = _m_get(arg.window_handle); + if (pr.second.size()) + this->show(pr.second); + } + else + this->close(); }; - events.mouse_leave.connect(leave_fn); - events.mouse_down.connect(leave_fn); + + events.mouse_enter.connect(mouse_fn); + events.mouse_leave.connect(mouse_fn); + events.mouse_down.connect(mouse_fn); events.destroy.connect([this](const arg_destroy& arg){ _m_untip(arg.window_handle); diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index c7f76244..2ba13a4d 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -1237,14 +1237,14 @@ namespace nana return impl_->mbuilder.data().items.at(index).flags.checked; } - void menu::answerer(std::size_t index, const menu::event_fn_t& fn) + void menu::answerer(std::size_t index, const event_fn_t& fn) { impl_->mbuilder.data().items.at(index).functor = fn; } - void menu::destroy_answer(const std::function& f) + void menu::destroy_answer(const std::function& fn) { - impl_->destroy_answer = f; + impl_->destroy_answer = fn; } void menu::gaps(const nana::point& pos) diff --git a/source/gui/widgets/menubar.cpp b/source/gui/widgets/menubar.cpp index 65a08292..10bf8814 100644 --- a/source/gui/widgets/menubar.cpp +++ b/source/gui/widgets/menubar.cpp @@ -610,7 +610,7 @@ namespace nana ::create(wd, rectangle(nana::size(API::window_size(wd).width, 28))); API::dev::set_menubar(handle(), true); - evt_resized_ = API::events(wd).resized([this](const ::nana::arg_resized& arg) + evt_resized_ = API::events(wd).resized.connect([this](const ::nana::arg_resized& arg) { auto sz = this->size(); sz.width = arg.width; diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index a63d832f..94e0f3f8 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -332,18 +332,18 @@ namespace nana{ namespace widgets nana::point caret_to_screen(nana::upoint pos) override { - auto & textbase = editor_.textbase_; - if (pos.y > static_cast(textbase.lines())) - pos.y = static_cast(textbase.lines()); + pos.y = (std::min)(pos.y, static_cast(editor_.textbase_.lines())); - std::unique_ptr mask_str; + auto text_ptr = &editor_.textbase_.getline(pos.y); + + std::wstring mask_str; if (editor_.mask_char_) - mask_str.reset(new std::wstring(textbase.getline(pos.y).size(), editor_.mask_char_)); + { + mask_str.resize(text_ptr->size(), editor_.mask_char_); + text_ptr = &mask_str; + } - auto & lnstr = editor_.mask_char_ ? *mask_str : textbase.getline(pos.y); - - pos.x = editor_._m_pixels_by_char(lnstr, pos.x) + editor_.text_area_.area.x; - + pos.x = editor_._m_pixels_by_char(*text_ptr, pos.x) + editor_.text_area_.area.x; int pos_y = static_cast((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base()); return{ static_cast(pos.x - editor_.points_.offset.x), pos_y }; @@ -354,21 +354,23 @@ namespace nana{ namespace widgets nana::upoint res{ 0, static_cast(_m_textline_from_screen(scrpos.y)) }; //Convert the screen point to text caret point - const string_type& real_str = editor_.textbase_.getline(res.y); - std::unique_ptr mask_str; + auto text_ptr = &editor_.textbase_.getline(res.y); + + std::wstring mask_str; if (editor_.mask_char_) - mask_str.reset(new std::wstring(real_str.size(), editor_.mask_char_)); - - auto & lnstr = (editor_.mask_char_ ? *mask_str : real_str); - if (lnstr.size() > 0) + { + mask_str.resize(text_ptr->size(), editor_.mask_char_); + text_ptr = &mask_str; + } + + if (text_ptr->size() > 0) { scrpos.x += (editor_.points_.offset.x - editor_.text_area_.area.x); if (scrpos.x > 0) { - unicode_bidi bidi; std::vector reordered; - bidi.linestr(lnstr.data(), lnstr.size(), reordered); + unicode_bidi{}.linestr(text_ptr->c_str(), text_ptr->size(), reordered); for (auto & ent : reordered) { @@ -377,13 +379,13 @@ namespace nana{ namespace widgets if (scrpos.x < str_px) { res.x = editor_._m_char_by_pixels(ent, static_cast(scrpos.x)); - res.x += static_cast(ent.begin - lnstr.data()); + res.x += static_cast(ent.begin - text_ptr->c_str()); return res; } scrpos.x -= str_px; } - res.x = static_cast(lnstr.size()); + res.x = static_cast(text_ptr->size()); } } @@ -398,10 +400,9 @@ namespace nana{ namespace widgets { if (points.caret.y) { - points.caret.x = static_cast(editor_.textbase_.getline(--points.caret.y).size()); - - if (points.xpos < points.caret.x) - points.caret.x = points.xpos; + points.caret.x = (std::min)(points.xpos, + static_cast(editor_.textbase_.getline(--points.caret.y).size()) + ); bool out_of_screen = (static_cast(points.caret.y) < points.offset.y); if (out_of_screen) @@ -414,10 +415,9 @@ namespace nana{ namespace widgets { if (points.caret.y + 1 < editor_.textbase_.lines()) { - points.caret.x = static_cast(editor_.textbase_.getline(++points.caret.y).size()); - - if (points.xpos < points.caret.x) - points.caret.x = points.xpos; + points.caret.x = (std::min)(points.xpos, + static_cast(editor_.textbase_.getline(++points.caret.y).size()) + ); return adjust_caret_into_screen(); } @@ -511,8 +511,8 @@ namespace nana{ namespace widgets const wchar_t* end; unsigned pixels; - text_section(const wchar_t* ptr, const wchar_t* endptr) - : begin(ptr), end(endptr) + text_section(const wchar_t* ptr, const wchar_t* endptr, unsigned px) + : begin(ptr), end(endptr), pixels(px) {} }; @@ -543,7 +543,7 @@ namespace nana{ namespace widgets { auto& linestr = editor_.textbase_.getline(line); auto p = mtr.line_sections.front().begin; - if (p < linestr.data() || (linestr.data() + linestr.size() < p)) + if (p < linestr.c_str() || (linestr.c_str() + linestr.size() < p)) pre_calc_line(line, editor_.width_pixels()); ++line; @@ -566,7 +566,7 @@ namespace nana{ namespace widgets { auto & linestr = editor_.textbase_.getline(line); auto p = mtr.line_sections.front().begin; - if (p < linestr.data() || (linestr.data() + linestr.size() < p)) + if (p < linestr.c_str() || (linestr.c_str() + linestr.size() < p)) pre_calc_line(line, editor_.width_pixels()); } ++line; @@ -581,8 +581,8 @@ namespace nana{ namespace widgets { auto & mtr = linemtr_[line]; mtr.line_sections.clear(); - mtr.line_sections.emplace_back(lnstr.data(), lnstr.data()); - mtr.line_sections.back().pixels = 0; + + mtr.line_sections.emplace_back(lnstr.c_str(), lnstr.c_str(), unsigned{}); mtr.take_lines = 1; return; } @@ -606,8 +606,7 @@ namespace nana{ namespace widgets { if (text_px != str_w) { - line_sections.emplace_back(secondary_begin, ts.begin); - line_sections.back().pixels = text_px - str_w; + line_sections.emplace_back(secondary_begin, ts.begin, unsigned{ text_px - str_w }); text_px = str_w; secondary_begin = ts.begin; } @@ -630,8 +629,7 @@ namespace nana{ namespace widgets continue; const wchar_t * endptr = ts.begin + (pxi - pxptr) + (text_px == pixels ? 1 : 0); - line_sections.emplace_back(secondary_begin, endptr); - line_sections.back().pixels = text_px - (text_px == pixels ? 0 : *pxi); + line_sections.emplace_back(secondary_begin, endptr, unsigned{ text_px - (text_px == pixels ? 0 : *pxi) }); secondary_begin = endptr; text_px = (text_px == pixels ? 0 : *pxi); @@ -641,8 +639,7 @@ namespace nana{ namespace widgets } else if (text_px == pixels) { - line_sections.emplace_back(secondary_begin, ts.begin); - line_sections.back().pixels = text_px - str_w; + line_sections.emplace_back(secondary_begin, ts.begin, unsigned{ text_px - str_w }); secondary_begin = ts.begin; text_px = str_w; } @@ -655,8 +652,7 @@ namespace nana{ namespace widgets if (secondary_begin) { - mtr.line_sections.emplace_back(secondary_begin, sections.back().end); - mtr.line_sections.back().pixels = text_px; + mtr.line_sections.emplace_back(secondary_begin, sections.back().end, unsigned{ text_px }); ++mtr.take_lines; } } @@ -694,7 +690,7 @@ namespace nana{ namespace widgets editor_.graph_.rectangle({ editor_.text_area_.area.x, top, editor_.width_pixels(), static_cast(pixels * secondary_before) }, true, API::bgcolor(editor_.window_)); auto fgcolor = API::fgcolor(editor_.window_); - auto text_ptr = editor_.textbase_.getline(textline).data(); + auto text_ptr = editor_.textbase_.getline(textline).c_str(); for (std::size_t pos = 0; pos < secondary_before; ++pos, top+=pixels) { @@ -716,7 +712,7 @@ namespace nana{ namespace widgets return line_index; nana::upoint str_pos(0, static_cast(primary)); - str_pos.x = static_cast(linemtr_[primary].line_sections[secondary].begin - editor_.textbase_.getline(primary).data()); + str_pos.x = static_cast(linemtr_[primary].line_sections[secondary].begin - editor_.textbase_.getline(primary).c_str()); int top = editor_._m_text_top_base(); const unsigned pixels = editor_.line_height(); @@ -786,7 +782,7 @@ namespace nana{ namespace widgets } else if (pos.x == chsize) { - scrpos.x = editor_._m_text_extent_size(str.data(), sec.end - sec.begin).width; + scrpos.x = editor_._m_text_extent_size(str.c_str(), sec.end - sec.begin).width; break; } else @@ -814,15 +810,18 @@ namespace nana{ namespace widgets //First of all, find the text of secondary. auto real_str = mtr.line_sections[secondary]; - std::unique_ptr mask_str; - if (editor_.mask_char_) - mask_str.reset(new std::wstring(real_str.end - real_str.begin, editor_.mask_char_)); + auto text_ptr = real_str.begin; + const auto text_size = real_str.end - real_str.begin; - const wchar_t * str = (editor_.mask_char_ ? mask_str->data() : real_str.begin); + std::wstring mask_str; + if (editor_.mask_char_) + { + mask_str.resize(text_size, editor_.mask_char_); + text_ptr = mask_str.c_str(); + } std::vector reordered; - unicode_bidi bidi; - bidi.linestr(str, real_str.end - real_str.begin, reordered); + unicode_bidi{}.linestr(text_ptr, text_size, reordered); nana::upoint res(static_cast(real_str.begin - mtr.line_sections.front().begin), static_cast(primary)); scrpos.x -= editor_.text_area_.area.x; @@ -831,12 +830,11 @@ namespace nana{ namespace widgets for (auto & ent : reordered) { - std::size_t len = ent.end - ent.begin; - auto str_px = static_cast(editor_._m_text_extent_size(ent.begin, len).width); + auto str_px = static_cast(editor_._m_text_extent_size(ent.begin, ent.end - ent.begin).width); if (scrpos.x < str_px) { res.x += editor_._m_char_by_pixels(ent, scrpos.x); - res.x += static_cast(ent.begin - str); + res.x += static_cast(ent.begin - text_ptr); return res; } scrpos.x -= str_px; @@ -929,13 +927,13 @@ namespace nana{ namespace widgets { if (str.empty()) { - tsec.emplace_back(str.data(), str.data()); + tsec.emplace_back(str.c_str(), str.c_str(), unsigned{}); return; } - const auto end = str.data() + str.size(); + const auto end = str.c_str() + str.size(); const wchar_t * word = nullptr; - for (auto i = str.data(); i != end; ++i) + for (auto i = str.c_str(); i != end; ++i) { wchar_t const ch = *i; @@ -944,11 +942,11 @@ namespace nana{ namespace widgets { if (word) //Record the word. { - tsec.emplace_back(word, i); + tsec.emplace_back(word, i, unsigned{}); word = nullptr; } - tsec.emplace_back(i, i + 1); + tsec.emplace_back(i, i + 1, unsigned{}); continue; } @@ -957,7 +955,7 @@ namespace nana{ namespace widgets } if(word) - tsec.emplace_back(word, end); + tsec.emplace_back(word, end, unsigned{}); } void _m_set_offset_by_secondary(std::size_t primary, std::size_t secondary) @@ -1054,7 +1052,7 @@ namespace nana{ namespace widgets unsigned len = static_cast(section.end - section.begin); auto chptr = section.begin + (secondary.x > len ? len : secondary.x); - pos = static_cast(chptr - editor_.textbase_.getline(textline).data()); + pos = static_cast(chptr - editor_.textbase_.getline(textline).c_str()); return true; } @@ -1179,25 +1177,6 @@ namespace nana{ namespace widgets std::vector entities; - auto test_whole_word = [&text](index pos, index len) - { - if (pos) - { - auto chr = text[pos - 1]; - if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_') - return false; - } - - if (pos + len < text.size()) - { - auto chr = text[pos + len]; - if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_') - return false; - } - - return true; - }; - ::nana::ciwstring cistr; for (auto & ds : kwptr->kwbase) { @@ -1212,22 +1191,22 @@ namespace nana{ namespace widgets if (ds.whole_word_matched) { - if (!test_whole_word(pos, ds.text.size())) + if (!_m_whole_word(text, pos, ds.text.size())) continue; } } else { if (cistr.empty()) - cistr.append(text.data(), text.size()); + cistr.append(text.c_str(), text.size()); - pos = cistr.find(ds.text.data(), pos); + pos = cistr.find(ds.text.c_str(), pos); if (pos == cistr.npos) break; if (ds.whole_word_matched) { - if (!test_whole_word(pos, ds.text.size())) + if (!_m_whole_word(text, pos, ds.text.size())) continue; } } @@ -1237,7 +1216,7 @@ namespace nana{ namespace widgets { entities.emplace_back(); auto & last = entities.back(); - last.begin = text.data() + pos; + last.begin = text.c_str() + pos; last.end = last.begin + ds.text.size(); last.scheme = ki->second.get(); } @@ -1270,6 +1249,25 @@ namespace nana{ namespace widgets { return entities_; } + private: + static bool _m_whole_word(const std::wstring& text, std::wstring::size_type pos, std::size_t len) + { + if (pos) + { + auto chr = text[pos - 1]; + if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_') + return false; + } + + if (pos + len < text.size()) + { + auto chr = text[pos + len]; + if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_') + return false; + } + + return true; + } private: std::vector entities_; }; @@ -1343,6 +1341,7 @@ namespace nana{ namespace widgets return; } } + keywords_->kwbase.emplace_back(kw, name, case_sensitive, whole_word_matched); } @@ -1448,7 +1447,7 @@ namespace nana{ namespace widgets void text_editor::indent(bool enb, std::function generator) { indent_.enabled = enb; - indent_.generator.swap(generator); + indent_.generator = std::move(generator); } void text_editor::set_event(event_interface* ptr) @@ -2030,7 +2029,7 @@ namespace nana{ namespace widgets { if(text_area_.vscroll && text_area_.hscroll) { - graph_.rectangle({ text_area_.area.right() - static_cast(text_area_.vscroll), text_area_.area.bottom() - static_cast(text_area_.hscroll), text_area_.vscroll, text_area_.hscroll }, + graph_.rectangle(rectangle{ text_area_.area.right() - static_cast(text_area_.vscroll), text_area_.area.bottom() - static_cast(text_area_.hscroll), text_area_.vscroll, text_area_.hscroll }, true, colors::button_face); } } @@ -2054,17 +2053,16 @@ namespace nana{ namespace widgets ext_renderer_.background(graph_, text_area_.area, bgcolor); if(attributes_.counterpart && !text_area_.area.empty()) - attributes_.counterpart.bitblt(nana::rectangle(0, 0, text_area_.area.width, text_area_.area.height), graph_, nana::point(text_area_.area.x, text_area_.area.y)); + attributes_.counterpart.bitblt(rectangle{ text_area_.area.dimension() }, graph_, text_area_.area.position()); //Render the content when the text isn't empty or the window has got focus, //otherwise draw the tip string. if ((false == textbase_.empty()) || has_focus) { - auto && text_pos = behavior_->render(fgcolor); + auto text_pos = behavior_->render(fgcolor); - if (text_pos.empty()) - text_pos.push_back({ 0, 0 }); + text_pos.push_back(upoint{}); if (text_pos != text_position_) { @@ -2077,7 +2075,7 @@ namespace nana{ namespace widgets graph_.string({ text_area_.area.x - points_.offset.x, text_area_.area.y }, attributes_.tip_string, static_cast(0x787878)); if (text_position_.empty()) - text_position_.push_back({ 0, 0 }); + text_position_.push_back(upoint{}); draw_corner(); @@ -2086,6 +2084,9 @@ namespace nana{ namespace widgets //public: void text_editor::put(std::wstring text) { + if (text.empty()) + return; + auto undo_ptr = std::unique_ptr{ new undo_input_text(*this, text) }; undo_ptr->set_selected_text(); @@ -2222,27 +2223,21 @@ namespace nana{ namespace widgets if (indent_.enabled) { - std::wstring indent_text; if (indent_.generator) { - indent_text = to_wstring(indent_.generator()); + put(to_wstring(indent_.generator())); } else { auto & text = textbase_.getline(points_.caret.y - 1); auto indent_pos = text.find_first_not_of(L"\t "); if (indent_pos != std::wstring::npos) - indent_text = text.substr(0, indent_pos); + put(text.substr(0, indent_pos)); else - indent_text = text; + put(text); } - - if (indent_text.size()) - put(indent_text); - } - if (behavior_->adjust_caret_into_screen() || need_refresh) render(true); @@ -2906,7 +2901,7 @@ namespace nana{ namespace widgets bool text_editor::_m_resolve_text(const std::wstring& text, std::vector> & lines) { - auto const text_str = text.data(); + auto const text_str = text.c_str(); std::size_t begin = 0; while (true) { @@ -2932,14 +2927,14 @@ namespace nana{ namespace widgets auto eats = eat_endl(chp, 0); if (eats) { - lines.emplace_back(0, 0); + lines.emplace_back(); chp += (eats - 1); } } if (text.npos == begin) { - lines.emplace_back(0, 0); + lines.emplace_back(); break; } } @@ -3130,7 +3125,7 @@ namespace nana{ namespace widgets if (str <= ent.begin && ent.begin < str_end) { ent_begin = ent.begin; - ent_off = std::accumulate(glyphs, glyphs + (ent.begin - str), 0); + ent_off = static_cast(std::accumulate(glyphs, glyphs + (ent.begin - str), unsigned{})); } else if (ent.begin <= str && str < ent.end) ent_begin = str; @@ -3146,16 +3141,17 @@ namespace nana{ namespace widgets canvas.rectangle(true); ent_pos.x += ent_off; + if (rtl) { //draw the whole text if it is a RTL text, because Arbic language is transformable. canvas.string({}, str, len); - graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 }); + graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas, point{ ent_off, 0 }); } else { canvas.string({}, ent_begin, ent_end - ent_begin); - graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas); + graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas); } } } @@ -3163,24 +3159,26 @@ namespace nana{ namespace widgets void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const std::wstring& str, bool if_mask) const { - ::nana::point text_pos{ text_area_.area.x - points_.offset.x, top }; + point text_pos{ text_area_.area.x - points_.offset.x, top }; const int text_right = text_area_.area.right(); - std::unique_ptr mask_str; + auto text_ptr = &str; + + std::wstring mask_str; if (if_mask && mask_char_) - mask_str.reset(new std::wstring(str.size(), mask_char_)); + { + mask_str.resize(str.size(), mask_char_); + text_ptr = &mask_str; + } - bool focused = API::is_focus_ready(window_); + const auto focused = API::is_focus_ready(window_); - auto & linestr = (if_mask && mask_char_ ? *mask_str : str); - - unicode_bidi bidi; std::vector reordered; - bidi.linestr(linestr.c_str(), linestr.size(), reordered); + unicode_bidi{}.linestr(text_ptr->c_str(), text_ptr->size(), reordered); //Parse highlight keywords keyword_parser parser; - parser.parse(linestr, keywords_.get()); + parser.parse(*text_ptr, keywords_.get()); auto whitespace_w = graph_.text_extent_size(L" ", 1).width; @@ -3233,7 +3231,7 @@ namespace nana{ namespace widgets graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_h_pixels), graph); }; - const wchar_t * strbeg = linestr.c_str(); + auto const strbeg = text_ptr->c_str(); if (a.y == b.y) { for (auto & ent : reordered) @@ -3242,7 +3240,7 @@ namespace nana{ namespace widgets unsigned str_w = graph_.text_extent_size(ent.begin, len).width; if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < text_right)) { - std::size_t pos = ent.begin - strbeg + str_pos.x; + auto const pos = ent.begin - strbeg + str_pos.x; const auto str_end = pos + len; //NOT selected or seleceted all @@ -3460,7 +3458,7 @@ namespace nana{ namespace widgets if (is_right_text(ent)) { - auto total_px = std::accumulate(pxbuf.get(), px_end, static_cast(0)); + auto total_px = std::accumulate(pxbuf.get(), px_end, unsigned{}); for (auto p = pxbuf.get(); p != px_end; ++p) { @@ -3499,17 +3497,16 @@ namespace nana{ namespace widgets if (pos > lnstr.size()) return 0; - unicode_bidi bidi; std::vector reordered; - bidi.linestr(lnstr.data(), lnstr.size(), reordered); + unicode_bidi{}.linestr(lnstr.c_str(), lnstr.size(), reordered); - auto ch = lnstr.data() + pos; + auto target = lnstr.c_str() + pos; unsigned text_w = 0; for (auto & ent : reordered) { std::size_t len = ent.end - ent.begin; - if (ent.begin <= ch && ch <= ent.end) + if (ent.begin <= target && target <= ent.end) { if (is_right_text(ent)) { @@ -3517,10 +3514,10 @@ namespace nana{ namespace widgets //RTL std::unique_ptr pxbuf(new unsigned[len]); graph_.glyph_pixels(ent.begin, len, pxbuf.get()); - return std::accumulate(pxbuf.get() + (ch - ent.begin), pxbuf.get() + len, text_w); + return std::accumulate(pxbuf.get() + (target - ent.begin), pxbuf.get() + len, text_w); } //LTR - return text_w + _m_text_extent_size(ent.begin, ch - ent.begin).width; + return text_w + _m_text_extent_size(ent.begin, target - ent.begin).width; } else text_w += _m_text_extent_size(ent.begin, len).width; diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index a4105075..961ddefa 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -162,7 +162,7 @@ namespace nana { for (auto & s : initlist) { - texts_.emplace_back(::nana::charset(s, ::nana::unicode::utf8)); + texts_.emplace_back(std::string{ s }); } } diff --git a/source/internationalization.cpp b/source/internationalization.cpp index 8ac35899..02f6c72f 100644 --- a/source/internationalization.cpp +++ b/source/internationalization.cpp @@ -271,7 +271,7 @@ namespace nana if (i == mgr.table.end()) { auto result = mgr.table.emplace(wd, std::move(eval)); - result.first->second.destroy = nana::API::events(wd).destroy([wd]{ + result.first->second.destroy = nana::API::events(wd).destroy.connect([wd](const arg_destroy&){ auto & eval_mgr = get_eval_manager(); std::lock_guard lockgd(eval_mgr.mutex); From 5340c4f6704efc497db519e97d84123385da44de Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 7 Jul 2016 07:09:40 +0800 Subject: [PATCH 296/309] fix mouse wheel step which is restored by merging listbox-model --- source/gui/widgets/listbox.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 23e86d7e..54d5439d 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2556,10 +2556,13 @@ namespace nana return false; index_pair target; - if(upwards == false) - lister.forward(scroll.offset_y_dpl, 1, target); + if (upwards == false) + { + if (!lister.forward(scroll.offset_y_dpl, this->scheme_ptr->mouse_wheel.lines, target)) + return false; + } else - lister.backward(scroll.offset_y_dpl, 1, target); + lister.backward(scroll.offset_y_dpl, this->scheme_ptr->mouse_wheel.lines, target); if (target == scroll.offset_y_dpl) return false; From 8489e16d726f1f465a0e57521398cd047bfe300c Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 11 Jul 2016 04:12:04 +0800 Subject: [PATCH 297/309] make listbox::index_pair constructor explicit --- include/nana/gui/widgets/listbox.hpp | 4 ++-- source/gui/widgets/listbox.cpp | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 05c7d109..24c06125 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -633,7 +633,7 @@ namespace nana size_type cat; //The pos of category size_type item; //the pos of item in a category. - index_pair(size_type cat_pos = 0, size_type item_pos = 0) + explicit index_pair(size_type cat_pos = 0, size_type item_pos = 0) : cat(cat_pos), item(item_pos) {} @@ -1383,7 +1383,7 @@ the nana::detail::basic_window member pointer scheme * @param abs_pos The absolute position before which an item will be inserted. * @param text Text of the first column. */ - void insert_item(const index_pair& abs_pos, ::std::wstring text); + void insert_item(const index_pair& abs_pos, const ::std::wstring& text); /// Returns an index of item which contains the specified point. index_pair cast(const point & pos) const; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 54d5439d..21f288a7 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1578,7 +1578,7 @@ namespace nana } ++id.cat; } - return {npos,npos}; + return index_pair{npos,npos}; } /// return absolute positions, no relative to display @@ -1867,7 +1867,7 @@ namespace nana /// absolute position of the last displayed item index_pair last_displ() const { - return absolute ( last() ); + return index_pair{ absolute(last()) }; } /// can be used as the absolute position of the first absolute item, or as the display pos of the first displayed item @@ -1880,7 +1880,7 @@ namespace nana /// absolute position of the first displayed item index_pair first_displ() const { - return absolute ( first() ); + return index_pair{ absolute(first()) }; } bool good(size_type cat) const @@ -1938,7 +1938,7 @@ namespace nana { //Returns an empty pos if item pos npos auto item_pos = absolute(display_pos); - return {item_pos != npos ? display_pos.cat : npos, item_pos}; + return index_pair{item_pos != npos ? display_pos.cat : npos, item_pos}; } ///Translate absolute position (original data order) into relative position (position in display) @@ -1962,7 +1962,7 @@ namespace nana { //Returns an empty pos if item is npos auto item_pos = relative(pos); - return {(item_pos != npos ? pos.cat : npos), item_pos}; + return index_pair{(item_pos != npos ? pos.cat : npos), item_pos}; } /// all arg are relative to display order, or all are absolute, but not mixed @@ -2301,12 +2301,12 @@ namespace nana const auto items = lister.the_number_of_expanded(); const auto disp_items = number_of_lister_items(false); - size_type off = lister.distance({ 0, 0 }, scroll.offset_y_dpl); + size_type off = lister.distance(index_pair{ 0, 0 }, scroll.offset_y_dpl); if (items < disp_items + off) { index_pair pos; - if (lister.forward({ 0, 0 }, items - disp_items, pos)) + if (lister.forward(index_pair{ 0, 0 }, items - disp_items, pos)) { off = items - disp_items; set_scroll_y_dpl(pos); @@ -2406,7 +2406,7 @@ namespace nana else if(!scroll.v.empty()) { scroll.v.close(); - set_scroll_y_dpl({0,0}); + set_scroll_y_dpl(index_pair{0,0}); } adjust_scroll_value(); } @@ -4206,7 +4206,7 @@ namespace nana { if(essence_->lister.sort_index(essence_->pointer_where.second)) { - essence_->trace_item_dpl({0,0}); + essence_->trace_item_dpl(index_pair{0,0}); refresh(graph); API::dev::lazy_refresh(); } @@ -4780,8 +4780,7 @@ namespace nana { internal_scope_guard lock; - ess_->lister.throw_if_immutable_model(pos_); - + ess_->lister.throw_if_immutable_model(index_pair{ pos_ }); cat_->sorted.push_back(cat_->items.size()); @@ -5233,7 +5232,7 @@ namespace nana } } - void listbox::insert_item(const index_pair& pos, std::wstring text) + void listbox::insert_item(const index_pair& pos, const std::wstring& text) { insert_item(pos, to_utf8(text)); } From 5d5a808b2d4de634ca0a9c50f2b9a3dc1250822f Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 13 Jul 2016 08:00:59 +0800 Subject: [PATCH 298/309] remove overloading assignment operator of rectangle --- include/nana/basic_types.hpp | 3 - source/basic_types.cpp | 14 --- source/gui/detail/basic_window.cpp | 2 +- source/gui/layout_utility.cpp | 2 +- source/gui/place.cpp | 6 +- source/gui/programming_interface.cpp | 2 +- source/gui/widgets/listbox.cpp | 98 ++++++++++++-------- source/gui/widgets/picture.cpp | 2 +- source/gui/widgets/skeletons/text_editor.cpp | 2 +- source/gui/widgets/treebox.cpp | 4 +- 10 files changed, 71 insertions(+), 64 deletions(-) diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index adbf55da..6ddb6912 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -449,9 +449,6 @@ namespace nana bool operator==(const rectangle& rhs) const; bool operator!=(const rectangle& rhs) const; - rectangle& operator=(const point&); - rectangle& operator=(const size&); - point position() const noexcept; rectangle& position(const point&) noexcept; diff --git a/source/basic_types.cpp b/source/basic_types.cpp index b5f7716b..6a40ee59 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -607,20 +607,6 @@ namespace nana return (width != rhs.width) || (height != rhs.height) || (x != rhs.x) || (y != rhs.y); } - rectangle & rectangle::operator=(const point& pos) - { - x = pos.x; - y = pos.y; - return *this; - } - - rectangle & rectangle::operator=(const size & sz) - { - width = sz.width; - height = sz.height; - return *this; - } - point rectangle::position() const noexcept { return{ x, y }; diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index faf0b553..525f5e57 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -61,7 +61,7 @@ namespace nana if (0 == effect_range_.width || 0 == effect_range_.height) { rect.x = rect.y = 0; - rect = owner_->dimension; + rect.dimension(owner_->dimension); } else { diff --git a/source/gui/layout_utility.cpp b/source/gui/layout_utility.cpp index 3afc6e62..4daade4a 100644 --- a/source/gui/layout_utility.cpp +++ b/source/gui/layout_utility.cpp @@ -56,7 +56,7 @@ namespace nana if (overlap(ir, valid_r, op_ir) == false) return false; - valid_r = valid_dst_area; + valid_r.dimension(valid_dst_area); rectangle good_dr; if (overlap(dr, valid_r, good_dr) == false) return false; diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 4b9e135b..bfa0e658 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -1684,7 +1684,7 @@ namespace nana graph.blend(r, clr, 0.5); r.x = r.y = 0; - r = graph.size(); + r.dimension(graph.size()); r.width = border_px; graph.blend(r, clr, 0.5); r.x = right - border_px; @@ -2099,7 +2099,7 @@ namespace nana { if (root_division && window_handle) { - root_division->field_area = API::window_size(window_handle); + root_division->field_area.dimension(API::window_size(window_handle)); if (root_division->field_area.empty()) return; @@ -2590,7 +2590,7 @@ namespace nana { if (impl_->root_division) { - impl_->root_division->field_area = ::nana::size(arg.width, arg.height); + impl_->root_division->field_area.dimension({ arg.width, arg.height }); impl_->root_division->collocate(arg.window_handle); } }); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 4485b260..787a2183 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -474,7 +474,7 @@ namespace API nana::point pos{ r.x, r.y }; calc_window_point(wd, pos); - r = pos; + r.position(pos); return r; } diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 21f288a7..a9b510b9 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -565,7 +565,7 @@ namespace nana { using container = std::vector; - container cells; + std::unique_ptr cells; nana::color bgcolor; nana::color fgcolor; paint::image img; @@ -585,7 +585,7 @@ namespace nana } item_data(const item_data& r) - : cells(r.cells), + : cells(r.cells ? std::make_unique(*r.cells) : nullptr), bgcolor(r.bgcolor), fgcolor(r.fgcolor), img(r.img), @@ -594,30 +594,34 @@ namespace nana {} item_data(container&& cont) - : cells(std::move(cont)) + : cells(std::make_unique(std::move(cont))) { flags.selected = flags.checked = false; } item_data(std::string&& s) + : cells(std::make_unique()) { flags.selected = flags.checked = false; - cells.emplace_back(std::move(s)); + cells->emplace_back(std::move(s)); } - item_data(std::string&& s, const nana::color& bg, const nana::color& fg) - : bgcolor(bg), - fgcolor(fg) + item_data(std::string&& s, const nana::color& bg, const nana::color& fg): + cells(std::make_unique()), + bgcolor(bg), + fgcolor(fg) { flags.selected = flags.checked = false; - cells.emplace_back(std::move(s)); + cells->emplace_back(std::move(s)); } item_data& operator=(const item_data& r) { if (this != &r) { - cells = r.cells; + if (r.cells) + cells = std::make_unique(*r.cells); + flags = r.flags; anyobj.reset(r.anyobj ? new nana::any(*r.anyobj) : nullptr); bgcolor = r.bgcolor; @@ -644,7 +648,7 @@ namespace nana if (model_cells) item_str += model_cells->operator[](col).text; else - item_str += cells[col].text; + item_str += (*cells)[col].text; } return item_str; @@ -790,20 +794,20 @@ namespace nana auto & mx = cat.items[x]; auto & my = cat.items[y]; - if (mx.cells.size() <= sorted_index_ || my.cells.size() <= sorted_index_) + if (mx.cells->size() <= sorted_index_ || my.cells->size() <= sorted_index_) { std::string a; - if (mx.cells.size() > sorted_index_) - a = mx.cells[sorted_index_].text; + if (mx.cells->size() > sorted_index_) + a = (*mx.cells)[sorted_index_].text; std::string b; - if (my.cells.size() > sorted_index_) - b = my.cells[sorted_index_].text; + if (my.cells->size() > sorted_index_) + b = (*my.cells)[sorted_index_].text; return weak_ordering_comp(a, mx.anyobj.get(), b, my.anyobj.get(), sorted_reverse_); } - return weak_ordering_comp(mx.cells[sorted_index_].text, mx.anyobj.get(), my.cells[sorted_index_].text, my.anyobj.get(), sorted_reverse_); + return weak_ordering_comp((*mx.cells)[sorted_index_].text, mx.anyobj.get(), (*my.cells)[sorted_index_].text, my.anyobj.get(), sorted_reverse_); }); } } @@ -843,21 +847,21 @@ namespace nana auto & mx = cat.items[x]; auto & my = cat.items[y]; - if (mx.cells.size() <= sorted_index_ || my.cells.size() <= sorted_index_) + if (mx.cells->size() <= sorted_index_ || my.cells->size() <= sorted_index_) { std::string a; - if (mx.cells.size() > sorted_index_) - a = mx.cells[sorted_index_].text; + if (mx.cells->size() > sorted_index_) + a = (*mx.cells)[sorted_index_].text; std::string b; - if (my.cells.size() > sorted_index_) - b = my.cells[sorted_index_].text; + if (my.cells->size() > sorted_index_) + b = (*my.cells)[sorted_index_].text; return (sorted_reverse_ ? a > b : a < b); } - auto & a = mx.cells[sorted_index_].text; - auto & b = my.cells[sorted_index_].text; + auto & a = (*mx.cells)[sorted_index_].text; + auto & b = (*my.cells)[sorted_index_].text; return (sorted_reverse_ ? a > b : a < b); }); } @@ -1010,7 +1014,7 @@ namespace nana catobj.items.emplace_back(std::move(text)); } - catobj.items.back().cells.emplace_back(std::move(text)); + catobj.items.back().cells->emplace_back(std::move(text)); } /// convert from display order to absolute (find the real item in that display pos) but without check from current active sorting, in fact using just the last sorting !!! @@ -1268,7 +1272,7 @@ namespace nana if (cat->model_ptr) throw std::runtime_error("nana::listbox disallow to get item cells, because there are model cells"); - return cat->items.at(pos).cells; + return *(cat->items.at(pos).cells); } std::vector get_model_cells(category_t* cat, std::size_t pos) const @@ -1295,7 +1299,7 @@ namespace nana model_cells = cat->model_ptr->container()->to_cells(pos); } - auto & cells = (cat->model_ptr ? model_cells : cat->items[pos].cells); + auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells)); if (col < cells.size()) { @@ -1328,7 +1332,7 @@ namespace nana model_cells = cat->model_ptr->container()->to_cells(pos); } - auto & cells = (cat->model_ptr ? model_cells : cat->items[pos].cells); + auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells)); if (col < cells.size()) { @@ -1934,6 +1938,7 @@ namespace nana return (display_pos.item < catobj.sorted.size() ? catobj.sorted[display_pos.item] : npos); } + index_pair absolute_pair(const index_pair& display_pos) const { //Returns an empty pos if item pos npos @@ -2499,7 +2504,7 @@ namespace nana { if (lister.wd_ptr()->borderless()) { - r = graph->size(); + r.dimension(graph->size()); r.height = scheme_ptr->header_height; return !r.empty(); } @@ -2870,14 +2875,30 @@ namespace nana unsigned max_px = 0; for (auto & cat : categories_) { - for (auto & m : cat.items) + if (cat.model_ptr) { - if (pos >= m.cells.size()) - continue; + for (std::size_t i = 0; i < cat.items.size(); ++i) + { + auto model_cells = cat.model_ptr->container()->to_cells(i); + if (pos >= model_cells.size()) + continue; - auto content_px = ess_->graph->text_extent_size(m.cells[pos].text).width; - if (content_px > max_px) - max_px = content_px; + auto content_px = ess_->graph->text_extent_size(model_cells[pos].text).width; + if (content_px > max_px) + max_px = content_px; + } + } + else + { + for (auto & m : cat.items) + { + if (pos >= m.cells->size()) + continue; + + auto content_px = ess_->graph->text_extent_size((*m.cells)[pos].text).width; + if (content_px > max_px) + max_px = content_px; + } } } return max_px; @@ -2965,7 +2986,7 @@ namespace nana ess_->lister.throw_if_immutable_model(pos); auto model_cells = ess_->lister.at_model_abs(pos); - auto & cells = ess_->lister.have_model(pos) ? model_cells : ess_->lister.at_abs(pos).cells; + auto & cells = ess_->lister.have_model(pos) ? model_cells : (*ess_->lister.at_abs(pos).cells); if (cells.size() <= column_pos_) cells.resize(column_pos_ + 1); @@ -3696,7 +3717,7 @@ namespace nana model_cells = cat.model_ptr->container()->to_cells(item_pos.item); } - auto & cells = (cat.model_ptr ? model_cells : item.cells); + auto & cells = (cat.model_ptr ? model_cells : *item.cells); if (item.flags.selected) // fetch the "def" colors bgcolor = essence_->scheme_ptr->item_selected; @@ -5050,7 +5071,10 @@ namespace nana cat_->sorted.clear(); cat_->items.resize(cat_->model_ptr->container()->size()); - for (std::size_t pos = 0; pos < cat_->items.size(); ++pos) + + const auto item_size = cat_->items.size(); + cat_->sorted.reserve(item_size + 100); + for (std::size_t pos = 0; pos != item_size; ++pos) cat_->sorted.push_back(pos); ess_->lister.sort(); diff --git a/source/gui/widgets/picture.cpp b/source/gui/widgets/picture.cpp index 9733e120..bf739693 100644 --- a/source/gui/widgets/picture.cpp +++ b/source/gui/widgets/picture.cpp @@ -76,7 +76,7 @@ namespace nana { auto valid_area = backimg.valid_area; if (valid_area.empty()) - valid_area = backimg.image.size(); + valid_area.dimension(backimg.image.size()); if (backimg.stretchable) { diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 94e0f3f8..09a1c556 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1280,7 +1280,7 @@ namespace nana{ namespace widgets graph_(graph), scheme_(schm), keywords_(new keywords) { - text_area_.area = graph.size(); + text_area_.area.dimension(graph.size()); text_area_.captured = false; text_area_.tab_space = 4; text_area_.scroll_pixels = 16; diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index e319b54f..b0895943 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1274,8 +1274,8 @@ namespace nana attr.area.x += (attr.area.width - fit_size.width) / 2; attr.area.y += (attr.area.height - fit_size.height) / 2; - attr.area = fit_size; - img->stretch(::nana::rectangle{ size }, graph, attr.area); + attr.area.dimension(fit_size); + img->stretch(rectangle{ size }, graph, attr.area); } else img->paste(graph, point{ attr.area.x + static_cast(attr.area.width - size.width) / 2, attr.area.y + static_cast(attr.area.height - size.height) / 2 }); From 02acc4c216d05727422cb4813f0d47b9fc7de9a3 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 13 Jul 2016 08:14:27 +0800 Subject: [PATCH 299/309] listbox code refined --- include/nana/gui/widgets/listbox.hpp | 33 +++-- source/gui/widgets/listbox.cpp | 208 +++++++++++++-------------- 2 files changed, 118 insertions(+), 123 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 24c06125..e4b06724 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -679,15 +679,15 @@ namespace nana using inline_notifier_interface = detail::inline_widget_notifier_interface; - // struct essence_t + // struct essence //@brief: this struct gives many data for listbox, // the state of the struct does not effect on member funcions, therefore all data members are public. - struct essence_t; + struct essence; class oresolver { public: - oresolver(essence_t*); + oresolver(essence*); oresolver& operator<<(bool); oresolver& operator<<(short); oresolver& operator<<(unsigned short); @@ -713,7 +713,7 @@ namespace nana ::nana::listbox& listbox(); private: - essence_t* const ess_; + essence* const ess_; std::vector cells_; }; @@ -755,7 +755,7 @@ namespace nana public: trigger(); ~trigger(); - essence_t& essence() const; + essence& ess() const; private: void _m_draw_border(); private: @@ -773,7 +773,7 @@ namespace nana void key_press(graph_reference, const arg_keyboard&) override; void key_char(graph_reference, const arg_keyboard&) override; private: - essence_t * essence_; + essence * essence_; drawer_header_impl *drawer_header_; drawer_lister_impl *drawer_lister_; };//end class trigger @@ -784,11 +784,11 @@ namespace nana : public std::iterator { public: - item_proxy(essence_t*); - item_proxy(essence_t*, const index_pair&); + item_proxy(essence*); + item_proxy(essence*, const index_pair&); /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() - static item_proxy from_display(essence_t *ess, const index_pair &relative) ; + static item_proxy from_display(essence *, const index_pair &relative) ; item_proxy from_display(const index_pair &relative) const; /// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort() @@ -814,7 +814,7 @@ namespace nana item_proxy& text(size_type col, cell); item_proxy& text(size_type col, std::string); - item_proxy& text(size_type col, std::wstring); + item_proxy& text(size_type col, const std::wstring&); std::string text(size_type col) const; void icon(const nana::paint::image&); @@ -916,13 +916,13 @@ namespace nana bool operator!=(const item_proxy&) const; //Undocumented method - essence_t * _m_ess() const; + essence * _m_ess() const; private: std::vector & _m_cells() const; nana::any * _m_value(bool alloc_if_empty); const nana::any * _m_value() const; private: - essence_t * ess_; + essence * ess_; category_t* cat_{nullptr}; index_pair pos_; //Position of an item, it never represents a category when item proxy is available. @@ -937,8 +937,8 @@ namespace nana template using cell_translator = typename container_translator::cell_translator; cat_proxy() = default; - cat_proxy(essence_t*, size_type pos); - cat_proxy(essence_t*, category_t*); + cat_proxy(essence*, size_type pos); + cat_proxy(essence*, category_t*); /// Append an item at abs end of the category, set_value determines whether assign T object to the value of item. template @@ -1064,7 +1064,7 @@ namespace nana void _m_update(); void _m_reset_model(model_interface*); private: - essence_t* ess_{nullptr}; + essence* ess_{nullptr}; category_t* cat_{nullptr}; size_type pos_{0}; ///< Absolute position, not relative to display, and dont change during sort() }; @@ -1422,14 +1422,13 @@ the nana::detail::basic_window member pointer scheme void move_select(bool upwards); ///, bool create_if_not_exists); void _m_erase_key(nana::detail::key_interface*); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index a9b510b9..f9ddfff5 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -181,7 +181,7 @@ namespace nana return *this; } - column(essence_t* ess, native_string_type&& text, unsigned px, size_type pos) : + column(essence* ess, native_string_type&& text, unsigned px, size_type pos) : text(std::move(text)), width_px(px), index(pos), @@ -189,10 +189,10 @@ namespace nana { } private: - //The definition is provided after essence_t + //The definition is provided after essence void _m_refresh(); private: - essence_t* const ess_; + essence* const ess_; public: //Implementation of column_interface unsigned width() const noexcept override @@ -306,19 +306,7 @@ namespace nana sortable_ = enable; } - std::function fetch_comp(std::size_t pos) const - { - try - { - return at(pos).weak_ordering; - } - catch (...) - { - } - return{}; - } - - size_type create(essence_t* ess, native_string_type&& text, unsigned pixels) + size_type create(essence* ess, native_string_type&& text, unsigned pixels) { cont_.emplace_back(ess, std::move(text), pixels, static_cast(cont_.size())); return cont_.back().index; @@ -559,7 +547,7 @@ namespace nana }; - struct essence_t; + struct essence; struct item_data { @@ -708,7 +696,7 @@ namespace nana categories_.emplace_back(); } - void bind(essence_t* ess, widget& wd) + void bind(essence* ess, widget& wd) { ess_ = ess; widget_ = dynamic_cast(&wd); @@ -741,7 +729,7 @@ namespace nana std::string to_string(const export_options& exp_opt) const; - // Definition is provided after struct essence_t + // Definition is provided after struct essence unsigned column_content_pixels(size_type pos) const; /// each sort() ivalidate any existing reference from display position to absolute item, that is after sort() display offset point to different items @@ -2074,7 +2062,7 @@ namespace nana public: index_pair last_selected_abs, last_selected_dpl; private: - essence_t * ess_{nullptr}; + essence * ess_{nullptr}; nana::listbox * widget_{nullptr}; std::size_t sorted_index_{npos}; ///< The index of the column used to sort bool resort_{true}; @@ -2091,7 +2079,7 @@ namespace nana /// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public. - struct essence_t + struct essence { enum class item_state{normal, highlighted, pressed, grabbed, floated}; enum class parts{unknown = -1, header, lister, checker}; @@ -2143,10 +2131,22 @@ namespace nana std::map>> inline_table, inline_buffered_table; - essence_t() + essence() { pointer_where.first = parts::unknown; - lister.fetch_ordering_comparer = std::bind(&es_header::fetch_comp, &header, std::placeholders::_1); + + lister.fetch_ordering_comparer = [this](std::size_t pos) -> std::function + { + try + { + return header.at(pos).weak_ordering; + } + catch (...) + { + } + + return {}; + }; } std::string to_string(const export_options& exp_opt) const @@ -2627,7 +2627,7 @@ namespace nana }; //definition of iresolver/oresolver - oresolver::oresolver(essence_t* ess) + oresolver::oresolver(essence* ess) : ess_(ess) {} @@ -2950,14 +2950,14 @@ namespace nana : public ::nana::detail::inline_widget_indicator { public: - using parts = essence_t::parts; + using parts = essence::parts; - inline_indicator(essence_t* ess, std::size_t column_pos) + inline_indicator(essence* ess, std::size_t column_pos) : ess_{ ess }, column_pos_{column_pos} { } - void attach(index_type pos, essence_t::inline_pane* pane) + void attach(index_type pos, essence::inline_pane* pane) { for (auto & pn : panes_) { @@ -3031,9 +3031,9 @@ namespace nana } } private: - essence_t * const ess_; + essence * const ess_; const std::size_t column_pos_; - std::vector> panes_; + std::vector> panes_; }; void es_lister::scroll(const index_pair& pos, bool to_bottom) @@ -3238,10 +3238,10 @@ namespace nana { public: using graph_reference = nana::paint::graphics&; - using item_state = essence_t::item_state; - using parts = essence_t::parts; + using item_state = essence::item_state; + using parts = essence::parts; - drawer_header_impl(essence_t* es): essence_(es){} + drawer_header_impl(essence* es): essence_(es){} size_type splitter() const { @@ -3340,6 +3340,8 @@ namespace nana void draw(graph_reference graph, const nana::rectangle& r) { + const auto border_color = essence_->scheme_ptr->header_bgcolor.get_color().blend(colors::black, 0.8); + int text_top = (r.height - essence_->scheme_ptr->text_height) / 2 + r.y; auto text_color = essence_->lister.wd_ptr()->fgcolor(); @@ -3365,7 +3367,7 @@ namespace nana if (right_pos > r.x) { _m_draw_header_item(graph, column_r, text_top, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); - graph.line({ right_pos - 1, r.y }, { right_pos - 1, r.bottom() - 2 }, _m_border_color()); + graph.line({ right_pos - 1, r.y }, { right_pos - 1, r.bottom() - 2 }, /*_m_border_color()*/ border_color); } column_r.x = right_pos; @@ -3382,7 +3384,7 @@ namespace nana } const int y = r.bottom() - 1; - graph.line({ r.x, y }, { r.right(), y }, _m_border_color()); + graph.line({ r.x, y }, { r.right(), y }, /*_m_border_color()*/ border_color); if (options_.grab_column) { @@ -3395,11 +3397,6 @@ namespace nana } } private: - ::nana::color _m_border_color() const - { - return essence_->scheme_ptr->header_bgcolor.get_color().blend(colors::black, 0.8); - } - size_type _m_target_strip(int x, const nana::rectangle& rect, size_type grab, bool& place_front) { //convert x to header logic coordinate. @@ -3488,7 +3485,7 @@ namespace nana } private: - essence_t * essence_; + essence * essence_; struct grab_variables { @@ -3514,10 +3511,10 @@ namespace nana class drawer_lister_impl { public: - using item_state = essence_t::item_state; - using parts = essence_t::parts; + using item_state = essence::item_state; + using parts = essence::parts; - drawer_lister_impl(essence_t * es) + drawer_lister_impl(essence * es) :essence_(es) {} @@ -3899,7 +3896,7 @@ namespace nana _m_draw_border(content_r.x, y, show_w); } - essence_t::inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const + essence::inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const { if (column_pos < cat.factories.size()) { @@ -3910,7 +3907,7 @@ namespace nana return nullptr; } - essence_t::inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const + essence::inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const { auto & cat = *essence_->lister.get(pos.cat); @@ -3937,22 +3934,26 @@ namespace nana { //Draw selecting inner rectangle auto graph = essence_->graph; - graph->rectangle({ x, y, width, essence_->scheme_ptr->item_height }, false, static_cast(0x99defd)); + graph->rectangle({ x, y, width, essence_->scheme_ptr->item_height }, false, static_cast(0x99defd)); graph->rectangle({ x + 1, y + 1, width - 2, essence_->scheme_ptr->item_height - 2 }, false, colors::white); + + const int right = x + width - 1; + const int bottom = y + essence_->scheme_ptr->item_height - 1; + graph->set_pixel(x, y); - graph->set_pixel(x, y + essence_->scheme_ptr->item_height - 1); - graph->set_pixel(x + width - 1, y); - graph->set_pixel(x + width - 1, y + essence_->scheme_ptr->item_height - 1); + graph->set_pixel(x, bottom); + graph->set_pixel(right, y); + graph->set_pixel(right, bottom); } private: - essence_t * essence_; + essence * const essence_; mutable facade crook_renderer_; }; //class trigger: public drawer_trigger trigger::trigger() - : essence_(new essence_t), + : essence_(new essence), drawer_header_(new drawer_header_impl(essence_)), drawer_lister_(new drawer_lister_impl(essence_)) {} @@ -3964,7 +3965,7 @@ namespace nana delete essence_; } - essence_t& trigger::essence() const + essence& trigger::ess() const { return *essence_; } @@ -3975,18 +3976,22 @@ namespace nana return; auto & graph = *essence_->graph; - auto size = graph.size(); + + int right = static_cast(graph.width()) - 1; + int bottom = static_cast(graph.height()) - 1; + //Draw Border graph.rectangle(false, static_cast(0x9cb6c5)); - graph.line({ 1, 1 }, {1, static_cast(size.height) - 2}, colors::white); - graph.line({ static_cast(size.width) - 2, 1 }, { static_cast(size.width) - 2, static_cast(size.height) - 2 }); + + graph.line({ 1, 1 }, { 1, bottom - 1}, colors::white); + graph.line({ right - 1, 1 }, { right - 1, bottom - 1 }); if ((essence_->scroll.h.empty() == false) && (essence_->scroll.v.empty() == false)) - graph.rectangle({ static_cast(size.width - 1 - essence_->scroll.scale), - static_cast(size.height - 1 - essence_->scroll.scale), - essence_->scroll.scale, - essence_->scroll.scale }, - true, colors::button_face); + graph.rectangle({ right - static_cast(essence_->scroll.scale), + bottom - static_cast(essence_->scroll.scale), + essence_->scroll.scale, + essence_->scroll.scale }, + true, colors::button_face); } void trigger::attached(widget_reference widget, graph_reference graph) @@ -4030,8 +4035,8 @@ namespace nana void trigger::mouse_move(graph_reference graph, const arg_mouse& arg) { - using item_state = essence_t::item_state; - using parts = essence_t::parts; + using item_state = essence::item_state; + using parts = essence::parts; bool need_refresh = false; @@ -4096,8 +4101,8 @@ namespace nana void trigger::mouse_leave(graph_reference graph, const arg_mouse&) { - using item_state = essence_t::item_state; - using parts = essence_t::parts; + using item_state = essence::item_state; + using parts = essence::parts; if((essence_->pointer_where.first != parts::unknown) || (essence_->ptr_state != item_state::normal)) { if (essence_->ptr_state != item_state::grabbed) @@ -4113,8 +4118,8 @@ namespace nana void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) { - using item_state = essence_t::item_state; - using parts = essence_t::parts; + using item_state = essence::item_state; + using parts = essence::parts; bool update = false; auto & ptr_where = essence_->pointer_where; if((ptr_where.first == parts::header) && (ptr_where.second != npos || (drawer_header_->splitter() != npos))) @@ -4215,8 +4220,8 @@ namespace nana void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) { - using item_state = essence_t::item_state; - using parts = essence_t::parts; + using item_state = essence::item_state; + using parts = essence::parts; auto prev_state = essence_->ptr_state; essence_->ptr_state = item_state::highlighted; @@ -4256,7 +4261,7 @@ namespace nana void trigger::dbl_click(graph_reference graph, const arg_mouse& arg) { - using parts = essence_t::parts; + using parts = essence::parts; if (parts::header == essence_->pointer_where.first) { @@ -4411,11 +4416,11 @@ namespace nana //class item_proxy - item_proxy::item_proxy(essence_t * ess) + item_proxy::item_proxy(essence * ess) : ess_(ess) {} - item_proxy::item_proxy(essence_t * ess, const index_pair& pos) + item_proxy::item_proxy(essence * ess, const index_pair& pos) : ess_(ess), pos_(pos) { @@ -4425,7 +4430,7 @@ namespace nana } /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() - item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative) + item_proxy item_proxy::from_display(essence *ess, const index_pair &relative) { return item_proxy{ess, ess->lister.absolute_pair(relative)}; } @@ -4535,7 +4540,7 @@ namespace nana return *this; } - item_proxy& item_proxy::text(size_type col, std::wstring str) + item_proxy& item_proxy::text(size_type col, const std::wstring& str) { ess_->lister.text(cat_, pos_.item, col, to_utf8(str), columns()); ess_->update(); @@ -4661,7 +4666,7 @@ namespace nana } //Undocumented methods - essence_t * item_proxy::_m_ess() const + essence * item_proxy::_m_ess() const { return ess_; } @@ -4690,14 +4695,14 @@ namespace nana //class cat_proxy //the member cat_ is used for fast accessing to the category - cat_proxy::cat_proxy(essence_t * ess, size_type pos) + cat_proxy::cat_proxy(essence * ess, size_type pos) : ess_(ess), pos_(pos) { _m_cat_by_pos(); } - cat_proxy::cat_proxy(essence_t* ess, category_t* cat) + cat_proxy::cat_proxy(essence* ess, category_t* cat) : ess_(ess), cat_(cat) { @@ -4739,7 +4744,7 @@ namespace nana size_type pos = 0; for (auto & txt : arg) { - ip.text(pos++, to_utf8(txt)); + ip.text(pos++, txt); if (pos >= items) break; } @@ -4797,6 +4802,20 @@ namespace nana return to_utf8(cat_->text); } + bool assign_colors_for_last(essence* ess, category_t* cat) + { + auto wd = ess->lister.wd_ptr(); + if (wd && !API::empty_window(wd->handle())) + { + auto & m = cat->items.back(); + m.bgcolor = wd->bgcolor(); + m.fgcolor = wd->fgcolor(); + + return true; + } + return false; + } + void cat_proxy::push_back(std::string s) { internal_scope_guard lock; @@ -4821,14 +4840,8 @@ namespace nana else cat_->items.emplace_back(std::move(s)); - auto wd = ess_->lister.wd_ptr(); - if(wd && !(API::empty_window(wd->handle()))) - { - auto & m = cat_->items.back(); - m.bgcolor = wd->bgcolor(); - m.fgcolor = wd->fgcolor(); + if (assign_colors_for_last(ess_, cat_)) ess_->update(); - } } //Behavior of a container @@ -5002,13 +5015,7 @@ namespace nana cells.resize(columns()); cat_->items.emplace_back(std::move(cells)); - auto wd = ess_->lister.wd_ptr(); - if (wd && !(API::empty_window(wd->handle()))) - { - auto & m = cat_->items.back(); - m.bgcolor = wd->bgcolor(); - m.fgcolor = wd->fgcolor(); - } + assign_colors_for_last(ess_, cat_); } void cat_proxy::_m_try_append_model(const const_virtual_pointer& dptr) @@ -5028,13 +5035,7 @@ namespace nana cat_->sorted.push_back(cat_->items.size()); cat_->items.emplace_back(); - auto wd = ess_->lister.wd_ptr(); - if (wd && !(API::empty_window(wd->handle()))) - { - auto & m = cat_->items.back(); - m.bgcolor = wd->bgcolor(); - m.fgcolor = wd->fgcolor(); - } + assign_colors_for_last(ess_, cat_); } else { @@ -5295,7 +5296,7 @@ namespace nana auto & ess=_m_ess(); auto _where=ess.where(pos.x, pos.y); index_pair item_pos{npos,npos}; - if(_where.first==drawerbase::listbox::essence_t::parts::lister) + if(_where.first==drawerbase::listbox::essence::parts::lister) { auto & offset_y = ess.scroll.offset_y_dpl; ess.lister.forward(offset_y, _where.second, item_pos); @@ -5498,11 +5499,6 @@ namespace nana return _m_ess().lister.size_categ(); } - listbox::size_type listbox::size_item() const - { - return size_item(0); - } - listbox::size_type listbox::size_item(size_type categ) const { return _m_ess().lister.size_item(categ); @@ -5524,9 +5520,9 @@ namespace nana return _m_ess().def_exp_options; } - drawerbase::listbox::essence_t & listbox::_m_ess() const + drawerbase::listbox::essence & listbox::_m_ess() const { - return get_drawer_trigger().essence(); + return get_drawer_trigger().ess(); } nana::any* listbox::_m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const From 49dfaca1efada80df432ff5bd8ed90a4959c9909 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 13 Jul 2016 22:57:13 +0800 Subject: [PATCH 300/309] fix a crash when the listbox inserts an item. --- source/gui/widgets/listbox.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index f9ddfff5..332f9fce 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -961,7 +961,7 @@ namespace nana } /// Insert before item in absolute "pos" a new item with "text" in column 0, and place it in last display position of this cat - void insert(const index_pair& pos, std::string&& text) + void insert(const index_pair& pos, std::string&& text, std::size_t columns) { auto & catobj = *get(pos.cat); @@ -990,8 +990,8 @@ namespace nana container->emplace_back(); } - std::vector cells; - cells.emplace_back(std::move(text)); + std::vector cells{ columns }; + cells[0] = std::move(text); container->assign(item_index, cells); } else @@ -1000,9 +1000,9 @@ namespace nana catobj.items.emplace(catobj.items.begin() + pos.item, std::move(text)); else catobj.items.emplace_back(std::move(text)); - } - catobj.items.back().cells->emplace_back(std::move(text)); + catobj.items.back().cells->emplace_back(std::move(text)); + } } /// convert from display order to absolute (find the real item in that display pos) but without check from current active sorting, in fact using just the last sorting !!! @@ -5246,7 +5246,7 @@ namespace nana { internal_scope_guard lock; auto & ess = _m_ess(); - ess.lister.insert(pos, std::move(text)); + ess.lister.insert(pos, std::move(text), ess.header.cont().size()); if (!empty()) { From 9b91d3b55ff88fa3f1ddc75b34e2ace980269277 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 13 Jul 2016 23:00:03 +0800 Subject: [PATCH 301/309] listbox and place code refined --- source/gui/place.cpp | 37 +++++---------------- source/gui/widgets/listbox.cpp | 61 +++++++++++++++------------------- 2 files changed, 34 insertions(+), 64 deletions(-) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index bfa0e658..a10246f9 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -503,7 +503,7 @@ namespace nana static event_handle erase_element(std::vector& elements, window handle) { - for (auto i = elements.begin(), end = elements.end(); i != end; ++i) + for (auto i = elements.begin(); i != elements.end(); ++i) { if (i->handle == handle) { @@ -515,26 +515,16 @@ namespace nana return nullptr; } private: - //The defintion is moved after the definition of class division - template - void _m_for_each(division*, Function); - //Listen to destroy of a window //It will delete the element and recollocate when the window destroyed. event_handle _m_make_destroy(window wd) { return API::events(wd).destroy.connect([this, wd](const arg_destroy&) { - for (auto i = elements.begin(), end = elements.end(); i != end; ++i) + if (erase_element(elements, wd)) { - if (i->handle == wd) - { - elements.erase(i); - - if (!API::is_destroying(API::get_parent_window(wd))) - place_ptr_->collocate(); - break; - } + if (!API::is_destroying(API::get_parent_window(wd))) + place_ptr_->collocate(); } }); } @@ -613,10 +603,7 @@ namespace nana division(kind k, std::string&& n) : kind_of_division(k), - name(std::move(n)), - field(nullptr), - div_next(nullptr), - div_owner(nullptr) + name(std::move(n)) {} virtual ~division() @@ -754,7 +741,6 @@ namespace nana //Collocate the division and its children divisions, //The window parameter is specified for the window which the place object binded. virtual void collocate(window) = 0; - public: kind kind_of_division; bool display{ true }; @@ -769,18 +755,11 @@ namespace nana place_parts::margin margin; place_parts::repeated_array gap; - field_gather * field; - division * div_next, *div_owner; + field_gather * field{ nullptr }; + division * div_next{ nullptr }; + division * div_owner{ nullptr }; };//end class division - template - void place::implement::field_gather::_m_for_each(division * div, Function fn) - { - for (auto & up : div->children) //The element of children is unique_ptr - fn(up.get()); - } - - class place::implement::div_arrange : public division { diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 332f9fce..5295a1e7 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -547,8 +547,6 @@ namespace nana }; - struct essence; - struct item_data { using container = std::vector; @@ -719,7 +717,7 @@ namespace nana if (allocate_if_empty) { - std::make_unique().swap(item.anyobj); + item.anyobj.reset(new any); return item.anyobj.get(); } } @@ -1044,8 +1042,8 @@ namespace nana { auto i = categories_.cbegin(); std::advance(i, pos.cat); - if (i->model_ptr && i->model_ptr->container()->immutable()) - throw std::runtime_error("nana::listbox disallow the operation because of immutable modal"); + + throw_if_immutable_model(i->model_ptr.get()); } } @@ -1057,8 +1055,7 @@ namespace nana std::advance(i, pos.cat); if (i->model_ptr) { - if (i->model_ptr->container()->immutable()) - throw std::runtime_error("nana::listbox disallow to modify the item because of immutable model"); + throw_if_immutable_model(i->model_ptr.get()); i->model_ptr->container()->assign(pos.item, cells); } @@ -1874,7 +1871,7 @@ namespace nana { return index_pair{ absolute(first()) }; } - + bool good(size_type cat) const { return (cat < categories_.size()); @@ -1884,6 +1881,7 @@ namespace nana { return ((pos.cat < categories_.size()) && (pos.item < size_item(pos.cat))); } + /// if good return the same item (in arg item), or just the next cat and true, but If fail return false bool good_item(index_pair pos, index_pair& item) const { @@ -1951,6 +1949,7 @@ namespace nana return npos; } + index_pair relative_pair(const index_pair& pos) const { //Returns an empty pos if item is npos @@ -2251,19 +2250,14 @@ namespace nana adjust_scroll_life(); // call adjust_scroll_value(); //adjust_scroll_value(); // again? } - void trace_item_abs( index_pair abs_pos ) - { - if( abs_pos.item == npos - && abs_pos.cat == scroll.offset_y_abs.cat - && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat - return; - - trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ; - } - void trace_last_selected_item( ) { - trace_item_abs(lister.last_selected_abs); + if (lister.last_selected_abs.item == npos && + lister.last_selected_abs.cat == scroll.offset_y_abs.cat && + scroll.offset_y_abs.item == npos) // if item==off y and is a cat + return; + + trace_item_dpl(lister.relative_pair(lister.last_selected_abs)); // ??? scroll_y_dpl_refresh() ; } void update() @@ -3040,7 +3034,7 @@ namespace nana { auto& cat = *get(pos.cat); - if ((pos.item != ::nana::npos) && (pos.item >= cat.items.size())) + if ((pos.item != nana::npos) && (pos.item >= cat.items.size())) throw std::invalid_argument("listbox: invalid pos to scroll"); if (!cat.expand) @@ -3069,12 +3063,12 @@ namespace nana if (categories_.back().expand) { if (categories_.back().items.empty()) - last.item = npos; + last.item = nana::npos; else last.item = categories_.back().items.size() - 1; } else - last.item = ::nana::npos; + last.item = nana::npos; backward(last, view_items, start_pos); } @@ -3204,19 +3198,18 @@ namespace nana std::vector model_cells; + auto const pcell = (cat.model_ptr ? &model_cells : nullptr); + for (auto i : cat.sorted) { auto& item = cat.items[i]; if (item.flags.selected || !exp_opt.only_selected_items) { //Test if the category have a model set. - if (cat.model_ptr) - { + if (pcell) cat.model_ptr->container()->to_cells(i).swap(model_cells); - list_str += (item.to_string(exp_opt, &model_cells) + exp_opt.endl); - } - else - list_str += (item.to_string(exp_opt, nullptr) + exp_opt.endl); + + list_str += (item.to_string(exp_opt, pcell) + exp_opt.endl); } } } @@ -3473,15 +3466,16 @@ namespace nana { const auto & col = essence_->header.at(essence_->pointer_where.second); - nana::paint::graphics ext_graph({ col.width_px, essence_->scheme_ptr->header_height }); - ext_graph.typeface(essence_->graph->typeface()); + paint::graphics fl_graph({ col.width_px, essence_->scheme_ptr->header_height }); + + fl_graph.typeface(essence_->graph->typeface()); int text_top = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; - _m_draw_header_item(ext_graph, rectangle{ext_graph.size()}, text_top, colors::white, col, item_state::floated); + _m_draw_header_item(fl_graph, rectangle{ fl_graph.size()}, text_top, colors::white, col, item_state::floated); auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos; - ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), point{xpos - static_cast(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5); + fl_graph.blend(rectangle{ fl_graph.size() }, *(essence_->graph), point{xpos - static_cast(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5); } private: @@ -5084,9 +5078,6 @@ namespace nana API::refresh_window(ess_->listbox_ptr->handle()); } } - - //class cat_proxy - //end class cat_proxy } }//end namespace drawerbase From 31455aa1650ece77101ac3a56d88e25bbeac6a87 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 14 Jul 2016 00:15:50 +0800 Subject: [PATCH 302/309] fix listbox horiz scroll issue(#145) --- source/gui/widgets/listbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 5295a1e7..abb84b68 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2330,7 +2330,7 @@ namespace nana //H scroll enabled //If range_adjusted is true, it indicates no horzontal scroll bar is enabled. - bool enable_horz = (range_adjusted && (columns_pixels + 4 > sz.width)); // 4px = left and right borders(2px) + left and right gaps(2px) + bool enable_horz = ((!range_adjusted) && (columns_pixels + 4 > sz.width)); // 4px = left and right borders(2px) + left and right gaps(2px) unsigned head_scroll = 2 + header_visible_px() + (enable_horz ? scroll.scale : 0); // 2px left and right gaps(2px) unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0; From 0a0fab679b5db8202385a250ad6c98e76de430d8 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 14 Jul 2016 00:41:34 +0800 Subject: [PATCH 303/309] fix some issues that are detected by PVS-studio team --- include/nana/gui/widgets/skeletons/text_token_stream.hpp | 3 +-- source/gui/detail/window_manager.cpp | 2 +- source/gui/widgets/skeletons/text_editor.cpp | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index a34183ce..3807ac16 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -665,8 +665,7 @@ namespace nana{ namespace widgets{ namespace skeletons case token::eof: return; default: - int * debug = 0; //for debug. - *debug = 0; + throw std::runtime_error("invalid token"); } } } diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 0af79eb8..2fedf0d7 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -293,7 +293,7 @@ namespace detail auto result = native_interface::create_window(native, nested, r, app); if (result.native_handle) { - core_window_t* wd = new core_window_t(owner, widget_notifier_interface::get_notifier(wdg), (category::root_tag**)nullptr); + auto wd = new core_window_t(owner, widget_notifier_interface::get_notifier(wdg), (category::root_tag**)nullptr); if (nested) { wd->owner = nullptr; diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 09a1c556..3a594643 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1312,7 +1312,7 @@ namespace nana{ namespace widgets void text_editor::set_highlight(const std::string& name, const ::nana::color& fgcolor, const ::nana::color& bgcolor) { - if (fgcolor.invisible() && fgcolor.invisible()) + if (fgcolor.invisible() && bgcolor.invisible()) { keywords_->schemes.erase(name); return; @@ -3259,7 +3259,7 @@ namespace nana{ namespace widgets else if (pos <= a.x && a.x < str_end) { //Partial selected int endpos = static_cast(b.x < str_end ? b.x : str_end); - std::unique_ptr pxbuf_ptr(new unsigned[len]); + std::unique_ptr pxbuf_ptr(new unsigned[len]); unsigned * pxbuf = pxbuf_ptr.get(); if (graph_.glyph_pixels(ent.begin, len, pxbuf)) { From de777617ffb1c87d37e14d59d47371a1732d2ff3 Mon Sep 17 00:00:00 2001 From: dankan1890 Date: Wed, 13 Jul 2016 22:12:29 +0200 Subject: [PATCH 304/309] c++ defines patch: # Recent versions of clang have support for make_unique. # Check if macro "__cpp_lib_experimental_filesystem" is defined and match with the standard value. --- include/nana/c++defines.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 26ffe63f..bd39a822 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -118,9 +118,10 @@ // is a known issue on libstdc++, it works on libc++ #define STD_CODECVT_NOT_SUPPORTED - - #ifndef STD_MAKE_UNIQUE_NOT_SUPPORTED - #define STD_MAKE_UNIQUE_NOT_SUPPORTED + #if !defined(__cpp_lib_make_unique) || (__cpp_lib_make_unique != 201304) + #ifndef STD_MAKE_UNIQUE_NOT_SUPPORTED + #define STD_MAKE_UNIQUE_NOT_SUPPORTED + #endif #endif #endif @@ -195,9 +196,9 @@ // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0061r0.html -# if __cpp_lib_experimental_filesystem -# undef STD_FILESYSTEM_NOT_SUPPORTED -# endif +#if defined(__cpp_lib_experimental_filesystem) && (__cpp_lib_experimental_filesystem == 201406) +# undef STD_FILESYSTEM_NOT_SUPPORTED +#endif #ifdef __has_include From 29446b5ef0ab3e12bd6fe32b5b6323e49dfc3ba5 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 17 Jul 2016 10:23:20 +0800 Subject: [PATCH 305/309] fix crash when adding a header to a zero-size listbox(#147) --- source/gui/widgets/listbox.cpp | 48 ++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index abb84b68..85889705 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2322,10 +2322,20 @@ namespace nana { internal_scope_guard lock; + const unsigned border_px = 1; + const unsigned border_px_twice = (border_px << 1); + const nana::size sz = graph->size(); + + if ((sz.width <= border_px_twice) || (sz.height <= border_px_twice)) + { + scroll.h.close(); + scroll.v.close(); + return; + } // Adjust the ranged column assume the vertical scrollbar is enabled. - auto range_adjusted = this->header.calc_ranged_columns(sz.width - 2 - scroll.scale); + auto range_adjusted = this->header.calc_ranged_columns(sz.width - border_px_twice - scroll.scale); auto columns_pixels = header.pixels(); //H scroll enabled @@ -2347,13 +2357,9 @@ namespace nana else if (range_adjusted) { //No vertical scrollbar, then re-adjust the range columns for a new width that excludes vert scroll. - this->header.calc_ranged_columns(sz.width - 2); + this->header.calc_ranged_columns(sz.width - border_px_twice); } - - unsigned width = sz.width - 2 - (enable_vert ? scroll.scale : 0); - unsigned height = sz.height - 2 - (enable_horz ? scroll.scale : 0); - //event hander for scrollbars auto evt_fn = [this](const arg_scroll& arg) { @@ -2371,12 +2377,28 @@ namespace nana API::refresh_window(this->lister.wd_ptr()->handle()); }; + unsigned horz_px = sz.width - border_px_twice; + if (enable_vert) + { + if (horz_px < scroll.scale) + horz_px = 0; + else + horz_px -= scroll.scale; + } - const auto wd_handle = lister.wd_ptr()->handle(); - + unsigned vert_px = sz.height - border_px_twice; if (enable_horz) { - rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); + if (vert_px < scroll.scale) + vert_px = 0; + else + vert_px -= scroll.scale; + } + + const auto wd_handle = lister.wd_ptr()->handle(); + if (enable_horz && horz_px) + { + rectangle r(border_px, static_cast(sz.height - border_px) - static_cast(scroll.scale), horz_px, scroll.scale); if(scroll.h.empty()) { scroll.h.create(wd_handle, r); @@ -2389,9 +2411,9 @@ namespace nana else if(!scroll.h.empty()) scroll.h.close(); - if (enable_vert) + if (enable_vert && vert_px) { - rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); + rectangle r(static_cast(sz.width - border_px) - static_cast(scroll.scale), border_px, scroll.scale, vert_px); if(scroll.v.empty()) { scroll.v.create(wd_handle, r); @@ -4253,7 +4275,7 @@ namespace nana } } - void trigger::dbl_click(graph_reference graph, const arg_mouse& arg) + void trigger::dbl_click(graph_reference graph, const arg_mouse&) { using parts = essence::parts; @@ -5022,8 +5044,6 @@ namespace nana ess_->lister.throw_if_immutable_model(cat_->model_ptr.get()); - - auto pos = cat_->model_ptr->container()->size(); if (cat_->model_ptr->container()->push_back(dptr)) { cat_->sorted.push_back(cat_->items.size()); From 56697b331a0a24c3ffe385cd5fba1beff1905425 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 17 Jul 2016 20:58:00 +0800 Subject: [PATCH 306/309] improve text_editor --- .../gui/widgets/skeletons/text_editor.hpp | 4 +- source/gui/widgets/skeletons/text_editor.cpp | 589 ++++++++---------- 2 files changed, 279 insertions(+), 314 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 7054899a..d2a10a35 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -138,6 +138,7 @@ namespace nana{ namespace widgets struct keywords; class keyword_parser; + class helper_pencil; public: using char_type = wchar_t; using size_type = textbase::size_type; @@ -269,10 +270,11 @@ namespace nana{ namespace widgets skeletons::textbase& textbase(); const skeletons::textbase& textbase() const; private: + void _m_pre_calc_lines(std::size_t line_off, std::size_t lines); + bool _m_accepts(char_type) const; ::nana::color _m_bgcolor() const; bool _m_scroll_text(bool vertical); - void _m_on_scroll(const arg_mouse&); void _m_scrollbar(); ::nana::size _m_text_area() const; void _m_get_scrollbar_size(); diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 3a594643..d989cc83 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -250,7 +250,7 @@ namespace nana{ namespace widgets class text_editor::editor_behavior_interface { public: - virtual ~editor_behavior_interface(){} + virtual ~editor_behavior_interface() = default; /// Deletes lines between first and second, and then, second line will be merged into first line. virtual void merge_lines(std::size_t first, std::size_t second) = 0; @@ -312,9 +312,7 @@ namespace nana{ namespace widgets ::nana::upoint str_pos(0, static_cast(editor_.points_.offset.y)); - std::size_t scrlines = editor_.screen_lines() + str_pos.y; - if (scrlines > editor_.textbase_.lines()) - scrlines = editor_.textbase_.lines(); + const auto scrlines = (std::min)(editor_.screen_lines() + str_pos.y, static_cast(editor_.textbase_.lines())); int top = editor_._m_text_top_base(); const unsigned pixels = editor_.line_height(); @@ -522,6 +520,9 @@ namespace nana{ namespace widgets std::vector line_sections; }; public: + /// A coordinate type for line position. first: the absolute line position of text. second: the secondary line position of a part of line. + using row_coordinate = std::pair; + behavior_linewrapped(text_editor& editor) : editor_(editor) {} @@ -706,13 +707,12 @@ namespace nana{ namespace widgets { std::vector line_index; - std::size_t secondary; - auto primary = _m_textline_from_screen(0, secondary); - if (primary >= linemtr_.size() || secondary >= linemtr_[primary].line_sections.size()) + auto row = _m_textline_from_screen(0); + if (row.first >= linemtr_.size() || row.second >= linemtr_[row.first].line_sections.size()) return line_index; - nana::upoint str_pos(0, static_cast(primary)); - str_pos.x = static_cast(linemtr_[primary].line_sections[secondary].begin - editor_.textbase_.getline(primary).c_str()); + nana::upoint str_pos(0, static_cast(row.first)); + str_pos.x = static_cast(linemtr_[row.first].line_sections[row.second].begin - editor_.textbase_.getline(row.first).c_str()); int top = editor_._m_text_top_base(); const unsigned pixels = editor_.line_height(); @@ -720,19 +720,19 @@ namespace nana{ namespace widgets const std::size_t scrlines = editor_.screen_lines(); for (std::size_t pos = 0; pos < scrlines; ++pos, top += pixels) { - if ((primary < linemtr_.size()) && (secondary < linemtr_[primary].line_sections.size())) + if ((row.first < linemtr_.size()) && (row.second < linemtr_[row.first].line_sections.size())) { - auto & mtr = linemtr_[primary]; - auto & section = mtr.line_sections[secondary]; + auto & mtr = linemtr_[row.first]; + auto & section = mtr.line_sections[row.second]; std::wstring text(section.begin, section.end); editor_._m_draw_string(top, fgcolor, str_pos, text, true); line_index.push_back(str_pos); - ++secondary; - if (secondary >= mtr.line_sections.size()) + ++row.second; + if (row.second >= mtr.line_sections.size()) { - ++primary; - secondary = 0; + ++row.first; + row.second = 0; str_pos.x = 0; ++str_pos.y; } @@ -800,15 +800,14 @@ namespace nana{ namespace widgets nana::upoint screen_to_caret(point scrpos) override { - std::size_t secondary; - std::size_t primary = _m_textline_from_screen(scrpos.y, secondary); + const auto row = _m_textline_from_screen(scrpos.y); - auto & mtr = linemtr_[primary]; + auto & mtr = linemtr_[row.first]; if (mtr.line_sections.empty()) - return{ 0, static_cast(primary) }; + return{ 0, static_cast(row.first) }; //First of all, find the text of secondary. - auto real_str = mtr.line_sections[secondary]; + auto real_str = mtr.line_sections[row.second]; auto text_ptr = real_str.begin; const auto text_size = real_str.end - real_str.begin; @@ -823,7 +822,7 @@ namespace nana{ namespace widgets std::vector reordered; unicode_bidi{}.linestr(text_ptr, text_size, reordered); - nana::upoint res(static_cast(real_str.begin - mtr.line_sections.front().begin), static_cast(primary)); + nana::upoint res(static_cast(real_str.begin - mtr.line_sections.front().begin), static_cast(row.first)); scrpos.x -= editor_.text_area_.area.x; if (scrpos.x < 0) scrpos.x = 0; @@ -886,11 +885,10 @@ namespace nana{ namespace widgets if (0 == scrlines) return false; - auto & points = editor_.points_; + const auto & points = editor_.points_; editor_._m_get_scrollbar_size(); - std::size_t off_secondary; - auto off_primary = _m_textline(points.offset.y, off_secondary); + auto off_coord = _m_textline(points.offset.y); unsigned caret_secondary; { @@ -900,26 +898,26 @@ namespace nana{ namespace widgets } //Use the caret line for the offset line when caret is in front of current offset line. - if (off_primary > points.caret.y || ((off_primary == points.caret.y) && (off_secondary > caret_secondary))) + if (off_coord.first > points.caret.y || ((off_coord.first == points.caret.y) && (off_coord.second > caret_secondary))) { //Use the line which was specified by points.caret for the first line. - _m_set_offset_by_secondary(points.caret.y, caret_secondary); + _m_set_offset_by_secondary(row_coordinate(points.caret.y, caret_secondary)); return true; } //Find the last screen line. If the text does not reach the bottom of screen, //do not adjust the offset line. - nana::upoint bottom; //x=primary, y=secondary - if (false == _m_advance_secondary(off_primary, off_secondary, static_cast(scrlines - 1), bottom)) + row_coordinate bottom; + if (false == _m_advance_secondary(off_coord, static_cast(scrlines - 1), bottom)) return false; //Do not adjust the offset line if the caret line does not reach the bottom line. - if (points.caret.y < bottom.x || ((points.caret.y == bottom.x) && (caret_secondary <= bottom.y))) + if (points.caret.y < bottom.first || ((points.caret.y == bottom.first) && (caret_secondary <= bottom.second))) return false; - _m_advance_secondary(points.caret.y, caret_secondary, -static_cast(scrlines - 1), bottom); + _m_advance_secondary(row_coordinate(points.caret.y, caret_secondary), -static_cast(scrlines - 1), bottom); - _m_set_offset_by_secondary(bottom.x, bottom.y); + _m_set_offset_by_secondary(bottom); return true; } private: @@ -958,23 +956,22 @@ namespace nana{ namespace widgets tsec.emplace_back(word, end, unsigned{}); } - void _m_set_offset_by_secondary(std::size_t primary, std::size_t secondary) + void _m_set_offset_by_secondary(row_coordinate row) { - for (auto i = linemtr_.begin(), end = linemtr_.begin() + primary; i != end; ++i) - secondary += i->take_lines; + for (auto i = linemtr_.begin(), end = linemtr_.begin() + row.first; i != end; ++i) + row.second += i->take_lines; - editor_.points_.offset.y = static_cast(secondary); + editor_.points_.offset.y = static_cast(row.second); } - bool _m_advance_secondary(std::size_t primary, std::size_t secondary, int distance, nana::upoint& new_sec) + bool _m_advance_secondary(row_coordinate row, int distance, row_coordinate& new_row) { - if ((primary >= linemtr_.size()) || (secondary >= linemtr_[primary].take_lines)) + if ((row.first >= linemtr_.size()) || (row.second >= linemtr_[row.first].take_lines)) return false; if (0 == distance) { - new_sec.x = static_cast(primary); - new_sec.y = static_cast(secondary); + new_row = row; return true; } @@ -982,32 +979,32 @@ namespace nana{ namespace widgets { std::size_t n = static_cast(-distance); - if (secondary > n) + if (row.second > n) { - new_sec.x = static_cast(primary); - new_sec.y = static_cast(secondary - n); + new_row.first = row.first; + new_row.second = row.second - n; return true; } - if (0 == primary) + if (0 == row.first) return false; - --primary; - n -= (secondary + 1); + --row.first; + n -= (row.second + 1); while (true) { - auto lines = linemtr_[primary].take_lines; + auto lines = linemtr_[row.first].take_lines; if (lines >= n) { - new_sec.x = static_cast(primary); - new_sec.y = static_cast(lines - n); + new_row.first = row.first; + new_row.second = lines - n; return true; } - if (0 == primary) + if (0 == row.first) return false; - --primary; + --row.first; n -= lines; } } @@ -1015,22 +1012,24 @@ namespace nana{ namespace widgets { std::size_t n = static_cast(distance); - if (linemtr_[primary].take_lines - (secondary + 1) >= n) + auto delta_lines = linemtr_[row.first].take_lines - (row.second + 1); + + if (delta_lines >= n) { - new_sec.x = static_cast(primary); - new_sec.y = static_cast(secondary + n); + new_row.first = row.first; + new_row.second = row.second + n; return true; } - n -= (linemtr_[primary].take_lines - (secondary + 1)); + n -= delta_lines; - while (++primary < linemtr_.size()) + while (++row.first < linemtr_.size()) { - auto & mtr = linemtr_[primary]; + auto & mtr = linemtr_[row.first]; if (mtr.take_lines >= n) { - new_sec.x = static_cast(primary); - new_sec.y = static_cast(n - 1); + new_row.first = row.first; + new_row.second = n - 1; return true; } n -= mtr.take_lines; @@ -1049,9 +1048,8 @@ namespace nana{ namespace widgets return false; auto & section = mtr.line_sections[secondary.y]; - unsigned len = static_cast(section.end - section.begin); - auto chptr = section.begin + (secondary.x > len ? len : secondary.x); + auto chptr = section.begin + (std::min)(secondary.x, static_cast(section.end - section.begin)); pos = static_cast(chptr - editor_.textbase_.getline(textline).c_str()); return true; } @@ -1080,37 +1078,32 @@ namespace nana{ namespace widgets } - std::size_t _m_textline(std::size_t scrline, std::size_t & secondary) const + row_coordinate _m_textline(std::size_t scrline) const { - secondary = 0; - std::size_t primary = 0; - + row_coordinate coord; for (auto & mtr : linemtr_) { if (mtr.take_lines > scrline) { - secondary = scrline; - return primary; + coord.second = scrline; + return coord; } else scrline -= mtr.take_lines; - ++primary; + ++coord.first; } - - return primary; + return coord; } //secondary, index of line that the text was splitted into multilines. - std::size_t _m_textline_from_screen(int y, std::size_t & secondary) const + row_coordinate _m_textline_from_screen(int y) const { + row_coordinate coord; const auto line_px = static_cast(editor_.line_height()); if ((0 == editor_.textbase_.lines()) || (0 == line_px)) - { - secondary = 0; - return 0; - } + return coord; const int text_area_top = editor_.text_area_.area.y; const int offset_top = editor_.points_.offset.y; @@ -1121,12 +1114,13 @@ namespace nana{ namespace widgets else screen_line = offset_top - screen_line; - auto primary = _m_textline(static_cast(screen_line), secondary); - if (primary < linemtr_.size()) - return primary; - - secondary = linemtr_.back().line_sections.size() - 1; - return linemtr_.size() - 1; + coord = _m_textline(static_cast(screen_line)); + if (linemtr_.size() <= coord.first) + { + coord.first = linemtr_.size() - 1; + coord.second = linemtr_.back().line_sections.size() - 1; + } + return coord; } private: text_editor& editor_; @@ -1522,13 +1516,12 @@ namespace nana{ namespace widgets rectangle text_editor::text_area(bool including_scroll) const { - if (including_scroll) - return text_area_.area; - auto r = text_area_.area; - - r.width = text_area_.area.width > text_area_.vscroll ? text_area_.area.width - text_area_.vscroll : 0; - r.height = text_area_.area.height > text_area_.hscroll ? text_area_.area.height - text_area_.hscroll : 0; + if (!including_scroll) + { + r.width = r.width > text_area_.vscroll ? r.width - text_area_.vscroll : 0; + r.height = r.height > text_area_.hscroll ? r.height - text_area_.hscroll : 0; + } return r; } @@ -2127,7 +2120,8 @@ namespace nana{ namespace widgets auto secondary_before = behavior_->take_lines(points_.caret.y); textbase_.insert(points_.caret, std::move(ch_str)); - behavior_->pre_calc_line(points_.caret.y, width_pixels()); + _m_pre_calc_lines(points_.caret.y, 1); + points_.caret.x ++; if (refresh || _m_update_caret_line(secondary_before)) @@ -2208,10 +2202,8 @@ namespace nana{ namespace widgets if (record_undo) undo_.push(std::move(undo_ptr)); - const auto width_px = width_pixels(); behavior_->add_lines(points_.caret.y - 1, 1); - behavior_->pre_calc_line(points_.caret.y, width_px); - behavior_->pre_calc_line(points_.caret.y - 1, width_px); + _m_pre_calc_lines(points_.caret.y - 1, 2); points_.caret.x = 0; @@ -2286,7 +2278,8 @@ namespace nana{ namespace widgets undo_ptr->set_removed(lnstr.substr(points_.caret.x, erase_number)); auto secondary = behavior_->take_lines(points_.caret.y); textbase_.erase(points_.caret.y, points_.caret.x, erase_number); - behavior_->pre_calc_line(points_.caret.y, width_pixels()); + _m_pre_calc_lines(points_.caret.y, 1); + if(_m_move_offset_x_while_over_border(-2) == false) { behavior_->update_line(points_.caret.y, secondary); @@ -2589,6 +2582,13 @@ namespace nana{ namespace widgets return false; } + void text_editor::_m_pre_calc_lines(std::size_t line_off, std::size_t lines) + { + unsigned width_px = width_pixels(); + for (auto pos = line_off, end = line_off + lines; pos != end; ++pos) + this->behavior_->pre_calc_line(pos, width_px); + } + bool text_editor::_m_accepts(char_type ch) const { if (accepts::no_restrict == attributes_.acceptive) @@ -2637,27 +2637,23 @@ namespace nana{ namespace widgets return false; } - void text_editor::_m_on_scroll(const arg_mouse& arg) - { - if((arg.evt_code == event_code::mouse_move) && (arg.left_button == false)) - return; - - bool vert = (attributes_.vscroll && (attributes_.vscroll->handle() == arg.window_handle)); - if(_m_scroll_text(vert)) - { - render(true); - reset_caret(); - API::update_window(window_); - } - } - void text_editor::_m_scrollbar() { _m_get_scrollbar_size(); nana::size tx_area = _m_text_area(); - auto scroll_fn = [this](const arg_mouse& arg) { - _m_on_scroll(arg); + auto scroll_fn = [this](const arg_mouse& arg) + { + if ((arg.evt_code == event_code::mouse_move) && (arg.left_button == false)) + return; + + bool vert = (attributes_.vscroll && (attributes_.vscroll->handle() == arg.window_handle)); + if (_m_scroll_text(vert)) + { + render(true); + reset_caret(); + API::update_window(window_); + } }; if (text_area_.vscroll) @@ -2800,11 +2796,8 @@ namespace nana{ namespace widgets textbase_.insertln(++crtpos.y, text.substr(backpos.first, backpos.second - backpos.first) + str_orig.substr(x_orig)); crtpos.x = static_cast(backpos.second - backpos.first); - const auto width_px = width_pixels(); behavior_->add_lines(points_.caret.y, lines.size() - 1); - const auto endline = points_.caret.y + lines.size(); - for (auto i = points_.caret.y; i < endline; ++i) - behavior_->pre_calc_line(i, width_px); + _m_pre_calc_lines(points_.caret.y, lines.size()); } else { @@ -2816,7 +2809,7 @@ namespace nana{ namespace widgets textbase_.insert(crtpos, std::move(text)); crtpos.x += static_cast(length); - behavior_->pre_calc_line(crtpos.y, width_pixels()); + _m_pre_calc_lines(crtpos.y, 1); } return crtpos; } @@ -2839,7 +2832,7 @@ namespace nana{ namespace widgets else { textbase_.erase(a.y, a.x, b.x - a.x); - behavior_->pre_calc_line(a.y, width_pixels()); + _m_pre_calc_lines(a.y, 1); } select_.a = select_.b; @@ -3142,32 +3135,76 @@ namespace nana{ namespace widgets ent_pos.x += ent_off; + if (rtl) { //draw the whole text if it is a RTL text, because Arbic language is transformable. canvas.string({}, str, len); - graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas, point{ ent_off, 0 }); } else { canvas.string({}, ent_begin, ent_end - ent_begin); - graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas); + ent_off = 0; } + graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas, point{ ent_off, 0 }); } } } - void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const std::wstring& str, bool if_mask) const + class text_editor::helper_pencil { - point text_pos{ text_area_.area.x - points_.offset.x, top }; + public: + helper_pencil(paint::graphics& graph, const text_editor& editor, const color_proxy& selection_fgcolor, const color_proxy& selection_bgcolor, keyword_parser& parser): + graph_( graph ), + editor_( editor ), + parser_( parser ), + selection_fgcolor_{ selection_fgcolor }, + selection_bgcolor_{ selection_bgcolor }, + line_px_( editor.line_height() ) + {} + + void write_selection(const point& text_pos, unsigned text_px, const wchar_t* text, std::size_t len) + { + graph_.palette(true, selection_fgcolor_.get_color()); + graph_.rectangle(::nana::rectangle{ text_pos, { text_px, line_px_ } }, true, selection_bgcolor_); + graph_.string(text_pos, text, len); + } + + void rtl_string(point strpos, const wchar_t* str, std::size_t len, std::size_t str_px, unsigned glyph_front, unsigned glyph_selected) + { + editor_._m_draw_parse_string(parser_, true, strpos, selection_fgcolor_.get_color(), str, len); + + //Draw selected part + paint::graphics graph({ glyph_selected, line_px_ }); + graph.typeface(this->graph_.typeface()); + graph.rectangle(true, selection_bgcolor_.get_color()); + + int sel_xpos = static_cast(str_px - (glyph_front + glyph_selected)); + + graph.palette(true, selection_fgcolor_.get_color()); + graph.string({ -sel_xpos, 0 }, str, len); + graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_px_), graph); + }; + private: + paint::graphics& graph_; + const text_editor& editor_; + keyword_parser & parser_; + const color_proxy & selection_fgcolor_; + const color_proxy & selection_bgcolor_; + unsigned line_px_; + }; + + void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& text_coord, const std::wstring& text, bool if_mask) const + { + point text_draw_pos{ text_area_.area.x - points_.offset.x, top }; const int text_right = text_area_.area.right(); - auto text_ptr = &str; + auto text_ptr = &text; std::wstring mask_str; if (if_mask && mask_char_) { - mask_str.resize(str.size(), mask_char_); + mask_str.resize(text.size(), mask_char_); text_ptr = &mask_str; } @@ -3180,232 +3217,159 @@ namespace nana{ namespace widgets keyword_parser parser; parser.parse(*text_ptr, keywords_.get()); - auto whitespace_w = graph_.text_extent_size(L" ", 1).width; - const auto line_h_pixels = line_height(); - //The line of text is in the range of selection - nana::upoint a, b; + helper_pencil pencil(graph_, *this, scheme_->selection_text, scheme_->selection, parser); + + graph_.palette(true, clr); graph_.palette(false, scheme_->selection.get_color()); - //The text is not selected or the whole line text is selected - if(!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y) || !attributes_.editable) + + //Get the selection begin and end position of the current text. + const wchar_t *sbegin = nullptr, *send = nullptr; + + nana::upoint a, b; + if (_m_get_sort_select_points(a, b)) + { + if (a.y < text_coord.y && text_coord.y < b.y) + { + sbegin = text_ptr->c_str(); + send = sbegin + text_ptr->size(); + } + else if ((a.y == b.y) && a.y == text_coord.y) + { + auto sbegin_pos = (std::max)(a.x, text_coord.x); + auto send_pos = (std::min)(text_coord.x + text_ptr->size(), b.x); + + if (sbegin_pos < send_pos) + { + sbegin = text_ptr->c_str() + (sbegin_pos - text_coord.x); + send = text_ptr->c_str() + (send_pos - text_coord.x); + } + } + else if (a.y == text_coord.y) + { + if (a.x < text_coord.x + text_ptr->size()) + { + sbegin = text_ptr->c_str(); + if (text_coord.x < a.x) + sbegin += (a.x - text_coord.x); + + send = text_ptr->c_str() + text_ptr->size(); + } + } + else if (b.y == text_coord.y) + { + if (text_coord.x < b.x) + { + sbegin = text_ptr->c_str(); + send = text_ptr->c_str() + (std::min)(b.x - text_coord.x, text_ptr->size()); + } + } + } + + //A text editor feature, it draws an extra block at end of line if the end of line is in range of selection. + bool extra_space = false; + + const bool text_selected = (sbegin == text_ptr->c_str() && send == text_ptr->c_str() + text_ptr->size()); + //The text is not selected or the whole line text is selected + if (!focused || (!sbegin || !send) || text_selected || !attributes_.editable) { - bool selected = (a.y < str_pos.y && str_pos.y < b.y); for (auto & ent : reordered) { std::size_t len = ent.end - ent.begin; unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < text_right)) + if ((text_draw_pos.x + static_cast(str_w) > text_area_.area.x) && (text_draw_pos.x < text_right)) { - if (selected && focused) - { - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true); - graph_.string(text_pos, ent.begin, len); - } + if (text_selected && focused) + pencil.write_selection(text_draw_pos, str_w, ent.begin, len); else - _m_draw_parse_string(parser, is_right_text(ent), text_pos, clr, ent.begin, len); + _m_draw_parse_string(parser, is_right_text(ent), text_draw_pos, clr, ent.begin, len); } - text_pos.x += static_cast(str_w); + text_draw_pos.x += static_cast(str_w); } - if (selected) - graph_.rectangle(::nana::rectangle{ text_pos, { whitespace_w, line_h_pixels } }, true); + + extra_space = text_selected; } else { - auto rtl_string = [this, line_h_pixels, &parser, &clr](point strpos, const wchar_t* str, std::size_t len, std::size_t str_px, unsigned glyph_front, unsigned glyph_selected){ - this->_m_draw_parse_string(parser, true, strpos, clr, str, len); - - //Draw selected part - paint::graphics graph({ glyph_selected, line_h_pixels }); - graph.typeface(this->graph_.typeface()); - graph.rectangle(true, scheme_->selection.get_color()); - - int sel_xpos = static_cast(str_px - (glyph_front + glyph_selected)); - - graph.palette(true, scheme_->selection_text.get_color()); - graph.string({-sel_xpos, 0}, str, len); - graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_h_pixels), graph); - }; - - auto const strbeg = text_ptr->c_str(); - if (a.y == b.y) + for (auto & ent : reordered) { - for (auto & ent : reordered) + const auto len = ent.end - ent.begin; + auto ent_px = graph_.text_extent_size(ent.begin, len).width; + + extra_space = false; + + //Only draw the text which is in the visual rectangle. + if ((text_draw_pos.x + static_cast(ent_px) > text_area_.area.x) && (text_draw_pos.x < text_right)) { - std::size_t len = ent.end - ent.begin; - unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < text_right)) + if (send <= ent.begin || ent.end <= sbegin) { - auto const pos = ent.begin - strbeg + str_pos.x; - const auto str_end = pos + len; - - //NOT selected or seleceted all - if ((str_end <= a.x || pos >= b.x) || (a.x <= pos && str_end <= b.x)) - { - //selected all - if (a.x <= pos && str_end <= b.x) - { - graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(text_pos, ent.begin, len); - } - else - _m_draw_parse_string(parser, false, text_pos, clr, ent.begin, len); - } - else if (pos <= a.x && a.x < str_end) - { //Partial selected - int endpos = static_cast(b.x < str_end ? b.x : str_end); - std::unique_ptr pxbuf_ptr(new unsigned[len]); - unsigned * pxbuf = pxbuf_ptr.get(); - if (graph_.glyph_pixels(ent.begin, len, pxbuf)) - { - auto head_w = std::accumulate(pxbuf, pxbuf + (a.x - pos), unsigned()); - auto sel_w = std::accumulate(pxbuf + (a.x - pos), pxbuf + (endpos - pos), unsigned()); - - graph_.palette(true, clr); - if (is_right_text(ent)) - { //RTL - rtl_string(text_pos, ent.begin, len, str_w, head_w, sel_w); - } - else - { //LTR - _m_draw_parse_string(parser, false, text_pos, clr, ent.begin, a.x - pos); - - auto part_pos = text_pos; - part_pos.x += static_cast(head_w); - - //Draw selected part - graph_.rectangle(::nana::rectangle{ part_pos, { sel_w, line_h_pixels } }, true); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(part_pos, ent.begin + (a.x - pos), endpos - a.x); - - if (static_cast(endpos) < str_end) - { - part_pos.x += static_cast(sel_w); - _m_draw_parse_string(parser, false, part_pos, clr, ent.begin + (endpos - pos), str_end - endpos); - } - } - } - } - else if (pos <= b.x && b.x < str_end) - { //Partial selected - int endpos = b.x; - unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, endpos - pos).width; - - if (is_right_text(ent)) - { //RTL - graph_.palette(true, clr); - rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w); - } - else - { //LTR - //Draw selected part - graph_.rectangle(::nana::rectangle{ text_pos, { sel_w, line_h_pixels } }, true); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(text_pos, ent.begin, endpos - pos); - - _m_draw_parse_string(parser, false, text_pos + ::nana::point(static_cast(sel_w), 0), clr, ent.begin + (endpos - pos), str_end - endpos); - } - } + //this string is not selected + _m_draw_parse_string(parser, false, text_draw_pos, clr, ent.begin, len); } - text_pos.x += static_cast(str_w); - }//end for - } - else if (a.y == str_pos.y) - { - for (auto & ent : reordered) - { - std::size_t len = ent.end - ent.begin; - unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < text_right)) + else if (sbegin <= ent.begin && ent.end <= send) { + //this string is completed selected + pencil.write_selection(text_draw_pos, ent_px, ent.begin, len); + extra_space = true; + } + else + { + //a part of string is selected + + //get the selected range of this string. + auto ent_sbegin = (std::max)(sbegin, ent.begin); + auto ent_send = (std::min)(send, ent.end); + + unsigned select_pos = (ent_sbegin != ent.begin ? ent_sbegin - ent.begin : 0); + unsigned select_len = ent_send - ent_sbegin; + + std::unique_ptr pxbuf{ new unsigned[len] }; + graph_.glyph_pixels(ent.begin, len, pxbuf.get()); + + auto head_px = std::accumulate(pxbuf.get(), pxbuf.get() + select_pos, unsigned{}); + auto select_px = std::accumulate(pxbuf.get() + select_pos, pxbuf.get() + select_pos + select_len, unsigned{}); + graph_.palette(true, clr); - std::size_t pos = ent.begin - strbeg + str_pos.x; - if ((pos + len <= a.x) || (a.x < pos)) //Not selected or selected all - { - if (a.x < pos) - { - //Draw selected all - graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true, static_cast(0x3399FF)); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(text_pos, ent.begin, len); - } - else - _m_draw_parse_string(parser, false, text_pos, clr, ent.begin, len); + if (is_right_text(ent)) + { //RTL + pencil.rtl_string(text_draw_pos, ent.begin, len, ent_px, head_px, select_px); } else - { - unsigned head_w = graph_.glyph_extent_size(ent.begin, len, 0, a.x - pos).width; - if (is_right_text(ent)) - { //RTL - rtl_string(text_pos, ent.begin, len, str_w, head_w, str_w - head_w); - } - else - { //LTR - graph_.string(text_pos, ent.begin, a.x - pos); + { //LTR + _m_draw_parse_string(parser, false, text_draw_pos, clr, ent.begin, select_pos); - ::nana::point part_pos{ text_pos.x + static_cast(head_w), text_pos.y }; + auto part_pos = text_draw_pos; + part_pos.x += static_cast(head_px); - //Draw selected part - graph_.rectangle(::nana::rectangle{ part_pos, {str_w - head_w, line_h_pixels } }, true); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(part_pos, ent.begin + a.x - pos, len - (a.x - pos)); - } - } - } + pencil.write_selection(part_pos, select_px, ent.begin + select_pos, select_len); - text_pos.x += static_cast(str_w); - } - - if (str_pos.y < b.y) - { - if (a.y < str_pos.y || ((a.y == str_pos.y) && (a.x <= str_pos.x ))) - graph_.rectangle(::nana::rectangle{ text_pos, { whitespace_w, line_h_pixels } }, true); - } - } - else if (b.y == str_pos.y) - { - for (auto & ent : reordered) - { - std::size_t len = ent.end - ent.begin; - unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < text_right)) - { - std::size_t pos = ent.begin - strbeg + str_pos.x; - graph_.palette(true, clr); - if (pos + len <= b.x) - { - //Draw selected part - graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(text_pos, ent.begin, len); - } - else if (pos <= b.x && b.x < pos + len) - { - unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, b.x - pos).width; - if (is_right_text(ent)) - { //RTL - rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w); - } - else + if (ent_send < ent.end) { - //draw selected part - graph_.rectangle(::nana::rectangle{ text_pos, { sel_w, line_h_pixels } }, true); - graph_.palette(true, scheme_->selection_text.get_color()); - graph_.string(text_pos, ent.begin, b.x - pos); - - _m_draw_parse_string(parser, false, text_pos + ::nana::point(static_cast(sel_w), 0), clr, ent.begin + b.x - pos, len - (b.x - pos)); + part_pos.x += static_cast(select_px); + _m_draw_parse_string(parser, false, part_pos, clr, ent_send, ent.end - ent_send); } } - else - _m_draw_parse_string(parser, false, text_pos, clr, ent.begin, len); + + extra_space = (select_pos + select_len == text_ptr->size()); } - text_pos.x += static_cast(str_w); } + text_draw_pos.x += static_cast(ent_px); + }//end for + } + + //extra_space is true if the end of line is selected + if (extra_space) + { + //draw the extra space if end of line is not equal to the second selection position. + auto pos = text_coord.x + text_ptr->size(); + if (b.x != pos || text_coord.y != b.y) + { + auto whitespace_w = graph_.text_extent_size(L" ", 1).width; + graph_.rectangle(::nana::rectangle{ text_draw_pos, { whitespace_w, line_h_pixels } }, true); } } } @@ -3483,7 +3447,6 @@ namespace nana{ namespace widgets return static_cast(p - pxbuf.get()) + 1; return static_cast(p - pxbuf.get()); } - pos -= *p; } } From 98483d3e40a494e6982ff652fde060ee94b8d327 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 18 Jul 2016 02:36:18 +0800 Subject: [PATCH 307/309] fix crash in linux because of compiler bug(GCC 4.8) --- source/gui/widgets/skeletons/text_editor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index d989cc83..0fe8e573 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -3158,8 +3158,8 @@ namespace nana{ namespace widgets graph_( graph ), editor_( editor ), parser_( parser ), - selection_fgcolor_{ selection_fgcolor }, - selection_bgcolor_{ selection_bgcolor }, + selection_fgcolor_( selection_fgcolor ), + selection_bgcolor_( selection_bgcolor ), line_px_( editor.line_height() ) {} @@ -3196,6 +3196,7 @@ namespace nana{ namespace widgets void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& text_coord, const std::wstring& text, bool if_mask) const { + point text_draw_pos{ text_area_.area.x - points_.offset.x, top }; const int text_right = text_area_.area.right(); From 7229c768077d5fa71f8ae150154c484a20f800e7 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 18 Jul 2016 04:21:05 +0800 Subject: [PATCH 308/309] fix some compiler errors on x64 --- source/gui/widgets/skeletons/text_editor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 0fe8e573..03168ce1 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -3241,7 +3241,7 @@ namespace nana{ namespace widgets else if ((a.y == b.y) && a.y == text_coord.y) { auto sbegin_pos = (std::max)(a.x, text_coord.x); - auto send_pos = (std::min)(text_coord.x + text_ptr->size(), b.x); + auto send_pos = (std::min)(text_coord.x + static_cast(text_ptr->size()), b.x); if (sbegin_pos < send_pos) { @@ -3265,7 +3265,7 @@ namespace nana{ namespace widgets if (text_coord.x < b.x) { sbegin = text_ptr->c_str(); - send = text_ptr->c_str() + (std::min)(b.x - text_coord.x, text_ptr->size()); + send = text_ptr->c_str() + (std::min)(b.x - text_coord.x, static_cast(text_ptr->size())); } } } @@ -3325,8 +3325,8 @@ namespace nana{ namespace widgets auto ent_sbegin = (std::max)(sbegin, ent.begin); auto ent_send = (std::min)(send, ent.end); - unsigned select_pos = (ent_sbegin != ent.begin ? ent_sbegin - ent.begin : 0); - unsigned select_len = ent_send - ent_sbegin; + unsigned select_pos = static_cast(ent_sbegin != ent.begin ? ent_sbegin - ent.begin : 0); + unsigned select_len = static_cast(ent_send - ent_sbegin); std::unique_ptr pxbuf{ new unsigned[len] }; graph_.glyph_pixels(ent.begin, len, pxbuf.get()); From c5e3fd2ec8ff296ff9a003fb11cc63ffc79143bf Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 19 Jul 2016 23:28:00 +0800 Subject: [PATCH 309/309] update extrlib/readme.txt --- extrlib/readme.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/extrlib/readme.txt b/extrlib/readme.txt index 08aff887..ff52e8a3 100644 --- a/extrlib/readme.txt +++ b/extrlib/readme.txt @@ -1,5 +1,12 @@ You can download the precompiled external libraries at http://sourceforge.net/projects/nanapro/files/extrlib/ Extract the ZIP file to the directory nana/extrlib. Then modify the marco switch defined in nana/include/config.hpp header file and rebuild the nana library. +A method to configure the 3rd party libraries +https://github.com/cnjinhao/nana/wiki/Configuration-of-Third-Party-Libraries-for-Nana + + 您可以下载预先编译的外部程序库,下载地址http://sourceforge.net/projects/nanapro/files/extrlib/ -将ZIP文件释放到nana/extrlib目录。然后修改nana/include/config.hpp文件中对应的标志,重新编译Nana库即可。 \ No newline at end of file +将ZIP文件释放到nana/extrlib目录。然后修改nana/include/config.hpp文件中对应的标志,重新编译Nana库即可。 + +配置第三方库的方法 +https://github.com/cnjinhao/nana/wiki/Configuration-of-Third-Party-Libraries-for-Nana \ No newline at end of file