Merge branch 'develop'
This commit is contained in:
commit
3a927ee7fc
@ -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
|
||||
|
||||
@ -116,8 +116,6 @@
|
||||
# define _enable_std_clamp
|
||||
# endif
|
||||
|
||||
#elif defined(NANA_MINGW)
|
||||
# define STD_THREAD_NOT_SUPPORTED
|
||||
#elif defined(__clang__) //Clang
|
||||
|
||||
#include <iosfwd> //Introduces some implement-specific flags of ISO C++ Library
|
||||
@ -132,9 +130,6 @@
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
# define _enable_std_clamp
|
||||
|
||||
#elif defined(__GNUC__) //GCC
|
||||
|
||||
#include <iosfwd> //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
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<void(item_proxy&)> 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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 <nana/charset.hpp>
|
||||
@ -21,6 +22,7 @@
|
||||
#include <clocale>
|
||||
#include <cstring> //Added by Pr0curo(pr#98)
|
||||
#include <memory>
|
||||
#include <locale> //Added by crillion
|
||||
|
||||
//GCC 4.7.0 does not implement the <codecvt> and codecvt_utfx classes
|
||||
#ifndef STD_CODECVT_NOT_SUPPORTED
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<element_t>& 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
#include <nana/gui/wvl.hpp>
|
||||
#include <nana/paint/text_renderer.hpp>
|
||||
#include <cctype> //introduces tolower
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace nana
|
||||
@ -37,7 +36,8 @@ namespace nana
|
||||
using item_container = std::vector<std::unique_ptr<item_type>>;
|
||||
using iterator = item_container::iterator;
|
||||
|
||||
std::vector<menu_type*> owner;
|
||||
::nana::menu* owner;
|
||||
std::vector<menu_type*> 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<renderer_interface>(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_interface>& renderer()
|
||||
@ -321,6 +290,58 @@ namespace nana
|
||||
pat::cloneable<renderer_interface> 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<int>(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<void()> destroy_answer;
|
||||
std::map<std::size_t, info> 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_type> 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;
|
||||
std::unique_ptr<menu> guard{new menu};
|
||||
if (impl_->mbuilder.set_linkage(index, guard->impl_->mbuilder.data(), true))
|
||||
return guard.release();
|
||||
|
||||
if (this->link(index, *sub))
|
||||
{
|
||||
auto& minfo = impl_->sub_container[index];
|
||||
minfo.handle = sub;
|
||||
minfo.kill = true;
|
||||
return sub;
|
||||
}
|
||||
|
||||
delete sub;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -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<int>(impl_->content_size.width) - static_cast<int>(imd_area.width);
|
||||
@ -451,6 +453,8 @@ namespace nana {
|
||||
impl_->origin.y = static_cast<int>(impl_->content_size.height) - static_cast<int>(imd_area.height);
|
||||
|
||||
if (impl_->origin.y < 0) impl_->origin.y = 0;
|
||||
|
||||
return (pre_origin != impl_->origin);
|
||||
}
|
||||
|
||||
void content_view::sync(bool try_update)
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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<int>(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<int>(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<int>(height * row.second);
|
||||
|
||||
const rectangle area_r = { text_area_.area.x, top, width_pixels(), static_cast<unsigned>(height * lines) };
|
||||
|
||||
@ -2839,7 +2841,7 @@ namespace nana{ namespace widgets
|
||||
for (auto & ent : reordered)
|
||||
{
|
||||
auto str_px = static_cast<int>(_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<unsigned>(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<decltype(crtpos.x)>(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<unsigned>(text.size());
|
||||
textbase.insert(points_.caret, std::move(text));
|
||||
|
||||
crtpos.x += static_cast<unsigned>(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<unsigned>(p - pxbuf.get()) + 1;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user