diff --git a/include/nana/gui.hpp b/include/nana/gui.hpp index af3d99f6..d6677a44 100644 --- a/include/nana/gui.hpp +++ b/include/nana/gui.hpp @@ -18,9 +18,7 @@ #include "gui/compact.hpp" #include "gui/screen.hpp" #include "gui/widgets/form.hpp" -#ifndef NANA_DRAWING_REMOVED #include "gui/drawing.hpp" -#endif #include "gui/msgbox.hpp" #include "gui/place.hpp" diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index c6893049..9c103af9 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -29,8 +29,11 @@ namespace nana struct native_window_handle_impl; struct native_drawable_impl; struct event_handle_impl; + struct drawing_handle_impl; } + using drawing_handle = detail::drawing_handle_impl*; + #ifdef NANA_X11 namespace x11 { diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index 9c8caf94..e3876db9 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -1,7 +1,7 @@ /* * A Drawer Implementation * Nana C++ Library(https://nana.acemind.cn) - * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2024 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -152,14 +152,9 @@ namespace nana void attached(widget&, drawer_trigger&); drawer_trigger* detached(); public: - std::function drawing() const; - void drawing(std::function&&); - -#ifndef NANA_DRAWING_REMOVED void clear(); - void* draw(std::function &&, bool diehard); - void erase(void* diehard); -#endif + drawing_handle drawing(std::function&&, bool diehard) noexcept; + void erase(drawing_handle) noexcept; private: void _m_effect_bground_subsequent(); method_state& _m_mth_state(int pos); diff --git a/include/nana/gui/drawing.hpp b/include/nana/gui/drawing.hpp index 65bca9f0..42708b28 100644 --- a/include/nana/gui/drawing.hpp +++ b/include/nana/gui/drawing.hpp @@ -10,8 +10,6 @@ * @file: nana/gui/drawing.hpp */ -#ifndef NANA_DRAWING_REMOVED - #ifndef NANA_GUI_DRAWING_HPP #define NANA_GUI_DRAWING_HPP @@ -55,5 +53,3 @@ namespace nana #include #endif - -#endif //NANA_DRAWING_REMOVED \ No newline at end of file diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index f4214165..ed3b2f18 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -534,8 +534,8 @@ namespace api /// the specified window is a text editor window, false otherwise. bool keyboard_numeric(window, bool padding); - std::function drawing(window); - void drawing(window, std::function); + drawing_handle drawing(window, std::function) noexcept; + void remove_drawing(window, drawing_handle) noexcept; }//end namespace api namespace API = api; diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index c59a8689..b8591d84 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(https://nana.acemind.cn) - * Copyright(C) 2003-2020 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2024 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -128,8 +128,7 @@ namespace nana operator dummy_bool_type() const; operator window() const; - std::function drawing() const; - void drawing(std::function); + drawing_handle drawing(std::function); protected: std::unique_ptr<::nana::detail::widget_notifier_interface> _m_wdg_notifier(); diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index 799291f2..b0d26394 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -228,11 +228,7 @@ namespace nana drawer_trigger* realizer{ nullptr }; method_state mth_state[event_size]; - std::function draw; - -#ifndef NANA_DRAWING_REMOVED std::vector, bool>*> draws; //Drawing function and flag for clearable -#endif }; drawer::drawer() @@ -241,10 +237,8 @@ namespace nana drawer::~drawer() { -#ifndef NANA_DRAWING_REMOVED for(auto p : data_impl_->draws) delete p; -#endif delete data_impl_; } @@ -422,67 +416,56 @@ namespace nana return nullptr; } - std::function drawer::drawing() const - { - return data_impl_->draw; - } - void drawer::drawing(std::function&& fn) + drawing_handle drawer::drawing(std::function&& fn, bool diehard) noexcept { - data_impl_->draw = std::move(fn); - } -#ifndef NANA_DRAWING_REMOVED - void drawer::clear() - { - for (auto i = data_impl_->draws.cbegin(); i != data_impl_->draws.cend();) + std::pair, bool>* pdw = nullptr; + try { + pdw = new std::pair, bool>(std::move(fn), diehard); + data_impl_->draws.emplace_back(pdw); + return reinterpret_cast(pdw); + } + catch (...) { - if ((*i)->second) - { - delete (*i); - i = data_impl_->draws.erase(i); - } - else - ++i; + delete pdw; + return nullptr; } } - void* drawer::draw(std::function && f, bool diehard) + void drawer::erase(drawing_handle dw) noexcept { - if(f) + for (auto i = data_impl_->draws.cbegin(); i != data_impl_->draws.cend(); ++i) { - auto p = new std::pair, bool>(std::move(f), !diehard); - data_impl_->draws.emplace_back(p); - return p; + if (reinterpret_cast(*i) == dw) + { + delete (*i); + data_impl_->draws.erase(i); + return; + } } - return nullptr; } - void drawer::erase(void * p) + void drawer::clear() { - for (auto i = data_impl_->draws.begin(); i != data_impl_->draws.end(); ++i) + for (auto i = data_impl_->draws.cbegin(); i != data_impl_->draws.cend();) { - if (*i == p) + if (!(*i)->second) { delete (*i); - data_impl_->draws.erase(i); - return; + i = data_impl_->draws.erase(i); } + else + ++i; } } -#endif + void drawer::_m_effect_bground_subsequent() { - if (data_impl_->draw) - data_impl_->draw(graphics); - - auto & effect = data_impl_->window_handle->effect; - -#ifndef NANA_DRAWING_REMOVED for (auto * dw : data_impl_->draws) dw->first(graphics); -#endif + auto& effect = data_impl_->window_handle->effect; if (effect.bground) { if (effect.bground_fade_rate >= 0.01) diff --git a/source/gui/drawing.cpp b/source/gui/drawing.cpp index 836f3147..ba34bd53 100644 --- a/source/gui/drawing.cpp +++ b/source/gui/drawing.cpp @@ -10,7 +10,6 @@ * @file: nana/gui/drawing.cpp */ -#ifndef NANA_DRAWING_REMOVED #include "detail/basic_window.hpp" #include #include @@ -55,42 +54,46 @@ namespace nana void drawing::draw(const draw_fn_t& f) { + internal_scope_guard lock; if(api::empty_window(handle_)) return; - restrict::get_drawer(handle_).draw(draw_fn_t(f), false); + restrict::get_drawer(handle_).drawing(draw_fn_t(f), false); } void drawing::draw(draw_fn_t&& f) { + internal_scope_guard lock; if(api::empty_window(handle_)) return; - restrict::get_drawer(handle_).draw(std::move(f), false); + restrict::get_drawer(handle_).drawing(std::move(f), false); } drawing::diehard_t drawing::draw_diehard(const draw_fn_t& f) { + internal_scope_guard lock; if(api::empty_window(handle_)) return nullptr; - return reinterpret_cast(restrict::get_drawer(handle_).draw(draw_fn_t(f), true)); + return reinterpret_cast(restrict::get_drawer(handle_).drawing(draw_fn_t(f), true)); } drawing::diehard_t drawing::draw_diehard(draw_fn_t&& f) { + internal_scope_guard lock; if(api::empty_window(handle_)) return nullptr; - return reinterpret_cast(restrict::get_drawer(handle_).draw(std::move(f), true)); + return reinterpret_cast(restrict::get_drawer(handle_).drawing(std::move(f), true)); } void drawing::erase(diehard_t d) { + internal_scope_guard lock; //Fixed by Tumiz //https://github.com/cnjinhao/nana/issues/153 if(!api::empty_window(handle_)) - restrict::get_drawer(handle_).erase(d); + restrict::get_drawer(handle_).erase(reinterpret_cast(d)); } void drawing::clear() { + internal_scope_guard lock; if(api::empty_window(handle_)) return; restrict::get_drawer(handle_).clear(); } //end class drawing -}//end namespace nana - -#endif //NANA_DRAWING_REMOVED \ No newline at end of file +}//end namespace nana \ No newline at end of file diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 7330a284..8b42e05e 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -1755,22 +1755,20 @@ namespace api #endif } - std::function drawing(window wd) + drawing_handle drawing(window wd, std::function fn) noexcept { internal_scope_guard lock; if (!is_window(wd)) - return {}; + return nullptr; - return wd->drawer.drawing(); + return wd->drawer.drawing(std::move(fn), false); } - void drawing(window wd, std::function fn) + void remove_drawing(window wd, drawing_handle dw) noexcept { internal_scope_guard lock; - if (!is_window(wd)) - return; - - wd->drawer.drawing(std::move(fn)); + if (is_window(wd)) + wd->drawer.erase(dw); } }//end namespace api }//end namespace nana diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index af8a523d..6ffd2e82 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -293,14 +293,9 @@ namespace nana return handle(); } - std::function widget::drawing() const + drawing_handle widget::drawing(std::function draw_fn) { - return api::drawing(handle()); - } - - void widget::drawing(std::function draw_fn) - { - api::drawing(handle(), std::move(draw_fn)); + return api::drawing(handle(), std::move(draw_fn)); } std::unique_ptr<::nana::detail::widget_notifier_interface> widget::_m_wdg_notifier()