Merge branch 'hotfix-1.6.1' into develop
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
#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<iterator> 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<element> 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<pixel_tag> pixels;
|
||||
#else
|
||||
std::vector<visual_line> 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<std::vector<pixel_tag> > pixel_lines;
|
||||
#else
|
||||
//All visual lines data of whole text.
|
||||
std::deque<std::vector<visual_line>> 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<int>(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<int>(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<int>(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<unsigned>(px.pixels);
|
||||
#else
|
||||
for (auto& vsline : rs.vslines)
|
||||
retsize.height += static_cast<unsigned>(vsline.extent_height_px);
|
||||
#endif
|
||||
}
|
||||
|
||||
return retsize;
|
||||
@@ -287,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);
|
||||
@@ -387,23 +330,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<int>(rs.allowed_width - w) >> 1);
|
||||
break;
|
||||
case align::right:
|
||||
px.x_base = static_cast<int>(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,15 +345,28 @@ namespace nana
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VISUAL_LINES
|
||||
|
||||
/**
|
||||
* prepare data for rendering a line of text.
|
||||
*/
|
||||
unsigned _m_prepare_visual_lines(graph_reference graph, dstream::linecontainer& line, unsigned def_line_px, render_status& rs)
|
||||
{
|
||||
if (line.empty())
|
||||
{
|
||||
//Insert an empty visual line for empty content.
|
||||
#ifdef _nana_std_has_emplace_return_type
|
||||
auto & vsline = rs.vslines.emplace_back();
|
||||
#else
|
||||
rs.vslines.emplace_back();
|
||||
auto & vsline = rs.vslines.back();
|
||||
|
||||
vsline.baseline = 0;
|
||||
vsline.extent_height_px = def_line_px;
|
||||
vsline.x_base = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned abs_text_px = 0;
|
||||
unsigned max_ascent = 0;
|
||||
unsigned max_descent = 0;
|
||||
@@ -479,7 +418,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();
|
||||
@@ -530,7 +469,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();
|
||||
@@ -564,7 +503,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();
|
||||
@@ -596,189 +535,16 @@ 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<unsigned>(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<iterator> 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<unsigned>(data_ptr->ascent());
|
||||
ds = static_cast<unsigned>(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<int>(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<int>(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<int>(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;
|
||||
@@ -796,7 +562,7 @@ namespace nana
|
||||
}
|
||||
|
||||
++rs.index; //next line index
|
||||
rs.pos.y += vsline.extent_height_px;
|
||||
rs.pos.y += static_cast<int>(vsline.extent_height_px);
|
||||
|
||||
if (rs.pos.y > bottom)
|
||||
return false;
|
||||
@@ -804,20 +570,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<int>(rs.allowed_width) : right > static_cast<int>(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 +585,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<int>(px.pixels - data_ptr->size().height) / 2;
|
||||
case fblock::aligns::bottom:
|
||||
return static_cast<int>(px.pixels - data_ptr->size().height);
|
||||
case fblock::aligns::baseline:
|
||||
return static_cast<int>(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 +628,6 @@ namespace nana
|
||||
rs.pos.x += static_cast<int>(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<int>(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<int>(text_extent_size.width) > range_text_area) && (rs.pos.x != px.x_base))
|
||||
{
|
||||
//Change a new line
|
||||
rs.pos.y += static_cast<int>(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<int>(rs.allowed_width) - rs.pos.x;
|
||||
nana::size text_extent_size = data_ptr->size();
|
||||
if ((static_cast<int>(text_extent_size.width) > w) && (rs.pos.x != px.x_base))
|
||||
{
|
||||
//Change a new line
|
||||
rs.pos.y += static_cast<int>(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<int>(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<std::size_t, std::size_t> _m_locate(dstream::linecontainer::iterator& i, std::size_t pos)
|
||||
{
|
||||
|
||||
@@ -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<size_type>(cont_.size())).index;
|
||||
#else
|
||||
cont_.emplace_back(ess, std::move(text), pixels, static_cast<size_type>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<unsigned>(lines.back().second - lines.back().first), static_cast<unsigned>(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)
|
||||
@@ -1004,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();
|
||||
@@ -1192,9 +1201,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 +1690,7 @@ namespace nana{ namespace widgets
|
||||
auto undo_ptr = std::unique_ptr<undo_input_text>{ 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 +1707,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 +1915,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 +2033,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 +2044,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 +2074,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 +2084,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();
|
||||
@@ -2086,6 +2102,10 @@ namespace nana{ namespace widgets
|
||||
|
||||
void text_editor::copy() const
|
||||
{
|
||||
//Disallows 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_));
|
||||
@@ -2103,7 +2123,7 @@ namespace nana{ namespace widgets
|
||||
|
||||
if ((accepts::no_restrict == impl_->capacities.acceptive) || !impl_->capacities.pred_acceptive)
|
||||
{
|
||||
put(move(text));
|
||||
put(move(text), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2121,13 +2141,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;
|
||||
@@ -2135,7 +2155,7 @@ namespace nana{ namespace widgets
|
||||
auto undo_ptr = std::unique_ptr<undo_input_text>(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();
|
||||
|
||||
@@ -2173,21 +2193,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)
|
||||
@@ -2211,10 +2234,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<undo_backspace>(new undo_backspace(*this));
|
||||
bool has_to_redraw = true;
|
||||
@@ -2254,7 +2277,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();
|
||||
}
|
||||
|
||||
@@ -2263,6 +2286,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();
|
||||
@@ -2956,7 +2984,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;
|
||||
@@ -2998,10 +3026,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))
|
||||
@@ -3023,6 +3054,9 @@ namespace nana{ namespace widgets
|
||||
_m_pre_calc_lines(a.y, 1);
|
||||
}
|
||||
|
||||
if (perform_event)
|
||||
textbase.text_changed();
|
||||
|
||||
select_.a = select_.b;
|
||||
return a;
|
||||
}
|
||||
@@ -3235,8 +3269,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);
|
||||
@@ -3245,8 +3279,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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -449,7 +449,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());
|
||||
@@ -466,7 +466,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());
|
||||
|
||||
Reference in New Issue
Block a user