optimize binary size

This commit is contained in:
Jinhao 2016-07-01 23:43:48 +08:00
parent b32afa282c
commit 8c7051566c
13 changed files with 180 additions and 180 deletions

View File

@ -173,7 +173,7 @@ namespace nana
{ {
is_queue<std::is_same<cond_type, nana::null_type>::value, std::vector<handle_type> >::erase(handle, queue_); is_queue<std::is_same<cond_type, nana::null_type>::value, std::vector<handle_type> >::erase(handle, queue_);
cacher_.insert(handle, false); cacher_.insert(handle, false);
trash_.emplace_back(i->first, i->second); trash_.push_back(*i);
holder_.erase(i); holder_.erase(i);
} }
} }

View File

@ -310,7 +310,7 @@ namespace nana{ namespace widgets
unsigned _m_char_by_pixels(const unicode_bidi::entity&, unsigned pos); unsigned _m_char_by_pixels(const unicode_bidi::entity&, unsigned pos);
unsigned _m_pixels_by_char(const ::std::wstring&, std::size_t pos) const; unsigned _m_pixels_by_char(const ::std::wstring&, ::std::size_t pos) const;
void _handle_move_key(const arg_keyboard& arg); void _handle_move_key(const arg_keyboard& arg);
private: private:

View File

@ -135,7 +135,7 @@ namespace skeletons
while(ifs.good()) while(ifs.good())
{ {
std::getline(ifs, str_mbs); std::getline(ifs, str_mbs);
text_cont_.emplace_back(nana::charset(str_mbs)); text_cont_.emplace_back(static_cast<string_type&&>(nana::charset{ str_mbs }));
if(text_cont_.back().size() > attr_max_.size) if(text_cont_.back().size() > attr_max_.size)
{ {
attr_max_.size = text_cont_.back().size(); attr_max_.size = text_cont_.back().size();
@ -218,7 +218,7 @@ namespace skeletons
byte_order_translate_4bytes(str); byte_order_translate_4bytes(str);
} }
text_cont_.emplace_back(nana::charset(str, encoding)); text_cont_.emplace_back(static_cast<string_type&&>(nana::charset{ str, encoding }));
attr_max_.size = text_cont_.back().size(); attr_max_.size = text_cont_.back().size();
attr_max_.line = 0; attr_max_.line = 0;
@ -236,7 +236,7 @@ namespace skeletons
byte_order_translate_4bytes(str); byte_order_translate_4bytes(str);
} }
text_cont_.emplace_back(nana::charset(str, encoding)); text_cont_.emplace_back(static_cast<string_type&&>(nana::charset{ str, encoding }));
if(text_cont_.back().size() > attr_max_.size) if(text_cont_.back().size() > attr_max_.size)
{ {
attr_max_.size = text_cont_.back().size(); attr_max_.size = text_cont_.back().size();
@ -406,7 +406,7 @@ namespace skeletons
void erase_all() void erase_all()
{ {
std::deque<string_type>().swap(text_cont_); text_cont_.clear();
attr_max_.reset(); attr_max_.reset();
text_cont_.emplace_back(); //text_cont_ must not be empty text_cont_.emplace_back(); //text_cont_ must not be empty

View File

@ -1128,7 +1128,7 @@ namespace nana
impl->browse.create(impl->dock); impl->browse.create(impl->dock);
impl->browse.i18n(i18n_eval("Browse")); impl->browse.i18n(i18n_eval("Browse"));
impl->browse.events().click([wd, impl](const arg_click&) impl->browse.events().click.connect_unignorable([wd, impl](const arg_click&)
{ {
impl->fbox.owner(wd); impl->fbox.owner(wd);
if (impl->fbox.show()) if (impl->fbox.show())

View File

@ -268,7 +268,7 @@ namespace nana
#endif #endif
}); });
impl_->evt_destroy = API::events(wd).destroy([this] impl_->evt_destroy = API::events(wd).destroy.connect([this](const arg_destroy&)
{ {
close(); close();
}); });

View File

@ -572,7 +572,7 @@ namespace nana
//Listen to destroy of a window. The deleting a fastened window //Listen to destroy of a window. The deleting a fastened window
//does not change the layout. //does not change the layout.
auto evt = API::events(wd).destroy([this](const arg_destroy& arg) auto evt = API::events(wd).destroy.connect([this](const arg_destroy& arg)
{ {
erase_element(fastened, arg.window_handle); erase_element(fastened, arg.window_handle);
}); });
@ -1015,12 +1015,14 @@ namespace nana
auto find_lowest = [&revises](double level_px) auto find_lowest = [&revises](double level_px)
{ {
double v = (std::numeric_limits<double>::max)(); double v = (std::numeric_limits<double>::max)();
for (auto i = revises.begin(); i != revises.end(); ++i) for (auto i = revises.begin(); i != revises.end(); ++i)
{ {
if (i->min_px >= 0 && i->min_px < v && i->min_px > level_px) auto & rev = *i;
v = i->min_px; if (rev.min_px >= 0 && rev.min_px < v && rev.min_px > level_px)
else if (i->max_px >= 0 && i->max_px < v) v = rev.min_px;
v = i->max_px; else if (rev.max_px >= 0 && rev.max_px < v)
v = rev.max_px;
} }
return v; return v;
}; };
@ -1639,7 +1641,7 @@ namespace nana
indicator_.docker->z_order(nullptr, ::nana::z_order_action::topmost); indicator_.docker->z_order(nullptr, ::nana::z_order_action::topmost);
indicator_.docker->show(); indicator_.docker->show();
indicator_.docker->events().destroy([this](const arg_destroy&) indicator_.docker->events().destroy.connect([this](const arg_destroy&)
{ {
if (indicator_.dock_area) if (indicator_.dock_area)
{ {
@ -1860,9 +1862,9 @@ namespace nana
}; };
auto & evt = this->events(); auto & evt = this->events();
evt.mouse_down(grab_fn); evt.mouse_down.connect(grab_fn);
evt.mouse_up(grab_fn); evt.mouse_up.connect(grab_fn);
evt.mouse_move(grab_fn); evt.mouse_move.connect(grab_fn);
} }
void range(int begin, int end) void range(int begin, int end)
@ -1886,10 +1888,10 @@ namespace nana
division* front() const division* front() const
{ {
for (auto i = children.cbegin(); i != children.cend(); ++i) for (auto & child : children)
{ {
if (i->get()->display) if (child->display)
return i->get(); return child.get();
} }
return nullptr; return nullptr;
@ -2181,7 +2183,7 @@ namespace nana
{ {
auto splitter = new div_splitter(tknizer.number()); auto splitter = new div_splitter(tknizer.number());
children.back()->div_next = splitter; children.back()->div_next = splitter;
children.emplace_back(splitter); children.emplace_back(std::unique_ptr<division>{ splitter });
} }
break; break;
case token::div_start: case token::div_start:
@ -2190,7 +2192,7 @@ namespace nana
if (!children.empty()) if (!children.empty())
children.back()->div_next = div.get(); children.back()->div_next = div.get();
children.emplace_back(div.release()); children.emplace_back(std::move(div));
} }
break; break;
case token::vert: case token::vert:
@ -2430,7 +2432,7 @@ namespace nana
auto dockpn = new div_dockpane(std::move(child->name), this, child->dir); auto dockpn = new div_dockpane(std::move(child->name), this, child->dir);
dockpn->div_owner = child->div_owner; dockpn->div_owner = child->div_owner;
dockpn->weight = child->weight; dockpn->weight = child->weight;
adjusted_children.emplace_back(dockpn); adjusted_children.emplace_back(std::unique_ptr<division>{ dockpn });
} }
division * next = nullptr; division * next = nullptr;
@ -2646,11 +2648,11 @@ namespace nana
implement::division * div_next = div_ptr->div_next; implement::division * div_next = div_ptr->div_next;
if (div_owner) if (div_owner)
{ {
for (auto i = div_owner->children.begin(); i != div_owner->children.end(); ++i) for (auto& child: div_owner->children)
{ {
if (i->get() == div_ptr) if (child.get() == div_ptr)
{ {
replaced = &(*i); replaced = &child;
break; break;
} }
} }
@ -2702,7 +2704,7 @@ namespace nana
{ {
//search the division with the specified name, //search the division with the specified name,
//and attached the division to the field //and attached the division to the field
implement::division * div = implement::search_div_name(impl_->root_division.get(), name); auto div = implement::search_div_name(impl_->root_division.get(), name);
if (div) if (div)
{ {
if (div->field && (div->field != p)) if (div->field && (div->field != p))
@ -2803,12 +2805,11 @@ namespace nana
//Register the factory if it has a name //Register the factory if it has a name
if (!factory_name.empty()) if (!factory_name.empty())
{ {
auto i = impl_->dock_factoris.find(factory_name); if (impl_->dock_factoris.find(factory_name) != impl_->dock_factoris.end())
if (i != impl_->dock_factoris.end())
throw std::invalid_argument("nana::place - the specified factory name(" + factory_name + ") already exists"); throw std::invalid_argument("nana::place - the specified factory name(" + factory_name + ") already exists");
impl_->dock_factoris[factory_name] = dock_ptr; impl_->dock_factoris[factory_name] = dock_ptr;
dock_ptr->factories[factory_name].swap(factory); dock_ptr->factories[factory_name] = std::move(factory);
} }
auto div = dynamic_cast<implement::div_dockpane*>(impl_->search_div_name(impl_->root_division.get(), name)); auto div = dynamic_cast<implement::div_dockpane*>(impl_->search_div_name(impl_->root_division.get(), name));

View File

@ -164,10 +164,7 @@ namespace nana
: public widget_object < category::widget_tag, dockcaption_dtrigger > : public widget_object < category::widget_tag, dockcaption_dtrigger >
{ {
public: public:
void on_close(std::function<void()> fn) using widget_object<category::widget_tag, dockcaption_dtrigger>::get_drawer_trigger;
{
get_drawer_trigger().on_close(std::move(fn));
}
}; };
class dockarea class dockarea
@ -192,7 +189,7 @@ namespace nana
base_type::create(parent, true); base_type::create(parent, true);
this->caption("dockarea"); this->caption("dockarea");
caption_.create(*this, true); caption_.create(*this, true);
caption_.on_close([this] caption_.get_drawer_trigger().on_close([this]
{ {
bool destroy_dockarea = true; bool destroy_dockarea = true;
@ -207,7 +204,7 @@ namespace nana
notifier_->request_close(); notifier_->request_close();
}); });
this->events().resized([this](const arg_resized& arg) this->events().resized.connect([this](const arg_resized& arg)
{ {
rectangle r{ 0, 0, arg.width, 20 }; rectangle r{ 0, 0, arg.width, 20 };
caption_.move(r); caption_.move(r);
@ -272,9 +269,9 @@ namespace nana
} }
}; };
caption_.events().mouse_down(grab_fn); caption_.events().mouse_down.connect(grab_fn);
caption_.events().mouse_move(grab_fn); caption_.events().mouse_move.connect(grab_fn);
caption_.events().mouse_up(grab_fn); caption_.events().mouse_up.connect(grab_fn);
} }
@ -307,7 +304,7 @@ namespace nana
API::set_parent_window(handle(), container_->handle()); API::set_parent_window(handle(), container_->handle());
this->move({ 1, 1 }); this->move({ 1, 1 });
container_->events().resized([this](const arg_resized& arg) container_->events().resized.connect([this](const arg_resized& arg)
{ {
this->size({arg.width - 2, arg.height - 2}); this->size({arg.width - 2, arg.height - 2});
}); });
@ -350,7 +347,7 @@ namespace nana
tabbar_.reset(new tabbar_lite(*this)); tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear(); tabbar_->events().selected.clear();
tabbar_->events().selected([this] tabbar_->events().selected.connect([this](const event_arg&)
{ {
auto handle = tabbar_->attach(tabbar_->selected()); auto handle = tabbar_->attach(tabbar_->selected());
//Set caption through a caption of window specified by handle //Set caption through a caption of window specified by handle

View File

@ -282,17 +282,22 @@ namespace nana
} }
auto & events = API::events(wd); auto & events = API::events(wd);
events.mouse_enter.connect([this](const arg_mouse& arg){
auto & pr = _m_get(arg.window_handle);
if (pr.second.size())
this->show(pr.second);
});
auto leave_fn = [this]{ auto mouse_fn = [this](const arg_mouse& arg)
this->close(); {
if (event_code::mouse_enter == arg.evt_code)
{
auto & pr = _m_get(arg.window_handle);
if (pr.second.size())
this->show(pr.second);
}
else
this->close();
}; };
events.mouse_leave.connect(leave_fn);
events.mouse_down.connect(leave_fn); events.mouse_enter.connect(mouse_fn);
events.mouse_leave.connect(mouse_fn);
events.mouse_down.connect(mouse_fn);
events.destroy.connect([this](const arg_destroy& arg){ events.destroy.connect([this](const arg_destroy& arg){
_m_untip(arg.window_handle); _m_untip(arg.window_handle);

View File

@ -1237,14 +1237,14 @@ namespace nana
return impl_->mbuilder.data().items.at(index).flags.checked; return impl_->mbuilder.data().items.at(index).flags.checked;
} }
void menu::answerer(std::size_t index, const menu::event_fn_t& fn) void menu::answerer(std::size_t index, const event_fn_t& fn)
{ {
impl_->mbuilder.data().items.at(index).functor = fn; impl_->mbuilder.data().items.at(index).functor = fn;
} }
void menu::destroy_answer(const std::function<void()>& f) void menu::destroy_answer(const std::function<void()>& fn)
{ {
impl_->destroy_answer = f; impl_->destroy_answer = fn;
} }
void menu::gaps(const nana::point& pos) void menu::gaps(const nana::point& pos)

View File

@ -610,7 +610,7 @@ namespace nana
::create(wd, rectangle(nana::size(API::window_size(wd).width, 28))); ::create(wd, rectangle(nana::size(API::window_size(wd).width, 28)));
API::dev::set_menubar(handle(), true); API::dev::set_menubar(handle(), true);
evt_resized_ = API::events(wd).resized([this](const ::nana::arg_resized& arg) evt_resized_ = API::events(wd).resized.connect([this](const ::nana::arg_resized& arg)
{ {
auto sz = this->size(); auto sz = this->size();
sz.width = arg.width; sz.width = arg.width;

View File

@ -332,18 +332,18 @@ namespace nana{ namespace widgets
nana::point caret_to_screen(nana::upoint pos) override nana::point caret_to_screen(nana::upoint pos) override
{ {
auto & textbase = editor_.textbase_; pos.y = (std::min)(pos.y, static_cast<unsigned>(editor_.textbase_.lines()));
if (pos.y > static_cast<unsigned>(textbase.lines()))
pos.y = static_cast<unsigned>(textbase.lines());
std::unique_ptr<std::wstring> mask_str; auto text_ptr = &editor_.textbase_.getline(pos.y);
std::wstring mask_str;
if (editor_.mask_char_) if (editor_.mask_char_)
mask_str.reset(new std::wstring(textbase.getline(pos.y).size(), editor_.mask_char_)); {
mask_str.resize(text_ptr->size(), editor_.mask_char_);
text_ptr = &mask_str;
}
auto & lnstr = editor_.mask_char_ ? *mask_str : textbase.getline(pos.y); pos.x = editor_._m_pixels_by_char(*text_ptr, pos.x) + editor_.text_area_.area.x;
pos.x = editor_._m_pixels_by_char(lnstr, pos.x) + editor_.text_area_.area.x;
int pos_y = static_cast<int>((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base()); int pos_y = static_cast<int>((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base());
return{ static_cast<int>(pos.x - editor_.points_.offset.x), pos_y }; return{ static_cast<int>(pos.x - editor_.points_.offset.x), pos_y };
@ -354,21 +354,23 @@ namespace nana{ namespace widgets
nana::upoint res{ 0, static_cast<unsigned>(_m_textline_from_screen(scrpos.y)) }; nana::upoint res{ 0, static_cast<unsigned>(_m_textline_from_screen(scrpos.y)) };
//Convert the screen point to text caret point //Convert the screen point to text caret point
const string_type& real_str = editor_.textbase_.getline(res.y);
std::unique_ptr<std::wstring> mask_str; auto text_ptr = &editor_.textbase_.getline(res.y);
std::wstring mask_str;
if (editor_.mask_char_) if (editor_.mask_char_)
mask_str.reset(new std::wstring(real_str.size(), editor_.mask_char_)); {
mask_str.resize(text_ptr->size(), editor_.mask_char_);
auto & lnstr = (editor_.mask_char_ ? *mask_str : real_str); text_ptr = &mask_str;
if (lnstr.size() > 0) }
if (text_ptr->size() > 0)
{ {
scrpos.x += (editor_.points_.offset.x - editor_.text_area_.area.x); scrpos.x += (editor_.points_.offset.x - editor_.text_area_.area.x);
if (scrpos.x > 0) if (scrpos.x > 0)
{ {
unicode_bidi bidi;
std::vector<unicode_bidi::entity> reordered; std::vector<unicode_bidi::entity> reordered;
bidi.linestr(lnstr.data(), lnstr.size(), reordered); unicode_bidi{}.linestr(text_ptr->c_str(), text_ptr->size(), reordered);
for (auto & ent : reordered) for (auto & ent : reordered)
{ {
@ -377,13 +379,13 @@ namespace nana{ namespace widgets
if (scrpos.x < str_px) if (scrpos.x < str_px)
{ {
res.x = editor_._m_char_by_pixels(ent, static_cast<unsigned>(scrpos.x)); res.x = editor_._m_char_by_pixels(ent, static_cast<unsigned>(scrpos.x));
res.x += static_cast<unsigned>(ent.begin - lnstr.data()); res.x += static_cast<unsigned>(ent.begin - text_ptr->c_str());
return res; return res;
} }
scrpos.x -= str_px; scrpos.x -= str_px;
} }
res.x = static_cast<int>(lnstr.size()); res.x = static_cast<int>(text_ptr->size());
} }
} }
@ -398,10 +400,9 @@ namespace nana{ namespace widgets
{ {
if (points.caret.y) if (points.caret.y)
{ {
points.caret.x = static_cast<unsigned>(editor_.textbase_.getline(--points.caret.y).size()); points.caret.x = (std::min)(points.xpos,
static_cast<unsigned>(editor_.textbase_.getline(--points.caret.y).size())
if (points.xpos < points.caret.x) );
points.caret.x = points.xpos;
bool out_of_screen = (static_cast<int>(points.caret.y) < points.offset.y); bool out_of_screen = (static_cast<int>(points.caret.y) < points.offset.y);
if (out_of_screen) if (out_of_screen)
@ -414,10 +415,9 @@ namespace nana{ namespace widgets
{ {
if (points.caret.y + 1 < editor_.textbase_.lines()) if (points.caret.y + 1 < editor_.textbase_.lines())
{ {
points.caret.x = static_cast<unsigned>(editor_.textbase_.getline(++points.caret.y).size()); points.caret.x = (std::min)(points.xpos,
static_cast<unsigned>(editor_.textbase_.getline(++points.caret.y).size())
if (points.xpos < points.caret.x) );
points.caret.x = points.xpos;
return adjust_caret_into_screen(); return adjust_caret_into_screen();
} }
@ -511,8 +511,8 @@ namespace nana{ namespace widgets
const wchar_t* end; const wchar_t* end;
unsigned pixels; unsigned pixels;
text_section(const wchar_t* ptr, const wchar_t* endptr) text_section(const wchar_t* ptr, const wchar_t* endptr, unsigned px)
: begin(ptr), end(endptr) : begin(ptr), end(endptr), pixels(px)
{} {}
}; };
@ -543,7 +543,7 @@ namespace nana{ namespace widgets
{ {
auto& linestr = editor_.textbase_.getline(line); auto& linestr = editor_.textbase_.getline(line);
auto p = mtr.line_sections.front().begin; auto p = mtr.line_sections.front().begin;
if (p < linestr.data() || (linestr.data() + linestr.size() < p)) if (p < linestr.c_str() || (linestr.c_str() + linestr.size() < p))
pre_calc_line(line, editor_.width_pixels()); pre_calc_line(line, editor_.width_pixels());
++line; ++line;
@ -566,7 +566,7 @@ namespace nana{ namespace widgets
{ {
auto & linestr = editor_.textbase_.getline(line); auto & linestr = editor_.textbase_.getline(line);
auto p = mtr.line_sections.front().begin; auto p = mtr.line_sections.front().begin;
if (p < linestr.data() || (linestr.data() + linestr.size() < p)) if (p < linestr.c_str() || (linestr.c_str() + linestr.size() < p))
pre_calc_line(line, editor_.width_pixels()); pre_calc_line(line, editor_.width_pixels());
} }
++line; ++line;
@ -581,8 +581,8 @@ namespace nana{ namespace widgets
{ {
auto & mtr = linemtr_[line]; auto & mtr = linemtr_[line];
mtr.line_sections.clear(); mtr.line_sections.clear();
mtr.line_sections.emplace_back(lnstr.data(), lnstr.data());
mtr.line_sections.back().pixels = 0; mtr.line_sections.emplace_back(lnstr.c_str(), lnstr.c_str(), unsigned{});
mtr.take_lines = 1; mtr.take_lines = 1;
return; return;
} }
@ -606,8 +606,7 @@ namespace nana{ namespace widgets
{ {
if (text_px != str_w) if (text_px != str_w)
{ {
line_sections.emplace_back(secondary_begin, ts.begin); line_sections.emplace_back(secondary_begin, ts.begin, unsigned{ text_px - str_w });
line_sections.back().pixels = text_px - str_w;
text_px = str_w; text_px = str_w;
secondary_begin = ts.begin; secondary_begin = ts.begin;
} }
@ -630,8 +629,7 @@ namespace nana{ namespace widgets
continue; continue;
const wchar_t * endptr = ts.begin + (pxi - pxptr) + (text_px == pixels ? 1 : 0); const wchar_t * endptr = ts.begin + (pxi - pxptr) + (text_px == pixels ? 1 : 0);
line_sections.emplace_back(secondary_begin, endptr); line_sections.emplace_back(secondary_begin, endptr, unsigned{ text_px - (text_px == pixels ? 0 : *pxi) });
line_sections.back().pixels = text_px - (text_px == pixels ? 0 : *pxi);
secondary_begin = endptr; secondary_begin = endptr;
text_px = (text_px == pixels ? 0 : *pxi); text_px = (text_px == pixels ? 0 : *pxi);
@ -641,8 +639,7 @@ namespace nana{ namespace widgets
} }
else if (text_px == pixels) else if (text_px == pixels)
{ {
line_sections.emplace_back(secondary_begin, ts.begin); line_sections.emplace_back(secondary_begin, ts.begin, unsigned{ text_px - str_w });
line_sections.back().pixels = text_px - str_w;
secondary_begin = ts.begin; secondary_begin = ts.begin;
text_px = str_w; text_px = str_w;
} }
@ -655,8 +652,7 @@ namespace nana{ namespace widgets
if (secondary_begin) if (secondary_begin)
{ {
mtr.line_sections.emplace_back(secondary_begin, sections.back().end); mtr.line_sections.emplace_back(secondary_begin, sections.back().end, unsigned{ text_px });
mtr.line_sections.back().pixels = text_px;
++mtr.take_lines; ++mtr.take_lines;
} }
} }
@ -694,7 +690,7 @@ namespace nana{ namespace widgets
editor_.graph_.rectangle({ editor_.text_area_.area.x, top, editor_.width_pixels(), static_cast<unsigned>(pixels * secondary_before) }, true, API::bgcolor(editor_.window_)); editor_.graph_.rectangle({ editor_.text_area_.area.x, top, editor_.width_pixels(), static_cast<unsigned>(pixels * secondary_before) }, true, API::bgcolor(editor_.window_));
auto fgcolor = API::fgcolor(editor_.window_); auto fgcolor = API::fgcolor(editor_.window_);
auto text_ptr = editor_.textbase_.getline(textline).data(); auto text_ptr = editor_.textbase_.getline(textline).c_str();
for (std::size_t pos = 0; pos < secondary_before; ++pos, top+=pixels) for (std::size_t pos = 0; pos < secondary_before; ++pos, top+=pixels)
{ {
@ -716,7 +712,7 @@ namespace nana{ namespace widgets
return line_index; return line_index;
nana::upoint str_pos(0, static_cast<unsigned>(primary)); nana::upoint str_pos(0, static_cast<unsigned>(primary));
str_pos.x = static_cast<unsigned>(linemtr_[primary].line_sections[secondary].begin - editor_.textbase_.getline(primary).data()); str_pos.x = static_cast<unsigned>(linemtr_[primary].line_sections[secondary].begin - editor_.textbase_.getline(primary).c_str());
int top = editor_._m_text_top_base(); int top = editor_._m_text_top_base();
const unsigned pixels = editor_.line_height(); const unsigned pixels = editor_.line_height();
@ -786,7 +782,7 @@ namespace nana{ namespace widgets
} }
else if (pos.x == chsize) else if (pos.x == chsize)
{ {
scrpos.x = editor_._m_text_extent_size(str.data(), sec.end - sec.begin).width; scrpos.x = editor_._m_text_extent_size(str.c_str(), sec.end - sec.begin).width;
break; break;
} }
else else
@ -814,15 +810,18 @@ namespace nana{ namespace widgets
//First of all, find the text of secondary. //First of all, find the text of secondary.
auto real_str = mtr.line_sections[secondary]; auto real_str = mtr.line_sections[secondary];
std::unique_ptr<std::wstring> mask_str; auto text_ptr = real_str.begin;
if (editor_.mask_char_) const auto text_size = real_str.end - real_str.begin;
mask_str.reset(new std::wstring(real_str.end - real_str.begin, editor_.mask_char_));
const wchar_t * str = (editor_.mask_char_ ? mask_str->data() : real_str.begin); std::wstring mask_str;
if (editor_.mask_char_)
{
mask_str.resize(text_size, editor_.mask_char_);
text_ptr = mask_str.c_str();
}
std::vector<unicode_bidi::entity> reordered; std::vector<unicode_bidi::entity> reordered;
unicode_bidi bidi; unicode_bidi{}.linestr(text_ptr, text_size, reordered);
bidi.linestr(str, real_str.end - real_str.begin, reordered);
nana::upoint res(static_cast<unsigned>(real_str.begin - mtr.line_sections.front().begin), static_cast<unsigned>(primary)); nana::upoint res(static_cast<unsigned>(real_str.begin - mtr.line_sections.front().begin), static_cast<unsigned>(primary));
scrpos.x -= editor_.text_area_.area.x; scrpos.x -= editor_.text_area_.area.x;
@ -831,12 +830,11 @@ namespace nana{ namespace widgets
for (auto & ent : reordered) for (auto & ent : reordered)
{ {
std::size_t len = ent.end - ent.begin; auto str_px = static_cast<int>(editor_._m_text_extent_size(ent.begin, ent.end - ent.begin).width);
auto str_px = static_cast<int>(editor_._m_text_extent_size(ent.begin, len).width);
if (scrpos.x < str_px) if (scrpos.x < str_px)
{ {
res.x += editor_._m_char_by_pixels(ent, scrpos.x); res.x += editor_._m_char_by_pixels(ent, scrpos.x);
res.x += static_cast<unsigned>(ent.begin - str); res.x += static_cast<unsigned>(ent.begin - text_ptr);
return res; return res;
} }
scrpos.x -= str_px; scrpos.x -= str_px;
@ -929,13 +927,13 @@ namespace nana{ namespace widgets
{ {
if (str.empty()) if (str.empty())
{ {
tsec.emplace_back(str.data(), str.data()); tsec.emplace_back(str.c_str(), str.c_str(), unsigned{});
return; return;
} }
const auto end = str.data() + str.size(); const auto end = str.c_str() + str.size();
const wchar_t * word = nullptr; const wchar_t * word = nullptr;
for (auto i = str.data(); i != end; ++i) for (auto i = str.c_str(); i != end; ++i)
{ {
wchar_t const ch = *i; wchar_t const ch = *i;
@ -944,11 +942,11 @@ namespace nana{ namespace widgets
{ {
if (word) //Record the word. if (word) //Record the word.
{ {
tsec.emplace_back(word, i); tsec.emplace_back(word, i, unsigned{});
word = nullptr; word = nullptr;
} }
tsec.emplace_back(i, i + 1); tsec.emplace_back(i, i + 1, unsigned{});
continue; continue;
} }
@ -957,7 +955,7 @@ namespace nana{ namespace widgets
} }
if(word) if(word)
tsec.emplace_back(word, end); tsec.emplace_back(word, end, unsigned{});
} }
void _m_set_offset_by_secondary(std::size_t primary, std::size_t secondary) void _m_set_offset_by_secondary(std::size_t primary, std::size_t secondary)
@ -1054,7 +1052,7 @@ namespace nana{ namespace widgets
unsigned len = static_cast<unsigned>(section.end - section.begin); unsigned len = static_cast<unsigned>(section.end - section.begin);
auto chptr = section.begin + (secondary.x > len ? len : secondary.x); auto chptr = section.begin + (secondary.x > len ? len : secondary.x);
pos = static_cast<unsigned>(chptr - editor_.textbase_.getline(textline).data()); pos = static_cast<unsigned>(chptr - editor_.textbase_.getline(textline).c_str());
return true; return true;
} }
@ -1179,25 +1177,6 @@ namespace nana{ namespace widgets
std::vector<entity> entities; std::vector<entity> entities;
auto test_whole_word = [&text](index pos, index len)
{
if (pos)
{
auto chr = text[pos - 1];
if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_')
return false;
}
if (pos + len < text.size())
{
auto chr = text[pos + len];
if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_')
return false;
}
return true;
};
::nana::ciwstring cistr; ::nana::ciwstring cistr;
for (auto & ds : kwptr->kwbase) for (auto & ds : kwptr->kwbase)
{ {
@ -1212,22 +1191,22 @@ namespace nana{ namespace widgets
if (ds.whole_word_matched) if (ds.whole_word_matched)
{ {
if (!test_whole_word(pos, ds.text.size())) if (!_m_whole_word(text, pos, ds.text.size()))
continue; continue;
} }
} }
else else
{ {
if (cistr.empty()) if (cistr.empty())
cistr.append(text.data(), text.size()); cistr.append(text.c_str(), text.size());
pos = cistr.find(ds.text.data(), pos); pos = cistr.find(ds.text.c_str(), pos);
if (pos == cistr.npos) if (pos == cistr.npos)
break; break;
if (ds.whole_word_matched) if (ds.whole_word_matched)
{ {
if (!test_whole_word(pos, ds.text.size())) if (!_m_whole_word(text, pos, ds.text.size()))
continue; continue;
} }
} }
@ -1237,7 +1216,7 @@ namespace nana{ namespace widgets
{ {
entities.emplace_back(); entities.emplace_back();
auto & last = entities.back(); auto & last = entities.back();
last.begin = text.data() + pos; last.begin = text.c_str() + pos;
last.end = last.begin + ds.text.size(); last.end = last.begin + ds.text.size();
last.scheme = ki->second.get(); last.scheme = ki->second.get();
} }
@ -1270,6 +1249,25 @@ namespace nana{ namespace widgets
{ {
return entities_; return entities_;
} }
private:
static bool _m_whole_word(const std::wstring& text, std::wstring::size_type pos, std::size_t len)
{
if (pos)
{
auto chr = text[pos - 1];
if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_')
return false;
}
if (pos + len < text.size())
{
auto chr = text[pos + len];
if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_')
return false;
}
return true;
}
private: private:
std::vector<entity> entities_; std::vector<entity> entities_;
}; };
@ -1343,6 +1341,7 @@ namespace nana{ namespace widgets
return; return;
} }
} }
keywords_->kwbase.emplace_back(kw, name, case_sensitive, whole_word_matched); keywords_->kwbase.emplace_back(kw, name, case_sensitive, whole_word_matched);
} }
@ -1448,7 +1447,7 @@ namespace nana{ namespace widgets
void text_editor::indent(bool enb, std::function<std::string()> generator) void text_editor::indent(bool enb, std::function<std::string()> generator)
{ {
indent_.enabled = enb; indent_.enabled = enb;
indent_.generator.swap(generator); indent_.generator = std::move(generator);
} }
void text_editor::set_event(event_interface* ptr) void text_editor::set_event(event_interface* ptr)
@ -2030,7 +2029,7 @@ namespace nana{ namespace widgets
{ {
if(text_area_.vscroll && text_area_.hscroll) if(text_area_.vscroll && text_area_.hscroll)
{ {
graph_.rectangle({ text_area_.area.right() - static_cast<int>(text_area_.vscroll), text_area_.area.bottom() - static_cast<int>(text_area_.hscroll), text_area_.vscroll, text_area_.hscroll }, graph_.rectangle(rectangle{ text_area_.area.right() - static_cast<int>(text_area_.vscroll), text_area_.area.bottom() - static_cast<int>(text_area_.hscroll), text_area_.vscroll, text_area_.hscroll },
true, colors::button_face); true, colors::button_face);
} }
} }
@ -2054,17 +2053,16 @@ namespace nana{ namespace widgets
ext_renderer_.background(graph_, text_area_.area, bgcolor); ext_renderer_.background(graph_, text_area_.area, bgcolor);
if(attributes_.counterpart && !text_area_.area.empty()) if(attributes_.counterpart && !text_area_.area.empty())
attributes_.counterpart.bitblt(nana::rectangle(0, 0, text_area_.area.width, text_area_.area.height), graph_, nana::point(text_area_.area.x, text_area_.area.y)); attributes_.counterpart.bitblt(rectangle{ text_area_.area.dimension() }, graph_, text_area_.area.position());
//Render the content when the text isn't empty or the window has got focus, //Render the content when the text isn't empty or the window has got focus,
//otherwise draw the tip string. //otherwise draw the tip string.
if ((false == textbase_.empty()) || has_focus) if ((false == textbase_.empty()) || has_focus)
{ {
auto && text_pos = behavior_->render(fgcolor); auto text_pos = behavior_->render(fgcolor);
if (text_pos.empty()) if (text_pos.empty())
text_pos.push_back({ 0, 0 }); text_pos.push_back(upoint{});
if (text_pos != text_position_) if (text_pos != text_position_)
{ {
@ -2077,7 +2075,7 @@ namespace nana{ namespace widgets
graph_.string({ text_area_.area.x - points_.offset.x, text_area_.area.y }, attributes_.tip_string, static_cast<color_rgb>(0x787878)); graph_.string({ text_area_.area.x - points_.offset.x, text_area_.area.y }, attributes_.tip_string, static_cast<color_rgb>(0x787878));
if (text_position_.empty()) if (text_position_.empty())
text_position_.push_back({ 0, 0 }); text_position_.push_back(upoint{});
draw_corner(); draw_corner();
@ -2086,6 +2084,9 @@ namespace nana{ namespace widgets
//public: //public:
void text_editor::put(std::wstring text) void text_editor::put(std::wstring text)
{ {
if (text.empty())
return;
auto undo_ptr = std::unique_ptr<undo_input_text>{ new undo_input_text(*this, text) }; auto undo_ptr = std::unique_ptr<undo_input_text>{ new undo_input_text(*this, text) };
undo_ptr->set_selected_text(); undo_ptr->set_selected_text();
@ -2222,27 +2223,21 @@ namespace nana{ namespace widgets
if (indent_.enabled) if (indent_.enabled)
{ {
std::wstring indent_text;
if (indent_.generator) if (indent_.generator)
{ {
indent_text = to_wstring(indent_.generator()); put(to_wstring(indent_.generator()));
} }
else else
{ {
auto & text = textbase_.getline(points_.caret.y - 1); auto & text = textbase_.getline(points_.caret.y - 1);
auto indent_pos = text.find_first_not_of(L"\t "); auto indent_pos = text.find_first_not_of(L"\t ");
if (indent_pos != std::wstring::npos) if (indent_pos != std::wstring::npos)
indent_text = text.substr(0, indent_pos); put(text.substr(0, indent_pos));
else else
indent_text = text; put(text);
} }
if (indent_text.size())
put(indent_text);
} }
if (behavior_->adjust_caret_into_screen() || need_refresh) if (behavior_->adjust_caret_into_screen() || need_refresh)
render(true); render(true);
@ -2906,7 +2901,7 @@ namespace nana{ namespace widgets
bool text_editor::_m_resolve_text(const std::wstring& text, std::vector<std::pair<std::size_t, std::size_t>> & lines) bool text_editor::_m_resolve_text(const std::wstring& text, std::vector<std::pair<std::size_t, std::size_t>> & lines)
{ {
auto const text_str = text.data(); auto const text_str = text.c_str();
std::size_t begin = 0; std::size_t begin = 0;
while (true) while (true)
{ {
@ -2932,14 +2927,14 @@ namespace nana{ namespace widgets
auto eats = eat_endl(chp, 0); auto eats = eat_endl(chp, 0);
if (eats) if (eats)
{ {
lines.emplace_back(0, 0); lines.emplace_back();
chp += (eats - 1); chp += (eats - 1);
} }
} }
if (text.npos == begin) if (text.npos == begin)
{ {
lines.emplace_back(0, 0); lines.emplace_back();
break; break;
} }
} }
@ -3130,7 +3125,7 @@ namespace nana{ namespace widgets
if (str <= ent.begin && ent.begin < str_end) if (str <= ent.begin && ent.begin < str_end)
{ {
ent_begin = ent.begin; ent_begin = ent.begin;
ent_off = std::accumulate(glyphs, glyphs + (ent.begin - str), 0); ent_off = static_cast<int>(std::accumulate(glyphs, glyphs + (ent.begin - str), unsigned{}));
} }
else if (ent.begin <= str && str < ent.end) else if (ent.begin <= str && str < ent.end)
ent_begin = str; ent_begin = str;
@ -3146,16 +3141,17 @@ namespace nana{ namespace widgets
canvas.rectangle(true); canvas.rectangle(true);
ent_pos.x += ent_off; ent_pos.x += ent_off;
if (rtl) if (rtl)
{ {
//draw the whole text if it is a RTL text, because Arbic language is transformable. //draw the whole text if it is a RTL text, because Arbic language is transformable.
canvas.string({}, str, len); canvas.string({}, str, len);
graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 }); graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas, point{ ent_off, 0 });
} }
else else
{ {
canvas.string({}, ent_begin, ent_end - ent_begin); canvas.string({}, ent_begin, ent_end - ent_begin);
graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas); graph_.bitblt(rectangle{ ent_pos, size{ ent_pixels, canvas.height() } }, canvas);
} }
} }
} }
@ -3163,24 +3159,26 @@ namespace nana{ namespace widgets
void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const std::wstring& str, bool if_mask) const void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const std::wstring& str, bool if_mask) const
{ {
::nana::point text_pos{ text_area_.area.x - points_.offset.x, top }; point text_pos{ text_area_.area.x - points_.offset.x, top };
const int text_right = text_area_.area.right(); const int text_right = text_area_.area.right();
std::unique_ptr<std::wstring> mask_str; auto text_ptr = &str;
std::wstring mask_str;
if (if_mask && mask_char_) if (if_mask && mask_char_)
mask_str.reset(new std::wstring(str.size(), mask_char_)); {
mask_str.resize(str.size(), mask_char_);
text_ptr = &mask_str;
}
bool focused = API::is_focus_ready(window_); const auto focused = API::is_focus_ready(window_);
auto & linestr = (if_mask && mask_char_ ? *mask_str : str);
unicode_bidi bidi;
std::vector<unicode_bidi::entity> reordered; std::vector<unicode_bidi::entity> reordered;
bidi.linestr(linestr.c_str(), linestr.size(), reordered); unicode_bidi{}.linestr(text_ptr->c_str(), text_ptr->size(), reordered);
//Parse highlight keywords //Parse highlight keywords
keyword_parser parser; keyword_parser parser;
parser.parse(linestr, keywords_.get()); parser.parse(*text_ptr, keywords_.get());
auto whitespace_w = graph_.text_extent_size(L" ", 1).width; auto whitespace_w = graph_.text_extent_size(L" ", 1).width;
@ -3233,7 +3231,7 @@ namespace nana{ namespace widgets
graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_h_pixels), graph); graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_h_pixels), graph);
}; };
const wchar_t * strbeg = linestr.c_str(); auto const strbeg = text_ptr->c_str();
if (a.y == b.y) if (a.y == b.y)
{ {
for (auto & ent : reordered) for (auto & ent : reordered)
@ -3242,7 +3240,7 @@ namespace nana{ namespace widgets
unsigned str_w = graph_.text_extent_size(ent.begin, len).width; unsigned str_w = graph_.text_extent_size(ent.begin, len).width;
if ((text_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_pos.x < text_right)) if ((text_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_pos.x < text_right))
{ {
std::size_t pos = ent.begin - strbeg + str_pos.x; auto const pos = ent.begin - strbeg + str_pos.x;
const auto str_end = pos + len; const auto str_end = pos + len;
//NOT selected or seleceted all //NOT selected or seleceted all
@ -3460,7 +3458,7 @@ namespace nana{ namespace widgets
if (is_right_text(ent)) if (is_right_text(ent))
{ {
auto total_px = std::accumulate(pxbuf.get(), px_end, static_cast<unsigned>(0)); auto total_px = std::accumulate(pxbuf.get(), px_end, unsigned{});
for (auto p = pxbuf.get(); p != px_end; ++p) for (auto p = pxbuf.get(); p != px_end; ++p)
{ {
@ -3499,17 +3497,16 @@ namespace nana{ namespace widgets
if (pos > lnstr.size()) if (pos > lnstr.size())
return 0; return 0;
unicode_bidi bidi;
std::vector<unicode_bidi::entity> reordered; std::vector<unicode_bidi::entity> reordered;
bidi.linestr(lnstr.data(), lnstr.size(), reordered); unicode_bidi{}.linestr(lnstr.c_str(), lnstr.size(), reordered);
auto ch = lnstr.data() + pos; auto target = lnstr.c_str() + pos;
unsigned text_w = 0; unsigned text_w = 0;
for (auto & ent : reordered) for (auto & ent : reordered)
{ {
std::size_t len = ent.end - ent.begin; std::size_t len = ent.end - ent.begin;
if (ent.begin <= ch && ch <= ent.end) if (ent.begin <= target && target <= ent.end)
{ {
if (is_right_text(ent)) if (is_right_text(ent))
{ {
@ -3517,10 +3514,10 @@ namespace nana{ namespace widgets
//RTL //RTL
std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]); std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
graph_.glyph_pixels(ent.begin, len, pxbuf.get()); graph_.glyph_pixels(ent.begin, len, pxbuf.get());
return std::accumulate(pxbuf.get() + (ch - ent.begin), pxbuf.get() + len, text_w); return std::accumulate(pxbuf.get() + (target - ent.begin), pxbuf.get() + len, text_w);
} }
//LTR //LTR
return text_w + _m_text_extent_size(ent.begin, ch - ent.begin).width; return text_w + _m_text_extent_size(ent.begin, target - ent.begin).width;
} }
else else
text_w += _m_text_extent_size(ent.begin, len).width; text_w += _m_text_extent_size(ent.begin, len).width;

View File

@ -162,7 +162,7 @@ namespace nana
{ {
for (auto & s : initlist) for (auto & s : initlist)
{ {
texts_.emplace_back(::nana::charset(s, ::nana::unicode::utf8)); texts_.emplace_back(std::string{ s });
} }
} }

View File

@ -271,7 +271,7 @@ namespace nana
if (i == mgr.table.end()) if (i == mgr.table.end())
{ {
auto result = mgr.table.emplace(wd, std::move(eval)); auto result = mgr.table.emplace(wd, std::move(eval));
result.first->second.destroy = nana::API::events(wd).destroy([wd]{ result.first->second.destroy = nana::API::events(wd).destroy.connect([wd](const arg_destroy&){
auto & eval_mgr = get_eval_manager(); auto & eval_mgr = get_eval_manager();
std::lock_guard<std::recursive_mutex> lockgd(eval_mgr.mutex); std::lock_guard<std::recursive_mutex> lockgd(eval_mgr.mutex);