diff --git a/.travis.yml b/.travis.yml index ba037042..170ef287 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise before_install: - - git clone --depth=1 --branch=hotfix-1.4 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 diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 226a7d58..551b45bb 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -116,8 +116,6 @@ # define _enable_std_clamp # endif -#elif defined(NANA_MINGW) -# define STD_THREAD_NOT_SUPPORTED #elif defined(__clang__) //Clang #include //Introduces some implement-specific flags of ISO C++ Library @@ -132,9 +130,6 @@ #endif #endif - -# define _enable_std_clamp - #elif defined(__GNUC__) //GCC #include //Introduces some implement-specific flags of ISO C++ Library @@ -190,8 +185,20 @@ #endif #endif #endif +#endif -# define _enable_std_clamp +//Assume the std::thread is not implement on MinGW +//But some toolchains may implement std::thread. +#ifdef NANA_MINGW +# ifndef STD_THREAD_NOT_SUPPORTED +# define STD_THREAD_NOT_SUPPORTED +# endif +#endif + +#if (!defined(__cpp_lib_clamp)) || (__cpp_lib_clamp < 201603) +# ifndef _enable_std_clamp +# define _enable_std_clamp +# endif #endif diff --git a/include/nana/charset.hpp b/include/nana/charset.hpp index 09f79bdf..0bbb9c71 100644 --- a/include/nana/charset.hpp +++ b/include/nana/charset.hpp @@ -1,15 +1,13 @@ /** * The charset Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2017 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/charset.hpp - * - * */ #ifndef NANA_CHARSET_HPP diff --git a/include/nana/gui/widgets/menu.hpp b/include/nana/gui/widgets/menu.hpp index 693310a2..f8ec1167 100644 --- a/include/nana/gui/widgets/menu.hpp +++ b/include/nana/gui/widgets/menu.hpp @@ -19,6 +19,8 @@ namespace nana { + class menu; + namespace drawerbase { namespace menu @@ -40,7 +42,7 @@ namespace nana class item_proxy { public: - item_proxy(std::size_t n, menu_item_type &); + item_proxy(std::size_t pos, ::nana::menu*); item_proxy& enabled(bool); bool enabled() const; @@ -48,12 +50,13 @@ namespace nana item_proxy& checked(bool); bool checked() const; + item_proxy& text(std::string title_utf8); std::string text() const; std::size_t index() const; private: - std::size_t index_; - menu_item_type &item_; + std::size_t const pos_; + ::nana::menu* const menu_; }; /// A callback functor type. typedef std::function event_fn_t; @@ -69,7 +72,12 @@ namespace nana bool checked:1; }flags; - menu_type *sub_menu{nullptr}; + struct + { + bool own_creation; //Indicates the menu_ptr is created by create_sub_menu + menu_type* menu_ptr; + }linked; + std::string text; event_fn_t event_handler; checks style{checks::none}; @@ -117,9 +125,8 @@ namespace nana typedef drawerbase::menu::checks checks; typedef drawerbase::menu::renderer_interface renderer_interface; - typedef drawerbase::menu::menu_item_type item_type; - typedef item_type::item_proxy item_proxy; - typedef item_type::event_fn_t event_fn_t; ///< A callback functor type. Prototype: `void(item_proxy&)` + typedef drawerbase::menu::menu_item_type::item_proxy item_proxy; + typedef drawerbase::menu::menu_item_type::event_fn_t event_fn_t; ///< A callback functor type. Prototype: `void(item_proxy&)` menu(); ///< The default constructor. NO OTHER CONSTRUCTOR. ~menu(); @@ -143,6 +150,7 @@ namespace nana void close(); void image(std::size_t pos, const paint::image& icon); void text(std::size_t pos, std::string text_utf8); + std::string text(std::size_t pos) const; void check_style(std::size_t pos, checks); void checked(std::size_t pos, bool); bool checked(std::size_t pos) const; @@ -150,7 +158,7 @@ namespace nana bool enabled(std::size_t pos) const; void erase(std::size_t pos); ///< Removes the item bool link(std::size_t pos, menu& menu_obj);///< Link a menu to the item as a sub menu. - menu * link(std::size_t pos); ///< Retrieves a linked sub menu of the item. + menu * link(std::size_t pos) const; ///< Retrieves a linked sub menu of the item. menu *create_sub_menu(std::size_t pos); void popup(window owner, int x, int y); ///< Popup the menu at the owner window. void popup_await(window owner, int x, int y); diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 3fe3e157..896027c0 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -230,7 +230,10 @@ namespace nana{ namespace widgets void _m_reset_content_size(bool calc_lines = false); void _m_reset(); + + //Inserts text at position where the caret is ::nana::upoint _m_put(::std::wstring); + ::nana::upoint _m_erase_select(); ::std::wstring _m_make_select_string() const; diff --git a/source/charset.cpp b/source/charset.cpp index eb2fcd55..5c802b15 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1,7 +1,7 @@ /** * A Character Encoding Set Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -12,6 +12,7 @@ * @contributions * UTF16 4-byte decoding issue by Renke Yan. * Pr0curo(pr#98) + * crillion */ #include @@ -21,6 +22,7 @@ #include #include //Added by Pr0curo(pr#98) #include +#include //Added by crillion //GCC 4.7.0 does not implement the and codecvt_utfx classes #ifndef STD_CODECVT_NOT_SUPPORTED diff --git a/source/gui/detail/window_register.hpp b/source/gui/detail/window_register.hpp index 65ac0fa8..40b2fae6 100644 --- a/source/gui/detail/window_register.hpp +++ b/source/gui/detail/window_register.hpp @@ -111,6 +111,15 @@ namespace nana public: using window_handle_type = basic_window*; + ~window_register() + { + //Deleting a basic_window if thread never called exec(), the basic_window object + //will always stay in trash. + // + //Empty the trash before destructs window register + delete_trash(0); + } + void insert(window_handle_type wd) { if (wd) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index ff446802..c0a4f972 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -632,13 +632,16 @@ namespace nana API::umake_event(e.evt_destroy); } - void visible(bool vsb) + void visible(bool vsb, bool sync_fastened = true) { for (auto & e : elements) API::show_window(e.handle, vsb); - for (auto & e : fastened) - API::show_window(e.handle, vsb); + if (sync_fastened) + { + for (auto & e : fastened) + API::show_window(e.handle, vsb); + } } static event_handle erase_element(std::vector& elements, window handle) noexcept @@ -2571,7 +2574,10 @@ namespace nana } } - field.second->visible(is_show); + //Collocate doesn't sync the visiblity of fastened windows. + //This is a feature that allows tabbar panels to be fastened to a same field, the collocate() + //shouldn't break the visibility of panels that are maintained by tabbar. + field.second->visible(is_show, false); } } } diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 53555952..1a3325ec 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -5376,6 +5376,8 @@ namespace nana if (start_pos < origin.y) origin.y -= ess->item_height(); + ess->lister.erase(_where); + ess->calc_content_size(false); ess->content_view->change_position(origin.y, false, false); ess->content_view->sync(false); diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 78f842bc..61e6a610 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -21,7 +21,6 @@ #include #include #include //introduces tolower -#include #include namespace nana @@ -37,7 +36,8 @@ namespace nana using item_container = std::vector>; using iterator = item_container::iterator; - std::vector owner; + ::nana::menu* owner; + std::vector links; item_container items; unsigned max_pixels; unsigned item_pixels; @@ -51,58 +51,15 @@ namespace nana } //struct menu_item_type - //class item_proxy - //@brief: this class is used as parameter of menu event function. - menu_item_type::item_proxy::item_proxy(std::size_t index, menu_item_type &item) - :index_(index), item_(item) - {} - - menu_item_type::item_proxy& menu_item_type::item_proxy::enabled(bool v) - { - item_.flags.enabled = v; - return *this; - } - - bool menu_item_type::item_proxy::enabled() const - { - return item_.flags.enabled; - } - - menu_item_type::item_proxy& menu_item_type::item_proxy::check_style(checks style) - { - if (good_checks(style)) - item_.style = style; - return *this; - } - - menu_item_type::item_proxy& menu_item_type::item_proxy::checked(bool ck) - { - item_.flags.checked = ck; - return *this; - } - - bool menu_item_type::item_proxy::checked() const - { - return item_.flags.checked; - } - - std::string menu_item_type::item_proxy::text() const - { - return item_.text; - } - - std::size_t menu_item_type::item_proxy::index() const - { - return index_; - } - //end class item_proxy - //Default constructor initializes the item as a splitter menu_item_type::menu_item_type() { flags.enabled = true; flags.splitter = true; flags.checked = false; + + linked.own_creation = false; + linked.menu_ptr = nullptr; } menu_item_type::menu_item_type(std::string text, const event_fn_t& fn) @@ -111,6 +68,9 @@ namespace nana flags.enabled = true; flags.splitter = false; flags.checked = false; + + linked.own_creation = false; + linked.menu_ptr = nullptr; } //end class menu_item_type @@ -209,8 +169,9 @@ namespace nana using event_fn_t = item_type::event_fn_t; using iterator = menu_type::item_container::iterator; - menu_builder() + menu_builder(::nana::menu* owner) { + root_.owner = owner; root_.max_pixels = screen::primary_monitor_size().width * 2 / 3; root_.item_pixels = 24; renderer_ = pat::cloneable(internal_renderer()); @@ -218,7 +179,37 @@ namespace nana ~menu_builder() { - this->destroy(); + //Disconnects the link. + + //Clears the all links which are parent of mine + for (auto link : root_.links) + { + for (auto & m : link->items) + { + if (m->linked.menu_ptr == &root_) + { + m->linked.own_creation = false; + m->linked.menu_ptr = nullptr; + } + } + } + + for (auto & m : root_.items) + { + if (m->linked.menu_ptr) + { + for (auto i = m->linked.menu_ptr->links.begin(); i != m->linked.menu_ptr->links.end();) + { + if ((*i) == &root_) + i = m->linked.menu_ptr->links.erase(i); + else + ++i; + } + + if (m->linked.own_creation) + delete m->linked.menu_ptr->owner; + } + } } void check_style(std::size_t index, checks s) @@ -270,41 +261,19 @@ namespace nana return root_; } - bool set_sub_menu(std::size_t pos, menu_type &sub) + //Returns false if the linked menu is already existing + bool set_linkage(std::size_t pos, menu_type &linked, bool own_creation) { - if(root_.items.size() > pos) - { - auto & item = *(root_.items[pos]); - if(!item.sub_menu) - { - item.sub_menu = ⊂ - sub.owner.emplace_back(&root_); - return true; - } - } - return false; - } + auto mi = root_.items.at(pos).get(); - void destroy() - { - for(auto i : root_.owner) - for(auto & m : i->items) - { - if(m->sub_menu == &root_) - m->sub_menu = nullptr; - } + if (mi->linked.menu_ptr) + return false; - for(auto & m : root_.items) - { - if(m->sub_menu) - for(auto i = m->sub_menu->owner.begin(); i != m->sub_menu->owner.end();) - { - if((*i) == &root_) - i = m->sub_menu->owner.erase(i); - else - ++i; - } - } + mi->linked.menu_ptr = &linked; + mi->linked.own_creation = own_creation; + linked.links.emplace_back(&root_); + + return true; } pat::cloneable& renderer() @@ -321,6 +290,58 @@ namespace nana pat::cloneable renderer_; };//end class menu_builder + + //class menu_item_type::item_proxy + menu_item_type::item_proxy::item_proxy(std::size_t pos, nana::menu* m): + pos_{pos}, + menu_{m} + {} + + menu_item_type::item_proxy& menu_item_type::item_proxy::enabled(bool v) + { + menu_->enabled(pos_, v); + return *this; + } + + bool menu_item_type::item_proxy::enabled() const + { + return menu_->enabled(pos_); + } + + menu_item_type::item_proxy& menu_item_type::item_proxy::check_style(checks style) + { + menu_->check_style(pos_, style); + return *this; + } + + menu_item_type::item_proxy& menu_item_type::item_proxy::checked(bool ck) + { + menu_->checked(pos_, ck); + return *this; + } + + bool menu_item_type::item_proxy::checked() const + { + return menu_->checked(pos_); + } + + menu_item_type::item_proxy& menu_item_type::item_proxy::text(std::string title) + { + menu_->text(pos_, title); + return *this; + } + + std::string menu_item_type::item_proxy::text() const + { + return menu_->text(pos_); + } + + std::size_t menu_item_type::item_proxy::index() const + { + return pos_; + } + //end class item_proxy + class menu_drawer : public drawer_trigger { @@ -438,7 +459,7 @@ namespace nana } } - if (item_ptr->sub_menu) + if (item_ptr->linked.menu_ptr) renderer->sub_arrow(graph, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr); item_r.y += item_r.height + 1; @@ -522,7 +543,7 @@ namespace nana std::size_t index = _m_get_index_by_pos(pos.x, pos.y); if (index != state_.active) { - if ((index == npos) && items.at(state_.active)->sub_menu && state_.sub_window) + if ((index == npos) && items.at(state_.active)->linked.menu_ptr && state_.sub_window) return false; state_.active = (index != npos && items.at(index)->flags.splitter) ? npos : index; @@ -550,7 +571,7 @@ namespace nana return nullptr; auto & items = menu_->items; - auto sub = items.at(state_.active)->sub_menu; + auto sub = items.at(state_.active)->linked.menu_ptr; if (sub) { pos.x = static_cast(graph_->width()) - 2; @@ -593,7 +614,7 @@ namespace nana if (!item_ptr->flags.splitter) { - if (item_ptr->sub_menu) + if (item_ptr->linked.menu_ptr) { state_.active = index; state_.active_timestamp = nana::system::timestamp(); @@ -606,7 +627,7 @@ namespace nana fn_close_tree_(); if (item_ptr->event_handler) { - item_proxy ip(index, *item_ptr); + item_proxy ip{ index, menu_->owner }; item_ptr->event_handler.operator()(ip); } return 1; @@ -901,7 +922,7 @@ namespace nana menu_item_type & item = *(menu->items.at(active)); - if ((!item.flags.enabled) || item.flags.splitter || item.sub_menu) + if ((!item.flags.enabled) || item.flags.splitter || item.linked.menu_ptr) return; if (checks::highlight == item.style) @@ -920,7 +941,7 @@ namespace nana if (item.event_handler) { - item_type::item_proxy ip(active, item); + item_type::item_proxy ip{ active, menu->owner }; item.event_handler.operator()(ip); } } @@ -1109,30 +1130,32 @@ namespace nana drawerbase::menu::menu_builder mbuilder; drawerbase::menu::menu_window * window_ptr; std::function destroy_answer; - std::map sub_container; + + implement(menu* self): + mbuilder{self} + { + } }; menu::menu() - :impl_(new implement) + :impl_(new implement(this)) { impl_->window_ptr = nullptr; } menu::~menu() { - for(auto i = impl_->sub_container.rbegin(); i != impl_->sub_container.rend(); ++i) - { - if(i->second.kill) - delete i->second.handle; - } + this->close(); delete impl_; } + using item_type = drawerbase::menu::menu_item_type; + auto menu::append(std::string text_utf8, const menu::event_fn_t& handler) -> item_proxy { std::unique_ptr item{ new item_type{ std::move(text_utf8), handler } }; - impl_->mbuilder.data().items.emplace_back(item.get()); - return item_proxy(size() - 1, *item.release()); + impl_->mbuilder.data().items.emplace_back(std::move(item)); + return item_proxy{size() - 1, this}; } void menu::append_splitter() @@ -1154,9 +1177,9 @@ namespace nana #else items.begin() + pos, #endif - item.get()); + std::move(item)); - return item_proxy{ pos, *item.release() }; + return item_proxy{ pos, this}; } void menu::clear() @@ -1193,39 +1216,32 @@ namespace nana impl_->mbuilder.data().items.at(index)->text.swap(text_utf8); } - bool menu::link(std::size_t index, menu& menu_obj) + std::string menu::text(std::size_t index) const { - if(impl_->mbuilder.set_sub_menu(index, menu_obj.impl_->mbuilder.data())) - { - auto& minfo = impl_->sub_container[index]; - minfo.handle = &menu_obj; - minfo.kill = false; - return true; - } - return false; + return impl_->mbuilder.data().items.at(index)->text; } - menu* menu::link(std::size_t index) + bool menu::link(std::size_t index, menu& menu_obj) { - auto i = impl_->sub_container.find(index); - if(i == impl_->sub_container.end()) - return nullptr; - return i->second.handle; + return impl_->mbuilder.set_linkage(index, menu_obj.impl_->mbuilder.data(), false); + } + + menu* menu::link(std::size_t index) const + { + auto mi = impl_->mbuilder.data().items.at(index).get(); + + if (mi && mi->linked.menu_ptr) + return mi->linked.menu_ptr->owner; + + return nullptr; } menu *menu::create_sub_menu(std::size_t index) { - menu * sub = new menu; - - if (this->link(index, *sub)) - { - auto& minfo = impl_->sub_container[index]; - minfo.handle = sub; - minfo.kill = true; - return sub; - } - - delete sub; + std::unique_ptr guard{new menu}; + if (impl_->mbuilder.set_linkage(index, guard->impl_->mbuilder.data(), true)) + return guard.release(); + return nullptr; } diff --git a/source/gui/widgets/skeletons/content_view.cpp b/source/gui/widgets/skeletons/content_view.cpp index 4dfc49a0..438ce4ea 100644 --- a/source/gui/widgets/skeletons/content_view.cpp +++ b/source/gui/widgets/skeletons/content_view.cpp @@ -92,14 +92,15 @@ namespace nana { auto mouse_evt = [this](const arg_mouse& arg) { - if (event_code::mouse_move == arg.evt_code) + if (event_code::mouse_down == arg.evt_code) { if (!arg.is_left_button()) return; - if ((!this->drag_started) && this->view.view_area().is_hit(arg.pos)) - this->drag_started = true; - + this->drag_started = this->view.view_area().is_hit(arg.pos); + } + else if (event_code::mouse_move == arg.evt_code) + { if (this->drag_started && this->drive(arg.pos)) { tmr.interval(16); @@ -113,6 +114,7 @@ namespace nana { } }; + API::events(handle).mouse_down.connect_unignorable(mouse_evt); API::events(handle).mouse_move.connect_unignorable(mouse_evt); API::events(handle).mouse_up.connect_unignorable(mouse_evt); @@ -164,11 +166,9 @@ namespace nana { speed_horz = (std::min)(5, (std::max)(speed_horz, -5)); speed_vert = (std::min)(5, (std::max)(speed_vert, -5)); - view.move_origin({ + return view.move_origin({ speed_horz, speed_vert }); - - return true; } void size_changed(bool try_update) @@ -435,10 +435,12 @@ namespace nana { } } - void content_view::move_origin(const point& skew) + bool content_view::move_origin(const point& skew) { auto imd_area = this->view_area(); + auto pre_origin = impl_->origin; + impl_->origin.x += skew.x; if (impl_->origin.x + imd_area.width > impl_->content_size.width) impl_->origin.x = static_cast(impl_->content_size.width) - static_cast(imd_area.width); @@ -451,6 +453,8 @@ namespace nana { impl_->origin.y = static_cast(impl_->content_size.height) - static_cast(imd_area.height); if (impl_->origin.y < 0) impl_->origin.y = 0; + + return (pre_origin != impl_->origin); } void content_view::sync(bool try_update) diff --git a/source/gui/widgets/skeletons/content_view.hpp b/source/gui/widgets/skeletons/content_view.hpp index 2575fe29..6d4b2d40 100644 --- a/source/gui/widgets/skeletons/content_view.hpp +++ b/source/gui/widgets/skeletons/content_view.hpp @@ -70,7 +70,8 @@ namespace skeletons void change_position(int pos, bool aligned, bool horz); - void move_origin(const point& skew); + /// Returns true if the origin is moved + bool move_origin(const point& skew); void sync(bool try_update); diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 282a08b5..d008d70a 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1802,6 +1802,9 @@ namespace nana{ namespace widgets reset_caret(); impl_->try_refresh = sync_graph::refresh; points_.xpos = 0; + + //_m_put calcs the lines + _m_reset_content_size(false); } } else @@ -1828,11 +1831,10 @@ namespace nana{ namespace widgets { const unsigned line_pixels = line_height(); - auto pos = _m_caret_to_screen(crtpos); - const int line_bottom = pos.y + static_cast(line_pixels); + //The coordinate of caret + auto coord = _m_caret_to_screen(crtpos); - if (reset_caret) - points_.caret = _m_screen_to_caret(pos); + const int line_bottom = coord.y + static_cast(line_pixels); if (!API::is_focus_ready(window_)) return false; @@ -1842,7 +1844,7 @@ namespace nana{ namespace widgets bool visible = false; auto text_area = impl_->cview->view_area(); - if (text_area.is_hit(pos) && (line_bottom > text_area.y)) + if (text_area.is_hit(coord) && (line_bottom > text_area.y)) { visible = true; if (line_bottom > text_area.bottom()) @@ -1856,10 +1858,10 @@ namespace nana{ namespace widgets caret->visible(visible); if(visible) - caret->position(pos); + caret->position(coord); //Adjust the caret into screen when the caret position is modified by this function - if (reset_caret && (!hit_text_area(pos))) + if (reset_caret && (!hit_text_area(coord))) { impl_->capacities.behavior->adjust_caret_into_screen(); impl_->try_refresh = sync_graph::refresh; @@ -2671,7 +2673,7 @@ namespace nana{ namespace widgets if (whole_line) lines = impl_->capacities.behavior->take_lines(row.first); else - top += height * row.second; + top += static_cast(height * row.second); const rectangle area_r = { text_area_.area.x, top, width_pixels(), static_cast(height * lines) }; @@ -2839,7 +2841,7 @@ namespace nana{ namespace widgets for (auto & ent : reordered) { auto str_px = static_cast(_m_text_extent_size(ent.begin, ent.end - ent.begin).width); - if (scrpos.x < str_px) + if (scrpos.x <= str_px) { res.x += _m_char_by_pixels(ent, scrpos.x); res.x += static_cast(ent.begin - text_ptr); @@ -3067,15 +3069,14 @@ namespace nana{ namespace widgets if (_m_resolve_text(text, lines) && attributes_.multi_lines) { auto str_orig = textbase.getline(crtpos.y); - auto x_orig = crtpos.x; - auto subpos = lines.front(); + auto const subpos = lines.front(); auto substr = text.substr(subpos.first, subpos.second - subpos.first); - if (str_orig.size() == x_orig) + if (str_orig.size() == crtpos.x) textbase.insert(crtpos, std::move(substr)); else - textbase.replace(crtpos.y, str_orig.substr(0, x_orig) + substr); + textbase.replace(crtpos.y, str_orig.substr(0, crtpos.x) + substr); //There are at least 2 elements in lines for (auto i = lines.begin() + 1, end = lines.end() - 1; i != end; ++i) @@ -3084,7 +3085,7 @@ namespace nana{ namespace widgets } auto backpos = lines.back(); - textbase.insertln(++crtpos.y, text.substr(backpos.first, backpos.second - backpos.first) + str_orig.substr(x_orig)); + textbase.insertln(++crtpos.y, text.substr(backpos.first, backpos.second - backpos.first) + str_orig.substr(crtpos.x)); crtpos.x = static_cast(backpos.second - backpos.first); impl_->capacities.behavior->add_lines(points_.caret.y, lines.size() - 1); @@ -3096,12 +3097,12 @@ namespace nana{ namespace widgets if (lines.size() > 1) text = text.substr(lines.front().first, lines.front().second - lines.front().first); - auto length = text.size(); - textbase.insert(crtpos, std::move(text)); + crtpos.x += static_cast(text.size()); + textbase.insert(points_.caret, std::move(text)); - crtpos.x += static_cast(length); _m_pre_calc_lines(crtpos.y, 1); } + return crtpos; } @@ -3737,7 +3738,7 @@ namespace nana{ namespace widgets { for (auto p = pxbuf.get(); p != px_end; ++p) { - if (pos < *p) + if (pos <= *p) { if ((*p > 1) && (pos >(*p >> 1))) return static_cast(p - pxbuf.get()) + 1; diff --git a/source/paint/truetype.hpp b/source/paint/truetype.hpp index 2caa3f0e..bd44c0db 100644 --- a/source/paint/truetype.hpp +++ b/source/paint/truetype.hpp @@ -51,7 +51,7 @@ namespace nana truetype(const path_type& filename) { - std::ifstream ifs{ filename, std::ios::binary }; + std::ifstream ifs(filename.string(), std::ios::binary); if (!ifs.is_open()) return;