From 74f060acbc6439ea78495bbc280dd2a187d14e06 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Aug 2018 22:57:05 +0800 Subject: [PATCH 1/7] x11_wait_for blocks execution in raspbian --- source/gui/detail/native_window_interface.cpp | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index d6f4b99b..ef0b1935 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -745,6 +745,14 @@ namespace nana{ { nana::detail::platform_scope_guard psg; Display* disp = restrict::spec.open_display(); + + //Returns if the requested visibility is same with the current status. + //In some X-Server versions/implementations, XMapWindow() doesn't generate + //a ConfigureNotify if the requested visibility is same with the current status. + //It causes that x11_wait_for always waiting for the ConfigureNotify. + if(show == is_window_visible(wd)) + return; + if(show) { ::XMapWindow(disp, reinterpret_cast(wd)); @@ -1050,6 +1058,16 @@ namespace nana{ XSizeHints hints; nana::detail::platform_scope_guard psg; + + //Returns if the requested rectangle is same with the current rectangle. + //In some X-Server versions/implementations, XMapWindow() doesn't generate + //a ConfigureNotify if the requested rectangle is same with the current rectangle. + //It causes that x11_wait_for always waiting for the ConfigureNotify. + rectangle current_r; + get_window_rect(wd, current_r); + if(r == current_r) + return true; + ::XGetWMNormalHints(disp, reinterpret_cast(wd), &hints, &supplied); if((hints.flags & (PMinSize | PMaxSize)) && (hints.min_width == hints.max_width) && (hints.min_height == hints.max_height)) { @@ -1239,6 +1257,15 @@ namespace nana{ auto disp = restrict::spec.open_display(); nana::detail::platform_scope_guard psg; + //Returns if the requested size is same with the current size. + //In some X-Server versions/implementations, XMapWindow() doesn't generate + //a ConfigureNotify if the requested size is same with the current size. + //It causes that x11_wait_for always waiting for the ConfigureNotify. + rectangle current_r; + get_window_rect(wd, current_r); + if(current_r.dimension() == sz) + return true; + //Check the XSizeHints for testing whether the window is sizable. XSizeHints hints; long supplied; @@ -1274,6 +1301,9 @@ namespace nana{ unsigned border, depth; nana::detail::platform_scope_guard psg; ::XGetGeometry(restrict::spec.open_display(), reinterpret_cast(wd), &root, &x, &y, &r.width, &r.height, &border, &depth); + + auto pos = window_position(wd); + r.position(pos); #endif } From c440613d9020af5a57cc30010fc9852d7de458af Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 25 Aug 2018 06:06:57 +0800 Subject: [PATCH 2/7] fix crash which occurs after calling widget::tooltip("")(#331) --- include/nana/gui/tooltip.hpp | 2 +- source/gui/tooltip.cpp | 71 ++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/include/nana/gui/tooltip.hpp b/include/nana/gui/tooltip.hpp index e724d19b..89ec2c1a 100644 --- a/include/nana/gui/tooltip.hpp +++ b/include/nana/gui/tooltip.hpp @@ -1,6 +1,6 @@ /* * A Tooltip Implementation - * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2018 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/tooltip.cpp b/source/gui/tooltip.cpp index 862a2720..34692036 100644 --- a/source/gui/tooltip.cpp +++ b/source/gui/tooltip.cpp @@ -1,7 +1,7 @@ /* * A Tooltip Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -15,6 +15,7 @@ #include #include #include +#include namespace nana { @@ -157,7 +158,14 @@ namespace nana class controller { - typedef std::pair pair_t; + struct tip_value + { + std::string text; + event_handle evt_msenter; + event_handle evt_msleave; + event_handle evt_msdown; + event_handle evt_destroy; + }; typedef std::function deleter_type; @@ -207,7 +215,7 @@ namespace nana if (str.empty()) _m_untip(wd); else - _m_get(wd).second = str; + _m_get(wd).text = str; } void show(const std::string& text, const point* pos, std::size_t duration) @@ -236,35 +244,35 @@ namespace nana window_.reset(); //Destroy the tooltip controller when there are not tooltips. - if (cont_.empty()) + if (table_.empty()) instance(true); } private: void _m_untip(window wd) { - for (auto i = cont_.begin(); i != cont_.end(); ++i) + auto i = table_.find(wd); + if(i != table_.end()) { - if (i->first == wd) - { - cont_.erase(i); + API::umake_event(i->second.evt_msdown); + API::umake_event(i->second.evt_msenter); + API::umake_event(i->second.evt_msleave); + API::umake_event(i->second.evt_destroy); - if (cont_.empty()) - { - window_.reset(); - instance(true); - } - return; - } + table_.erase(i); + } + + if (table_.empty()) + { + window_.reset(); + instance(true); } } private: - pair_t& _m_get(window wd) + tip_value& _m_get(window wd) { - for (auto & pr : cont_) - { - if (pr.first == wd) - return pr; - } + auto i = table_.find(wd); + if (i != table_.end()) + return i->second; auto & events = API::events(wd); @@ -272,28 +280,29 @@ namespace nana { if (event_code::mouse_enter == arg.evt_code) { - auto & pr = _m_get(arg.window_handle); - if (pr.second.size()) - this->show(pr.second, nullptr, 0); + auto & value = _m_get(arg.window_handle); + if (value.text.size()) + this->show(value.text, nullptr, 0); } else this->close(); }; - events.mouse_enter.connect(mouse_fn); - events.mouse_leave.connect(mouse_fn); - events.mouse_down.connect(mouse_fn); + auto & value = table_[wd]; - events.destroy.connect([this](const arg_destroy& arg){ + value.evt_msenter = events.mouse_enter.connect(mouse_fn); + value.evt_msleave = events.mouse_leave.connect(mouse_fn); + value.evt_msdown = events.mouse_down.connect(mouse_fn); + + value.evt_destroy = events.destroy.connect([this](const arg_destroy& arg){ _m_untip(arg.window_handle); }); - cont_.emplace_back(wd, std::string()); - return cont_.back(); + return value; } private: std::unique_ptr window_; - std::vector cont_; + std::map table_; }; }//namespace tooltip }//namespace drawerbase From e0ba1c7d8a5d064e4e096a3600d4f9e831995184 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 25 Aug 2018 06:34:43 +0800 Subject: [PATCH 3/7] disallows copying text from a masked text-editor. --- source/gui/widgets/skeletons/text_editor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 16963195..a2f81c39 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -2086,6 +2086,10 @@ namespace nana{ namespace widgets void text_editor::copy() const { + //Stops copying text if the text_editor is masked. + if (mask_char_) + return; + auto text = _m_make_select_string(); if (!text.empty()) nana::system::dataexch().set(text, API::root(this->window_)); From e8e7ad543c17968490c33374228b0114fdfe33af Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sat, 25 Aug 2018 06:53:11 +0800 Subject: [PATCH 4/7] the default pool thread number is thread hw concurrency --- include/nana/threads/pool.hpp | 13 ++++++++++--- source/gui/widgets/skeletons/text_editor.cpp | 2 +- source/threads/pool.cpp | 16 +++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/nana/threads/pool.hpp b/include/nana/threads/pool.hpp index 38d9952e..1234bcb2 100644 --- a/include/nana/threads/pool.hpp +++ b/include/nana/threads/pool.hpp @@ -1,6 +1,6 @@ /* * A Thread Pool Implementation - * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -13,10 +13,14 @@ #ifndef NANA_THREADS_POOL_HPP #define NANA_THREADS_POOL_HPP +#include #include #include #include +#ifndef STD_THREAD_NOT_SUPPORTED +# include +#endif namespace nana{ /// Some mutex classes for synchronizing. @@ -58,9 +62,12 @@ namespace threads pool(const pool&) = delete; pool& operator=(const pool&) = delete; public: - pool(); ///< Creates a group of threads. +#ifndef STD_THREAD_NOT_SUPPORTED + pool(unsigned thread_number = std::thread::hardware_concurrency()); ///< Creates a group of threads. +#else + pool(unsigned thread_number = 0); +#endif pool(pool&&); - pool(std::size_t thread_number); ///< Creates a number of threads specifed by thread_number. ~pool(); ///< waits for the all running tasks till they are finished and skips all the queued tasks. pool& operator=(pool&&); diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index a2f81c39..e04c4ab8 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -2086,7 +2086,7 @@ namespace nana{ namespace widgets void text_editor::copy() const { - //Stops copying text if the text_editor is masked. + //Disallows copying text if the text_editor is masked. if (mask_char_) return; diff --git a/source/threads/pool.cpp b/source/threads/pool.cpp index e83498b0..d4b3af2f 100644 --- a/source/threads/pool.cpp +++ b/source/threads/pool.cpp @@ -351,10 +351,17 @@ namespace threads }container_; };//end class impl - pool::pool() - : impl_(new impl(4)) +#ifndef STD_THREAD_NOT_SUPPORTED + pool::pool(unsigned thread_number) + : impl_(new impl(thread_number ? thread_number : std::thread::hardware_concurrency())) { } +#else + pool::pool(unsigned thread_number) + : impl_(new impl(0)) + { + } +#endif pool::pool(pool&& other) : pool() @@ -362,11 +369,6 @@ namespace threads std::swap(impl_, other.impl_); } - pool::pool(std::size_t thread_number) - : impl_(new impl(thread_number)) - { - } - pool& pool::operator=(pool&& other) { if(this != &other) From e1992fb0d48abf35cd12d0454ff78d289a7e65a6 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 26 Aug 2018 16:42:53 +0800 Subject: [PATCH 5/7] fix crash when drawing in text_changed event with new line inserted(#332) --- .../gui/widgets/skeletons/text_editor.hpp | 10 +- .../nana/gui/widgets/skeletons/textbase.hpp | 52 ++++++---- source/gui/widgets/skeletons/text_editor.cpp | 98 ++++++++++++------- source/gui/widgets/textbox.cpp | 4 +- 4 files changed, 101 insertions(+), 63 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index d3536182..dd24d365 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -191,14 +191,14 @@ namespace nana{ namespace widgets void draw_corner(); void render(bool focused); public: - void put(std::wstring); + void put(std::wstring, bool perform_event); void put(wchar_t); void copy() const; void cut(); void paste(); - void enter(bool record_undo = true); + void enter(bool record_undo, bool perform_event); void del(); - void backspace(bool record_undo = true); + void backspace(bool record_undo, bool perform_event); void undo(bool reverse); void set_undo_queue_length(std::size_t len); void move_ns(bool to_north); //Moves up and down @@ -243,9 +243,9 @@ namespace nana{ namespace widgets void _m_reset(); //Inserts text at position where the caret is - ::nana::upoint _m_put(::std::wstring); + ::nana::upoint _m_put(::std::wstring, bool perform_event); - ::nana::upoint _m_erase_select(); + ::nana::upoint _m_erase_select(bool perform_event); ::std::wstring _m_make_select_string() const; static bool _m_resolve_text(const ::std::wstring&, std::vector> & lines); diff --git a/include/nana/gui/widgets/skeletons/textbase.hpp b/include/nana/gui/widgets/skeletons/textbase.hpp index 751d9888..d11bc872 100644 --- a/include/nana/gui/widgets/skeletons/textbase.hpp +++ b/include/nana/gui/widgets/skeletons/textbase.hpp @@ -1,7 +1,7 @@ /* * A textbase class implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -301,6 +301,29 @@ namespace skeletons } } + //Triggers the text_changed event. + //It is exposed for outter classes. For a outter class(eg. text_editor), a changing text content operation + //may contains multiple textbase operations, therefore, the outter class determines when an event should be triggered. + // + //Addtional, using text_changed() method, it is possible to allow a outter class performing some updating operations + //before triggering text_changed event. + void text_changed() + { + if (!changed_) + { + _m_first_change(); + changed_ = true; + } + + if (edited_) + { + if (evt_agent_) + evt_agent_->text_changed(); + + edited_ = false; + } + } + size_type lines() const { return text_cont_.size(); @@ -330,7 +353,7 @@ namespace skeletons _m_at(pos).swap(text); _m_make_max(pos); - _m_edited(); + edited_ = true; } void insert(upoint pos, string_type && str) @@ -351,7 +374,7 @@ namespace skeletons } _m_make_max(pos.y); - _m_edited(); + edited_ = true; } void insertln(size_type pos, string_type&& str) @@ -362,7 +385,7 @@ namespace skeletons text_cont_.emplace_back(new string_type(std::move(str))); _m_make_max(pos); - _m_edited(); + edited_ = true; } void erase(size_type line, size_type pos, size_type count) @@ -378,7 +401,7 @@ namespace skeletons if (attr_max_.line == line) _m_scan_for_max(); - _m_edited(); + edited_ = true; } } @@ -398,7 +421,7 @@ namespace skeletons else if (pos < attr_max_.line) attr_max_.line -= n; - _m_edited(); + edited_ = true; return true; } @@ -426,7 +449,7 @@ namespace skeletons if(pos < attr_max_.line) --attr_max_.line; - _m_edited(); + edited_ = true; } } @@ -514,23 +537,12 @@ namespace skeletons changed_ = false; } - - void _m_edited() - { - if(!changed_) - { - _m_first_change(); - changed_ = true; - } - - if (evt_agent_) - evt_agent_->text_changed(); - } private: std::deque> text_cont_; textbase_event_agent_interface* evt_agent_{ nullptr }; - mutable bool changed_{ false }; + mutable bool changed_{ false }; + mutable bool edited_{ false }; mutable std::string filename_; //A string for the saved filename. const string_type nullstr_; diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index e04c4ab8..0510acd9 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -199,7 +199,7 @@ namespace nana{ namespace widgets { editor_.select_.a = sel_a_; editor_.select_.b = sel_b_; - editor_._m_erase_select(); + editor_._m_erase_select(false); editor_.select_.a = editor_.select_.b; editor_.points_.caret = sel_a_; } @@ -208,7 +208,7 @@ namespace nana{ namespace widgets if (is_enter) { editor_.points_.caret = nana::upoint(0, pos_.y + 1); - editor_.backspace(false); + editor_.backspace(false, false); } else editor_.textbase().erase(pos_.y, pos_.x, selected_text_.size()); @@ -218,11 +218,11 @@ namespace nana{ namespace widgets { if (is_enter) { - editor_.enter(false); + editor_.enter(false, false); } else { - editor_._m_put(selected_text_); + editor_._m_put(selected_text_, false); if (sel_a_ != sel_b_) { editor_.select_.a = sel_a_; @@ -234,6 +234,8 @@ namespace nana{ namespace widgets } } + editor_.textbase().text_changed(); + editor_.reset_caret(); } }; @@ -258,7 +260,7 @@ namespace nana{ namespace widgets { if (is_enter) { - editor_.enter(false); + editor_.enter(false, false); } else { @@ -266,9 +268,9 @@ namespace nana{ namespace widgets { editor_.select_.a = sel_a_; editor_.select_.b = sel_b_; - editor_._m_erase_select(); + editor_._m_erase_select(false); } - editor_.points_.caret = editor_._m_put(text_); //redo + editor_.points_.caret = editor_._m_put(text_, false); //redo } } else @@ -277,7 +279,7 @@ namespace nana{ namespace widgets { editor_.points_.caret.x = 0; ++editor_.points_.caret.y; - editor_.backspace(false); + editor_.backspace(false, false); } else { @@ -286,7 +288,7 @@ namespace nana{ namespace widgets { editor_.select_.a = pos_; editor_.select_.b = upoint(static_cast(lines.back().second - lines.back().first), static_cast(pos_.y + lines.size() - 1)); - editor_.backspace(false); + editor_.backspace(false, false); editor_.select_.a = editor_.select_.b; } else @@ -296,12 +298,14 @@ namespace nana{ namespace widgets if (!selected_text_.empty()) { editor_.points_.caret = (std::min)(sel_a_, sel_b_); - editor_._m_put(selected_text_); + editor_._m_put(selected_text_, false); editor_.points_.caret = sel_b_; editor_.select_.a = sel_a_; //Reset the selected text editor_.select_.b = sel_b_; } } + + editor_.textbase().text_changed(); editor_.reset_caret(); } private: @@ -333,8 +337,8 @@ namespace nana{ namespace widgets const auto text = editor_._m_make_select_string(); - editor_._m_erase_select(); - editor_._m_put(text); + editor_._m_erase_select(false); + editor_._m_put(text, false); editor_.select_.a = sel_a_; editor_.select_.b = sel_b_; @@ -342,6 +346,7 @@ namespace nana{ namespace widgets editor_.points_.caret = sel_b_; editor_.reset_caret(); } + editor_.textbase().text_changed(); } void set_destination(const nana::upoint& dest_a, const nana::upoint& dest_b) @@ -1192,9 +1197,9 @@ namespace nana{ namespace widgets switch (key) { case '\b': - backspace(); break; + backspace(true, true); break; case '\n': case '\r': - enter(); break; + enter(true, true); break; case keyboard::sync_idel: paste(); break; case keyboard::tab: @@ -1681,7 +1686,7 @@ namespace nana{ namespace widgets auto undo_ptr = std::unique_ptr{ new undo_input_text(*this, str) }; undo_ptr->set_caret_pos(); - _m_put(std::move(str)); + _m_put(std::move(str), false); impl_->undo.push(std::move(undo_ptr)); @@ -1698,7 +1703,9 @@ namespace nana{ namespace widgets } } else - put(std::move(str)); + put(std::move(str), false); + + textbase().text_changed(); } std::wstring text_editor::text() const @@ -1904,6 +1911,7 @@ namespace nana{ namespace widgets if (_m_move_select(true)) { + textbase().text_changed(); this->_m_adjust_view(); impl_->try_refresh = sync_graph::refresh; return true; @@ -2021,7 +2029,7 @@ namespace nana{ namespace widgets impl_->try_refresh = sync_graph::none; } //public: - void text_editor::put(std::wstring text) + void text_editor::put(std::wstring text, bool perform_event) { if (text.empty()) return; @@ -2032,14 +2040,16 @@ namespace nana{ namespace widgets //Do not forget to assign the _m_erase_select() to caret //because _m_put() will insert the text at the position where the caret is. - points_.caret = _m_erase_select(); + points_.caret = _m_erase_select(false); undo_ptr->set_caret_pos(); - points_.caret = _m_put(std::move(text)); + points_.caret = _m_put(std::move(text), false); impl_->undo.push(std::move(undo_ptr)); _m_reset_content_size(true); + if (perform_event) + textbase().text_changed(); if(graph_) { @@ -2060,7 +2070,7 @@ namespace nana{ namespace widgets undo_ptr->set_selected_text(); if(refresh) - points_.caret = _m_erase_select(); + points_.caret = _m_erase_select(false); undo_ptr->set_caret_pos(); @@ -2070,6 +2080,8 @@ namespace nana{ namespace widgets textbase().insert(points_.caret, std::move(ch_str)); _m_pre_calc_lines(points_.caret.y, 1); + textbase().text_changed(); + points_.caret.x ++; _m_reset_content_size(); @@ -2107,7 +2119,7 @@ namespace nana{ namespace widgets if ((accepts::no_restrict == impl_->capacities.acceptive) || !impl_->capacities.pred_acceptive) { - put(move(text)); + put(move(text), true); return; } @@ -2125,13 +2137,13 @@ namespace nana{ namespace widgets if (accepts::no_restrict != impl_->capacities.acceptive) { text.erase(i, text.end()); - put(move(text)); + put(move(text), true); } break; } } - void text_editor::enter(bool record_undo) + void text_editor::enter(bool record_undo, bool perform_event) { if(false == attributes_.multi_lines) return; @@ -2139,7 +2151,7 @@ namespace nana{ namespace widgets auto undo_ptr = std::unique_ptr(new undo_input_text(*this, std::wstring(1, '\n'))); undo_ptr->set_selected_text(); - points_.caret = _m_erase_select(); + points_.caret = _m_erase_select(false); undo_ptr->set_caret_pos(); @@ -2177,21 +2189,24 @@ namespace nana{ namespace widgets { if (impl_->indent.generator) { - put(to_wstring(impl_->indent.generator())); + put(nana::to_wstring(impl_->indent.generator()), false); } 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) - put(text.substr(0, indent_pos)); + put(text.substr(0, indent_pos), false); else - put(text); + put(text, false); } } else _m_reset_content_size(); + if (perform_event) + textbase.text_changed(); + auto origin_moved = impl_->cview->move_origin(origin - impl_->cview->origin()); if (this->_m_adjust_view() || origin_moved) @@ -2215,10 +2230,10 @@ namespace nana{ namespace widgets return; //No characters behind the caret } - backspace(); + backspace(true, true); } - void text_editor::backspace(bool record_undo) + void text_editor::backspace(bool record_undo, bool perform_event) { auto undo_ptr = std::unique_ptr(new undo_backspace(*this)); bool has_to_redraw = true; @@ -2258,7 +2273,7 @@ namespace nana{ namespace widgets else { undo_ptr->set_selected_text(); - points_.caret = _m_erase_select(); + points_.caret = _m_erase_select(false); undo_ptr->set_caret_pos(); } @@ -2267,6 +2282,11 @@ namespace nana{ namespace widgets _m_reset_content_size(false); + if (perform_event) + textbase().text_changed(); + + textbase().text_changed(); + if(has_to_redraw) { this->_m_adjust_view(); @@ -2960,7 +2980,7 @@ namespace nana{ namespace widgets select_.a = select_.b; } - nana::upoint text_editor::_m_put(std::wstring text) + nana::upoint text_editor::_m_put(std::wstring text, bool perform_event) { auto & textbase = this->textbase(); auto crtpos = points_.caret; @@ -3002,10 +3022,13 @@ namespace nana{ namespace widgets _m_pre_calc_lines(crtpos.y, 1); } + if (perform_event) + textbase.text_changed(); + return crtpos; } - nana::upoint text_editor::_m_erase_select() + nana::upoint text_editor::_m_erase_select(bool perform_event) { nana::upoint a, b; if (get_selected_points(a, b)) @@ -3027,6 +3050,9 @@ namespace nana{ namespace widgets _m_pre_calc_lines(a.y, 1); } + if (perform_event) + textbase.text_changed(); + select_.a = select_.b; return a; } @@ -3239,8 +3265,8 @@ namespace nana{ namespace widgets {//forward undo_ptr->set_caret_pos(); - _m_erase_select(); - _m_put(text); + _m_erase_select(false); + _m_put(text, false); select_.a = caret; select_.b.y = b.y + (caret.y - a.y); @@ -3249,8 +3275,8 @@ namespace nana{ namespace widgets { undo_ptr->set_caret_pos(); - _m_put(text); - _m_erase_select(); + _m_put(text, false); + _m_erase_select(false); select_.b.y = caret.y; select_.a.y = caret.y - (b.y - a.y); diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index db57ae82..6697e567 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -428,7 +428,7 @@ namespace drawerbase { if(at_caret == false) editor->move_caret_end(false); - editor->put(to_wstring(text)); + editor->put(to_wstring(text), true); editor->try_refresh(); API::update_window(this->handle()); @@ -445,7 +445,7 @@ namespace drawerbase { if(at_caret == false) editor->move_caret_end(false); - editor->put(text); + editor->put(text, true); editor->try_refresh(); API::update_window(this->handle()); From fe185e382b3b859c1ecc002e3a861ad0882ab01b Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 26 Aug 2018 17:45:24 +0800 Subject: [PATCH 6/7] remove deprecated code --- include/nana/gui/widgets/listbox.hpp | 2 - .../widgets/skeletons/text_token_stream.hpp | 7 - source/detail/platform_spec_posix.cpp | 33 -- source/gui/detail/bedrock_posix.cpp | 51 --- source/gui/programming_interface.cpp | 12 - source/gui/widgets/label.cpp | 388 ------------------ 6 files changed, 493 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index d3bb5bd8..473ba9b9 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -809,7 +809,6 @@ namespace nana /// operate with absolute positions and contain only the position but montain pointers to parts of the real items /// item_proxy self, it references and iterators are not invalidated by sort() class item_proxy - //: public std::iterator //deprecated : public ::nana::widgets::detail::widget_iterator { public: @@ -984,7 +983,6 @@ namespace nana }; class cat_proxy - //: public std::iterator //deprecated : public ::nana::widgets::detail::widget_iterator { public: diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index 52c33b70..f94dfea8 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -96,13 +96,6 @@ namespace nana{ namespace widgets{ namespace skeletons return std::stoi(idstr_, nullptr, 0); } private: - /* - static bool _m_unicode_word_breakable(wchar_t ch) //deprecated - { - return ((0x4E00 <= ch) && (ch <= 0x9FFF)); - } - */ - static bool _m_unicode_word_breakable(const wchar_t* ch) noexcept { if (*ch) diff --git a/source/detail/platform_spec_posix.cpp b/source/detail/platform_spec_posix.cpp index 1a58ec6c..bf3ab2fb 100644 --- a/source/detail/platform_spec_posix.cpp +++ b/source/detail/platform_spec_posix.cpp @@ -656,38 +656,6 @@ namespace detail msg_dispatcher_->erase(reinterpret_cast(wd)); platform_scope_guard lock; -#if 0 - auto i = wincontext_.find(wd); - if(i == wincontext_.end()) return; - - if(i->second.owner) - { - auto u = wincontext_.find(i->second.owner); - if(u != wincontext_.end()) - { - auto * vec = u->second.owned; - if(vec) - { - auto j = std::find(vec->begin(), vec->end(), i->first); - if(j != vec->end()) - vec->erase(j); - } - } - } - - auto * vec = i->second.owned; - if(vec) - { - set_error_handler(); - auto & wd_manager = detail::bedrock::instance().wd_manager(); - for(auto u = vec->rbegin(); u != vec->rend(); ++u) - wd_manager.close(wd_manager.root(*u)); - - rev_error_handler(); - } - delete vec; - wincontext_.erase(i); -#else if(umake_owner(wd)) { auto i = wincontext_.find(wd); @@ -708,7 +676,6 @@ namespace detail wincontext_.erase(i); } } -#endif iconbase_.erase(wd); } diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index debbbfee..62738e98 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -1133,62 +1133,11 @@ namespace detail wd_manager.do_lazy_refresh(msgwnd, false); break; } -#if 0 - //Fall through - case XLookupChars: - if (msgwnd->flags.enabled) - { - const wchar_t* charbuf; - - nana::detail::charset_conv charset(NANA_UNICODE, "UTF-8"); - const std::string& str = charset.charset(std::string(keybuf, keybuf + len)); - charbuf = reinterpret_cast(str.c_str()); - len = str.size() / sizeof(wchar_t); - - for(int i = 0; i < len; ++i) - { - arg_keyboard arg = modifiers_status; - arg.ignore = false; - arg.key = charbuf[i]; - - // ignore Unicode BOM (it may or may not appear) - if (arg.key == 0xFEFF) continue; - - //Only accept tab when it is not ignored. - if ((keyboard::tab == arg.key) && root_runtime->condition.ignore_tab) - continue; - - if(context.is_alt_pressed) - { - arg.ctrl = arg.shift = false; - arg.evt_code = event_code::shortkey; - brock.shortkey_occurred(true); - auto shr_wd = wd_manager.find_shortkey(native_window, arg.key); - if(shr_wd) - { - arg.window_handle = reinterpret_cast(shr_wd); - brock.emit(event_code::shortkey, shr_wd, arg, true, &context); - } - continue; - } - arg.evt_code = event_code::key_char; - arg.window_handle = 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); - } - - if(brock.shortkey_occurred(false)) - context.is_alt_pressed = false; - } - break; -#else x_lookup_chars(root_runtime, msgwnd, keybuf, len, modifiers_status); break; case XLookupChars: x_lookup_chars(root_runtime, msgwnd, keybuf, len, modifiers_status); break; -#endif } wd_manager.do_lazy_refresh(msgwnd, false); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 30f33e9a..698aa543 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -835,17 +835,6 @@ namespace API size inner_size = sz; -#if 0 - if (inner_size.width < iwd->extra_width) - inner_size.width = 0; - else - inner_size.width -= iwd->extra_width; - - if (inner_size.height < iwd->extra_height) - inner_size.height = 0; - else - inner_size.height -= iwd->extra_height; -#else if (inner_size.width < static_cast(fm_extents.left + fm_extents.right)) inner_size.width = 0; else @@ -855,7 +844,6 @@ namespace API inner_size.height = 0; else inner_size.height -= static_cast(fm_extents.top + fm_extents.bottom); -#endif window_size(wd, inner_size); } diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index 65b72c81..53ab80ae 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -20,8 +20,6 @@ #include #include -#define VISUAL_LINES - namespace nana { namespace drawerbase @@ -30,17 +28,6 @@ namespace nana { class renderer { -#ifndef VISUAL_LINES - typedef widgets::skeletons::dstream::linecontainer::iterator iterator; - - struct pixel_tag - { - int x_base; //The x position where this line starts. - std::size_t pixels; - std::size_t baseline; //The baseline for drawing text. - std::vector values; //line values - }; -#else //Iterator of content element in a line. using content_element_iterator = widgets::skeletons::dstream::linecontainer::const_iterator; //subsitute for member type iterator @@ -65,8 +52,6 @@ namespace nana std::vector elements; //description of text element in this rendering line. }; -#endif - //this is a helper variable, it just keeps the status while drawing. struct render_status { @@ -75,11 +60,7 @@ namespace nana align_v text_align_v; nana::point pos; -#ifndef VISUAL_LINES - std::vector pixels; -#else std::vector vslines; //The lines description of a line of text. substitute of member pixels. -#endif std::size_t index; //indicates the current rendering visual line. }; @@ -135,32 +116,19 @@ namespace nana rs.text_align = th; rs.text_align_v = tv; -#ifndef VISUAL_LINES - std::deque > pixel_lines; -#else //All visual lines data of whole text. std::deque> content_lines; -#endif std::size_t extent_v_pixels = 0; //the pixels, in height, that text will be painted. for (auto & line : dstream_) { -#ifndef VISUAL_LINES - _m_line_pixels(line, def_line_pixels, rs); - - for (auto & m : rs.pixels) - extent_v_pixels += m.pixels; - - pixel_lines.emplace_back(std::move(rs.pixels)); -#else _m_prepare_visual_lines(graph, line, def_line_pixels, rs); for (auto & vsline : rs.vslines) extent_v_pixels += vsline.extent_height_px; content_lines.emplace_back(std::move(rs.vslines)); -#endif if(extent_v_pixels >= graph.height()) break; @@ -176,30 +144,12 @@ namespace nana else rs.pos.y = 0; -#ifndef VISUAL_LINES - auto pixels_iterator = pixel_lines.begin(); -#else auto vsline_iterator = content_lines.begin(); -#endif for (auto & line : dstream_) { if (rs.pos.y >= static_cast(graph.height())) break; -#ifndef VISUAL_LINES - rs.index = 0; - rs.pixels.clear(); - - rs.pixels.swap(*pixels_iterator++); - - rs.pos.x = rs.pixels.front().x_base; - - //Stop drawing when it goes out of range. - if(false == _m_each_line(graph, line, rs)) - break; - - rs.pos.y += static_cast(rs.pixels.back().pixels); -#else rs.index = 0; rs.vslines.clear(); rs.vslines.swap(*vsline_iterator++); @@ -209,7 +159,6 @@ namespace nana break; rs.pos.y += static_cast(rs.vslines.back().extent_height_px); -#endif } graph.typeface(pre_font); @@ -256,13 +205,8 @@ namespace nana for(auto & line: dstream_) { -#ifndef VISUAL_LINES - rs.pixels.clear(); - unsigned w = _m_line_pixels(line, def_line_pixels, rs); -#else rs.vslines.clear(); auto w = _m_prepare_visual_lines(graph, line, def_line_pixels, rs); -#endif if(limited && (w > limited)) w = limited; @@ -270,13 +214,8 @@ namespace nana if(retsize.width < w) retsize.width = w; -#ifndef VISUAL_LINES - for (auto & px : rs.pixels) - retsize.height += static_cast(px.pixels); -#else for (auto& vsline : rs.vslines) retsize.height += static_cast(vsline.extent_height_px); -#endif } return retsize; @@ -387,23 +326,6 @@ namespace nana } } -#ifndef VISUAL_LINES - void _m_align_x_base(const render_status& rs, pixel_tag & px, unsigned w) noexcept - { - switch(rs.text_align) - { - case align::left: - px.x_base = 0; - break; - case align::center: - px.x_base = (static_cast(rs.allowed_width - w) >> 1); - break; - case align::right: - px.x_base = static_cast(rs.allowed_width - w); - break; - } - } -#else void _m_prepare_x(const render_status& rs, visual_line & vsline, unsigned w) noexcept { switch (rs.text_align) @@ -419,9 +341,6 @@ namespace nana break; } } -#endif - -#ifdef VISUAL_LINES /** * prepare data for rendering a line of text. @@ -605,180 +524,7 @@ namespace nana } return text.size(); } -#else - unsigned _m_line_pixels(dstream::linecontainer& line, unsigned def_line_pixels, render_status & rs) - { - if (line.empty()) - { - pixel_tag px; - px.baseline = 0; - px.pixels = def_line_pixels; - px.x_base = 0; - rs.pixels.emplace_back(px); - - return 0; - } - - unsigned total_w = 0; - unsigned w = 0; - unsigned max_ascent = 0; - unsigned max_descent = 0; - unsigned max_px = 0; - - //Bidi reorder is requried here - - std::vector line_values; - - for(auto i = line.begin(); i != line.end(); ++i) - { - data * data_ptr = i->data_ptr; - nana::size sz = data_ptr->size(); - total_w += sz.width; - - unsigned as = 0; //ascent - unsigned ds = 0; //descent - - if(fblock::aligns::baseline == i->fblock_ptr->text_align) - { - as = static_cast(data_ptr->ascent()); - ds = static_cast(sz.height - as); - - if(max_descent < ds) - max_descent = ds; - - if((false == data_ptr->is_text()) && (sz.height < max_ascent + max_descent)) - sz.height = max_ascent + max_descent; - } - - //Check if the content is displayed in a new line. - if((0 == rs.allowed_width) || (w + sz.width <= rs.allowed_width)) - { - w += sz.width; - - if(max_ascent < as) max_ascent = as; - if(max_descent < ds) max_descent = ds; - if(max_px < sz.height) max_px = sz.height; - line_values.emplace_back(i); - } - else - { - pixel_tag px; - _m_align_x_base(rs, px, (w ? w : sz.width)); - - if(w) - { - if(max_ascent + max_descent > max_px) - max_px = max_descent + max_ascent; - else - max_ascent = max_px - max_descent; - - px.pixels = max_px; - px.baseline = max_ascent; - px.values.swap(line_values); - - w = sz.width; - max_px = sz.height; - max_ascent = as; - max_descent = ds; - line_values.emplace_back(i); - } - else - { - px.pixels = sz.height; - px.baseline = as; - - px.values.emplace_back(i); - - max_px = 0; - max_ascent = max_descent = 0; - } - - rs.pixels.emplace_back(px); - } - } - - if (max_px) - { - pixel_tag px; - - _m_align_x_base(rs, px, w); - - if (max_ascent + max_descent > max_px) - max_px = max_descent + max_ascent; - else - max_ascent = max_px - max_descent; - - px.pixels = max_px; - px.baseline = max_ascent; - px.values.swap(line_values); - rs.pixels.emplace_back(px); - } - return total_w; - } -#endif - -#ifndef VISUAL_LINES - bool _m_each_line(graph_reference graph, dstream::linecontainer&, render_status& rs) - { - std::wstring text; - iterator block_start; - - const int lastpos = static_cast(graph.height()) - 1; - - for(auto & px : rs.pixels) - { - for(auto & render_iterator: px.values) - { - auto & value = *render_iterator; - if (value.data_ptr->is_text()) - { - //hold the block while the text is empty, - //it stands for the first block - if (text.empty()) - block_start = render_iterator; - - text += value.data_ptr->text(); - continue; - } - - if(text.size()) - { - _m_draw_block(graph, text, block_start, rs); - if(lastpos <= rs.pos.y) - return false; - text.clear(); - } - nana::size sz = value.data_ptr->size(); - - pixel_tag px = rs.pixels[rs.index]; - if ((rs.allowed_width < rs.pos.x + sz.width) && (rs.pos.x != px.x_base)) - { - //Change a line. - rs.pos.y += static_cast(px.pixels); - px = rs.pixels[++rs.index]; - rs.pos.x = px.x_base; - } - - int y = rs.pos.y + _m_text_top(px, value.fblock_ptr, value.data_ptr); - - value.data_ptr->nontext_render(graph, rs.pos.x, y); - _m_insert_if_traceable(rs.pos.x, y, sz, value.fblock_ptr); - rs.pos.x += static_cast(sz.width); - - if(lastpos < y) - return false; - } - - if(text.size()) - { - _m_draw_block(graph, text, block_start, rs); - text.clear(); - } - } - return (rs.pos.y <= lastpos); - } -#else bool _m_foreach_visual_line(graph_reference graph, render_status& rs) { std::wstring text; @@ -804,20 +550,7 @@ namespace nana return (rs.pos.y <= bottom); } -#endif - -#if 0 //deprecated - static bool _m_overline(const render_status& rs, int right, bool equal_required) noexcept - { - if(align::left == rs.text_align) - return (equal_required ? right >= static_cast(rs.allowed_width) : right > static_cast(rs.allowed_width)); - - return (equal_required ? rs.pixels[rs.index].x_base <= 0 : rs.pixels[rs.index].x_base < 0); - } -#endif - -#ifdef VISUAL_LINES static int _m_vsline_element_top(const visual_line& vsline, fblock* fblock_ptr, const data* data_ptr) noexcept { switch (fblock_ptr->text_align) @@ -832,24 +565,7 @@ namespace nana } return 0; } -#else - static int _m_text_top(const pixel_tag& px, fblock* fblock_ptr, const data* data_ptr) - { - switch(fblock_ptr->text_align) - { - case fblock::aligns::center: - return static_cast(px.pixels - data_ptr->size().height) / 2; - case fblock::aligns::bottom: - return static_cast(px.pixels - data_ptr->size().height); - case fblock::aligns::baseline: - return static_cast(px.baseline - (data_ptr->is_text() ? data_ptr->ascent() : data_ptr->size().height)); - default: break; - } - return 0; - } -#endif -#ifdef VISUAL_LINES void _m_draw_vsline_element(graph_reference graph, const visual_line::element& vsline_elm, render_status& rs) { auto data = vsline_elm.content_element->data_ptr; @@ -892,110 +608,6 @@ namespace nana rs.pos.x += static_cast(data->size().width); } } -#else - void _m_draw_block(graph_reference graph, const std::wstring& s, dstream::linecontainer::iterator block_start, render_status& rs) - { - auto const reordered = unicode_reorder(s.data(), s.length()); - - pixel_tag px = rs.pixels[rs.index]; - - for(auto & bidi : reordered) - { - std::size_t pos = bidi.begin - s.data(); - std::size_t len = bidi.end - bidi.begin; - - while (true) - { - auto i = block_start; - - //Text range indicates the position of text where begin to output - //The output length is the min between len and the second of text range. - auto text_range = _m_locate(i, pos); - - if (text_range.second > len) - text_range.second = len; - - fblock * fblock_ptr = i->fblock_ptr; - data * data_ptr = i->data_ptr; - -#if 1 - const int range_text_area = static_cast(rs.allowed_width) - rs.pos.x; - - _m_change_font(graph, fblock_ptr); - - auto text_extent_size = data_ptr->size(); -#ifndef _nana_std_has_string_view - std::wstring_view text_sv{ data_ptr->text().c_str() + text_range.first, text_range.second }; - if (data_ptr->text().size() != text_sv.size()) - text_extent_size = graph.text_extent_size(text_sv); -#else - auto text_sv = data_ptr->text().substr(text_range.first, text_range.second); - if (data_ptr->text().size() != text_sv.size()) - text_extent_size = graph.text_extent_size(text_sv); -#endif - if ((static_cast(text_extent_size.width) > range_text_area) && (rs.pos.x != px.x_base)) - { - //Change a new line - rs.pos.y += static_cast(px.pixels); - px = rs.pixels[++rs.index]; - rs.pos.x = px.x_base; - } - - const int y = rs.pos.y + _m_text_top(px, fblock_ptr, data_ptr); - graph.string({ rs.pos.x, y }, text_sv, _m_fgcolor(fblock_ptr)); -#else - const int w = static_cast(rs.allowed_width) - rs.pos.x; - nana::size text_extent_size = data_ptr->size(); - if ((static_cast(text_extent_size.width) > w) && (rs.pos.x != px.x_base)) - { - //Change a new line - rs.pos.y += static_cast(px.pixels); - px = rs.pixels[++rs.index]; - rs.pos.x = px.x_base; - } - - const int y = rs.pos.y + _m_text_top(px, fblock_ptr, data_ptr); - - _m_change_font(graph, fblock_ptr); - -#ifdef _nana_std_has_string_view - std::wstring_view text_sv{ data_ptr->text() }; - if (text_range.second != text_sv.size()) - { - text_sv = text_sv.substr(text_range.first, text_range.second); - text_extent_size = graph.text_extent_size(text_sv); - } - - graph.string({ rs.pos.x, y }, text_sv, _m_fgcolor(fblock_ptr)); -#else - if (text_range.second == data_ptr->text().length()) - { - graph.string({ rs.pos.x, y }, data_ptr->text(), _m_fgcolor(fblock_ptr)); - } - else - { - auto str = data_ptr->text().substr(text_range.first, text_range.second); - text_extent_size = graph.text_extent_size(str); - - graph.string({ rs.pos.x, y }, str, _m_fgcolor(fblock_ptr)); - } -#endif -#endif //#if 0 - - _m_insert_if_traceable(rs.pos.x, y, text_extent_size, fblock_ptr); - rs.pos.x += static_cast(text_extent_size.width); - - if(text_range.second < len) - { - len -= text_range.second; - pos += text_range.second; - } - else - break; - } - } - } -#endif //VISUAL_LINES static std::pair _m_locate(dstream::linecontainer::iterator& i, std::size_t pos) { From 81d667dbd799e8b238a63c698705c98554498db2 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 27 Aug 2018 06:51:20 +0800 Subject: [PATCH 7/7] using C++17 emplace return type --- include/nana/c++defines.hpp | 4 ++-- source/basic_types.cpp | 10 ++++++++-- source/gui/detail/window_manager.cpp | 8 ++++++++ source/gui/place.cpp | 6 ++++++ source/gui/place_parts.hpp | 7 +++++-- source/gui/widgets/group.cpp | 4 ++++ source/gui/widgets/label.cpp | 16 ++++++++++------ source/gui/widgets/listbox.cpp | 18 ++++++++++++++++++ source/gui/widgets/menubar.cpp | 7 +++++++ source/gui/widgets/skeletons/text_editor.cpp | 4 ++++ source/gui/widgets/tabbar.cpp | 2 +- source/unicode_bidi.cpp | 5 +++++ 12 files changed, 78 insertions(+), 13 deletions(-) diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index e7860b80..ef5d8e9f 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -220,14 +220,14 @@ #endif #undef _nana_std_has_string_view -#undef _nana_std_has_returnable_emplace_back +#undef _nana_std_has_emplace_return_type #if ((defined(_MSC_VER) && (_MSC_VER >= 1912) && defined(_MSVC_LANG) && _MSVC_LANG >= 201703)) || \ ((__cplusplus >= 201703L) && \ (defined(__clang__) && (__clang_major__ * 100 + __clang_minor__ >= 400) || \ (!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 701))) \ ) # define _nana_std_has_string_view -# define _nana_std_has_returnable_emplace_back +# define _nana_std_has_emplace_return_type #endif diff --git a/source/basic_types.cpp b/source/basic_types.cpp index 69c6fa78..dafe8574 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -186,10 +186,12 @@ namespace nana throw std::invalid_argument(excpt_what); std::vector rgb; - +#ifdef _nana_std_has_emplace_return_type + auto const is_real = (rgb.emplace_back(i->str()).back() == '%'); +#else rgb.emplace_back(i->str()); - const bool is_real = (rgb.back().back() == '%'); +#endif pat.assign(is_real ? "(\\d*\\.)?\\d+\\%" : "\\d+"); for (++i; i != end; ++i) @@ -275,9 +277,13 @@ namespace nana { std::vector rgb; +#ifdef _nana_std_has_emplace_return_type + auto const is_real = (rgb.emplace_back(std::move(str)).back() == '%'); +#else rgb.emplace_back(std::move(str)); const bool is_real = (rgb.back().back() == '%'); +#endif for (int i = 0; i < 2; ++i) { diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 785f45be..9d8ebd65 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -85,8 +85,12 @@ namespace nana } } +#ifdef _nana_std_has_emplace_return_type + auto & rep = impl_->base.emplace_back(); +#else impl_->base.emplace_back(); auto & rep = impl_->base.back(); +#endif rep.handle = wd; rep.keys.emplace_back(key); @@ -242,8 +246,12 @@ namespace detail return kv.second; } +#ifdef _nana_std_has_emplace_return_type + return table_.emplace_back(key).second; +#else table_.emplace_back(key); return table_.back().second; +#endif } iterator find(const Key& key) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 5b22491e..9b278111 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -742,8 +742,14 @@ namespace nana void _m_add_agent(const detail::place_agent& ag) override { +#ifdef _nana_std_has_emplace_return_type + this->operator<<( + widgets_.emplace_back(ag.create(place_ptr_->window_handle()))->handle() + ); +#else widgets_.emplace_back(ag.create(place_ptr_->window_handle())); this->operator<<(widgets_.back()->handle()); +#endif } public: division* attached{ nullptr }; diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index ca2ea8d7..2105dd02 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -436,10 +436,13 @@ namespace nana caption_.caption(wdg->caption()); } - panels_.emplace_back(); auto wdg_ptr = wdg.get(); +#ifdef _nana_std_has_emplace_return_type + panels_.emplace_back().widget_ptr = std::move(wdg); +#else + panels_.emplace_back(); panels_.back().widget_ptr.swap(wdg); - +#endif for (auto & pn : panels_) { if (pn.widget_ptr) diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index 8be557ef..6d697a62 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -136,8 +136,12 @@ namespace nana{ { _THROW_IF_EMPTY() +#ifdef _nana_std_has_emplace_return_type + auto & opt = impl_->options.emplace_back(new checkbox{ handle() }); +#else impl_->options.emplace_back(new checkbox(handle())); auto & opt = impl_->options.back(); +#endif opt->transparent(true); opt->caption(std::move(text)); impl_->place_content[field_options] << *opt; diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index 53ab80ae..013b5605 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -226,8 +226,12 @@ namespace nana { if(fbp->target.size() || fbp->url.size()) { +#ifdef _nana_std_has_emplace_return_type + auto & tr = traceable_.emplace_back(); +#else traceable_.emplace_back(); auto & tr = traceable_.back(); +#endif tr.r.x = x; tr.r.y = y; tr.r.dimension(sz); @@ -398,7 +402,7 @@ namespace nana //make a visual line for existing vsline elements if (text_pos) { -#ifdef _nana_std_has_returnable_emplace_back +#ifdef _nana_std_has_emplace_return_type auto & vsline = rs.vslines.emplace_back(); #else rs.vslines.emplace_back(); @@ -449,7 +453,7 @@ namespace nana if (text_begin + sub_text_len < data->text().size()) { //make a new visual line -#ifdef _nana_std_has_returnable_emplace_back +#ifdef _nana_std_has_emplace_return_type auto & vsline = rs.vslines.emplace_back(); #else rs.vslines.emplace_back(); @@ -483,7 +487,7 @@ namespace nana if (!vsline_elements.empty()) { -#ifdef _nana_std_has_returnable_emplace_back +#ifdef _nana_std_has_emplace_return_type auto & vsline = rs.vslines.emplace_back(); #else rs.vslines.emplace_back(); @@ -515,14 +519,14 @@ namespace nana #endif text_px = 0; - for (std::size_t i = 0; i < text.size(); ++i) + for (unsigned i = 0; i < text.size(); ++i) { if (text_px + pxbuf[i] > limited_width_px) return i; text_px += pxbuf[i]; } - return text.size(); + return static_cast(text.size()); } bool _m_foreach_visual_line(graph_reference graph, render_status& rs) @@ -542,7 +546,7 @@ namespace nana } ++rs.index; //next line index - rs.pos.y += vsline.extent_height_px; + rs.pos.y += static_cast(vsline.extent_height_px); if (rs.pos.y > bottom) return false; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index f25ac277..489f6611 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -312,8 +312,12 @@ namespace nana size_type create(essence* ess, native_string_type&& text, unsigned pixels) { +#ifdef _nana_std_has_emplace_return_type + return cont_.emplace_back(ess, std::move(text), pixels, static_cast(cont_.size())).index; +#else cont_.emplace_back(ess, std::move(text), pixels, static_cast(cont_.size())); return cont_.back().index; +#endif } void clear() @@ -1023,9 +1027,15 @@ namespace nana } } +#ifdef _nana_std_has_emplace_return_type + auto & last_cat = categories_.emplace_back(); + last_cat.key_ptr = ptr; + return &last_cat; +#else categories_.emplace_back(); categories_.back().key_ptr = ptr; return &(categories_.back()); +#endif } /// Inserts a new category at position specified by pos @@ -1033,8 +1043,12 @@ namespace nana { if (::nana::npos == pos) { +#ifdef _nana_std_has_emplace_return_type + return &categories_.emplace_back(std::move(text)); +#else categories_.emplace_back(std::move(text)); return &categories_.back(); +#endif } return &(*categories_.emplace(this->get(pos), std::move(text))); @@ -2622,8 +2636,12 @@ namespace nana oresolver& oresolver::operator<<(std::nullptr_t) { +#ifdef _nana_std_has_emplace_return_type + cells_.emplace_back().text.assign(1, wchar_t{}); +#else cells_.emplace_back(); cells_.back().text.assign(1, wchar_t(0)); //means invalid cell +#endif return *this; } diff --git a/source/gui/widgets/menubar.cpp b/source/gui/widgets/menubar.cpp index 3c211ba6..94d7c6c2 100644 --- a/source/gui/widgets/menubar.cpp +++ b/source/gui/widgets/menubar.cpp @@ -89,11 +89,18 @@ namespace nana if (shortkey && shortkey < 0x61) shortkey += (0x61 - 0x41); + +#ifdef _nana_std_has_emplace_return_type + auto & last = items.emplace_back(new item_type{std::move(transformed_text), shortkey, shortkey_pos}); + API::refresh_window(*widget_ptr); + return last->menu_obj; +#else items.emplace_back(new item_type{ std::move(transformed_text), shortkey, shortkey_pos }); API::refresh_window(*widget_ptr); return this->items.back()->menu_obj; +#endif } bool cancel() diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 0510acd9..ca070ace 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1009,8 +1009,12 @@ namespace nana{ namespace widgets auto ki = keywords.schemes.find(ds.scheme); if ((ki != keywords.schemes.end()) && ki->second) { +#ifdef _nana_std_has_emplace_return_type + auto & last = entities.emplace_back(); +#else entities.emplace_back(); auto & last = entities.back(); +#endif last.begin = c_str + pos; last.end = last.begin + ds.text.size(); last.scheme = ki->second.get(); diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index f0a972c9..8970089b 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -750,8 +750,8 @@ namespace nana { if((pos == npos) || (pos >= list_.size())) { + pos = list_.size(); this->list_.emplace_back(); - pos = list_.size() - 1; } else list_.emplace(iterator_at(pos)); diff --git a/source/unicode_bidi.cpp b/source/unicode_bidi.cpp index 3591d6ef..32ca0541 100644 --- a/source/unicode_bidi.cpp +++ b/source/unicode_bidi.cpp @@ -1,4 +1,5 @@ #include +#include namespace nana { @@ -611,8 +612,12 @@ namespace nana void unicode_bidi::_m_push_entity(const char_type * begin, const char_type *end, unsigned level, bidi_char bidi_char_type) { +#ifdef _nana_std_has_emplace_return_type + auto & e = levels_.emplace_back(); +#else levels_.emplace_back(); auto & e = levels_.back(); +#endif e.begin = begin; e.end = end; e.level = level;