code review

This commit is contained in:
Jinhao 2015-10-22 00:02:27 +08:00
parent 5590dd293b
commit fb3b1d51d4
7 changed files with 180 additions and 195 deletions

View File

@ -208,7 +208,7 @@ namespace nana{ namespace widgets
/// Sets caret position through text coordinate. /// Sets caret position through text coordinate.
void move_caret(const upoint&); void move_caret(const upoint&);
void move_caret_end(); void move_caret_end();
void reset_caret_height() const; void reset_caret_pixels() const;
void reset_caret(); void reset_caret();
void show_caret(bool isshow); void show_caret(bool isshow);
@ -216,8 +216,10 @@ namespace nana{ namespace widgets
bool select(bool); bool select(bool);
/// Sets the end position of a selected string. /// Sets the end position of a selected string.
void set_end_caret(); void set_end_caret();
bool hit_text_area(const point&) const; bool hit_text_area(const point&) const;
bool hit_select_area(nana::upoint pos) const; bool hit_select_area(nana::upoint pos) const;
bool move_select(); bool move_select();
bool mask(char_t); bool mask(char_t);
@ -245,8 +247,8 @@ namespace nana{ namespace widgets
void move_ns(bool to_north); //Moves up and down void move_ns(bool to_north); //Moves up and down
void move_left(); void move_left();
void move_right(); void move_right();
upoint mouse_caret(const point& screen_pos); const upoint& mouse_caret(const point& screen_pos);
upoint caret() const; const upoint& caret() const;
point caret_screen_pos() const; point caret_screen_pos() const;
bool scroll(bool upwards, bool vertical); bool scroll(bool upwards, bool vertical);
bool mouse_enter(bool); bool mouse_enter(bool);
@ -256,8 +258,6 @@ namespace nana{ namespace widgets
skeletons::textbase<nana::char_t>& textbase(); skeletons::textbase<nana::char_t>& textbase();
const skeletons::textbase<nana::char_t>& textbase() const; const skeletons::textbase<nana::char_t>& textbase() const;
std::vector<unsigned> get_lines() const;
private: private:
bool _m_accepts(char_type) const; bool _m_accepts(char_type) const;
::nana::color _m_bgcolor() const; ::nana::color _m_bgcolor() const;
@ -283,10 +283,8 @@ namespace nana{ namespace widgets
int _m_text_top_base() const; int _m_text_top_base() const;
/// Returns the right point of text area. /// Returns the right/bottom point of text area.
int _m_endx() const; int _m_end_pos(bool right) const;
/// Returns the bottom point of text area.
int _m_endy() const;
void _m_draw_parse_string(const keyword_parser&, bool rtl, ::nana::point pos, const ::nana::color& fgcolor, const ::nana::char_t*, std::size_t len) const; void _m_draw_parse_string(const keyword_parser&, bool rtl, ::nana::point pos, const ::nana::color& fgcolor, const ::nana::char_t*, std::size_t len) const;
//_m_draw_string //_m_draw_string
@ -302,7 +300,6 @@ namespace nana{ namespace widgets
unsigned _m_char_by_pixels(const nana::char_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl); unsigned _m_char_by_pixels(const nana::char_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl);
unsigned _m_pixels_by_char(const nana::string&, std::size_t pos) const; unsigned _m_pixels_by_char(const nana::string&, std::size_t pos) const;
static bool _m_is_right_text(const unicode_bidi::entity&);
void _handle_move_key(const arg_keyboard& arg); void _handle_move_key(const arg_keyboard& arg);
private: private:

View File

@ -249,60 +249,58 @@ namespace skeletons
return true; return true;
} }
void store(nana::string fs) const void store(nana::string fs, bool is_unicode, ::nana::unicode encoding) const
{ {
std::string fs_mbs = nana::charset(fs); std::string fs_mbs = nana::charset(fs);
std::ofstream ofs(fs_mbs.data(), std::ios::binary); std::ofstream ofs(fs_mbs.data(), std::ios::binary);
if(ofs && text_cont_.size()) if(ofs && text_cont_.size())
{ {
if(text_cont_.size() > 1) std::string last_mbs;
if (is_unicode)
{ {
for(auto i = text_cont_.cbegin(), end = text_cont_.cend() - 1; i != end; ++i) const char * le_boms[] = { "\xEF\xBB\xBF", "\xFF\xFE", "\xFF\xFE\x0\x0" }; //BOM for little-endian
int bytes = 0;
switch (encoding)
{ {
std::string mbs = nana::charset(*i); case nana::unicode::utf8:
ofs.write(mbs.c_str(), mbs.size()); bytes = 3; break;
ofs.write("\r\n", 2); case nana::unicode::utf16:
bytes = 2; break;
case nana::unicode::utf32:
bytes = 4; break;
} }
}
std::string mbs = nana::charset(text_cont_.back());
ofs.write(mbs.c_str(), mbs.size());
_m_saved(std::move(fs));
}
}
void store(nana::string fs, nana::unicode encoding) const if (bytes)
{ ofs.write(le_boms[static_cast<int>(encoding)], bytes);
std::string fs_mbs = nana::charset(fs);
std::ofstream ofs(fs_mbs.data(), std::ios::binary);
if(ofs && text_cont_.size())
{
const char * le_boms[] = {"\xEF\xBB\xBF", "\xFF\xFE", "\xFF\xFE\x0\x0"}; //BOM for little-endian
int bytes = 0;
switch(encoding)
{
case nana::unicode::utf8:
bytes = 3; break;
case nana::unicode::utf16:
bytes = 2; break;
case nana::unicode::utf32:
bytes = 4; break;
}
if(bytes) if (text_cont_.size() > 1)
ofs.write(le_boms[static_cast<int>(encoding)], bytes);
if(text_cont_.size() > 1)
{
std::string mbs;
for(auto i = text_cont_.cbegin(), end = text_cont_.cend() - 1; i != end; ++i)
{ {
mbs = nana::charset(*i).to_bytes(encoding); std::string mbs;
mbs += "\r\n"; for (auto i = text_cont_.cbegin(), end = text_cont_.cend() - 1; i != end; ++i)
ofs.write(mbs.c_str(), static_cast<std::streamsize>(mbs.size())); {
std::string(nana::charset(*i).to_bytes(encoding)).swap(mbs);
mbs += "\r\n";
ofs.write(mbs.c_str(), static_cast<std::streamsize>(mbs.size()));
}
} }
last_mbs = nana::charset(text_cont_.back()).to_bytes(encoding);
} }
std::string mbs = nana::charset(text_cont_.back()).to_bytes(encoding); else
ofs.write(mbs.c_str(), static_cast<std::streamsize>(mbs.size())); {
if (text_cont_.size() > 1)
{
for (auto i = text_cont_.cbegin(), end = text_cont_.cend() - 1; i != end; ++i)
{
std::string mbs = nana::charset(*i);
ofs.write(mbs.c_str(), mbs.size());
ofs.write("\r\n", 2);
}
}
last_mbs = nana::charset(text_cont_.back());
}
ofs.write(last_mbs.c_str(), static_cast<std::streamsize>(last_mbs.size()));
_m_saved(std::move(fs)); _m_saved(std::move(fs));
} }
} }

View File

@ -28,7 +28,66 @@ namespace nana
namespace detail namespace detail
{ {
template<typename Key, typename Value>
class lite_map
{
struct key_value_rep
{
Key first;
Value second;
key_value_rep()
: first{}, second{}
{}
key_value_rep(const Key& k)
: first(k), second{}
{
}
};
public:
using iterator = typename std::vector<key_value_rep>::iterator;
Value& operator[](const Key& key)
{
for (auto& kv : table_)
{
if (kv.first == key)
return kv.second;
}
table_.emplace_back(key);
return table_.back().second;
}
iterator find(const Key& key)
{
for (auto i = table_.begin(); i != table_.end(); ++i)
if (i->first == key)
return i;
return table_.end();
}
iterator erase(iterator pos)
{
return table_.erase(pos);
}
iterator begin()
{
return table_.begin();
}
iterator end()
{
return table_.end();
}
private:
std::vector<key_value_rep> table_;
};
//class window_manager //class window_manager
struct window_handle_deleter struct window_handle_deleter
{ {
void operator()(basic_window* wd) const void operator()(basic_window* wd) const
@ -37,6 +96,7 @@ namespace detail
delete wd; delete wd;
} }
}; };
//struct wdm_private_impl //struct wdm_private_impl
struct window_manager::wdm_private_impl struct window_manager::wdm_private_impl
{ {
@ -45,7 +105,7 @@ namespace detail
paint::image default_icon_big; paint::image default_icon_big;
paint::image default_icon_small; paint::image default_icon_small;
std::map<core_window_t*, std::vector<std::function<void()>>> safe_place; lite_map<core_window_t*, std::vector<std::function<void()>>> safe_place;
}; };
//end struct wdm_private_impl //end struct wdm_private_impl
@ -155,7 +215,7 @@ namespace detail
bool window_manager::is_queue(core_window_t* wd) bool window_manager::is_queue(core_window_t* wd)
{ {
return (wd && (wd->other.category == category::root_tag::value)); return (wd && (category::flags::root == wd->other.category));
} }
std::size_t window_manager::number_of_core_window() const std::size_t window_manager::number_of_core_window() const
@ -218,7 +278,7 @@ namespace detail
if (owner->flags.destroying) if (owner->flags.destroying)
throw std::logic_error("the specified owner is destory"); throw std::logic_error("the specified owner is destory");
native = (owner->other.category == category::frame_tag::value ? native = (category::flags::frame == owner->other.category ?
owner->other.attribute.frame->container : owner->root_widget->root); owner->other.attribute.frame->container : owner->root_widget->root);
r.x += owner->pos_root.x; r.x += owner->pos_root.x;
r.y += owner->pos_root.y; r.y += owner->pos_root.y;
@ -1224,6 +1284,7 @@ namespace detail
else else
++i; ++i;
} }
} }
bool check_tree(basic_window* wd, basic_window* const cond) bool check_tree(basic_window* wd, basic_window* const cond)

View File

@ -637,11 +637,7 @@ namespace nana
void set_display(bool dsp) void set_display(bool dsp)
{ {
if (field) set_visible(dsp);
field->visible(dsp);
_m_visible_for_child(this, dsp);
visible = dsp;
display = dsp; display = dsp;
if (kind::splitter != kind_of_division) if (kind::splitter != kind_of_division)

View File

@ -578,66 +578,6 @@ namespace nana
return false; return false;
} }
/*
void trigger::_m_draw()
{
auto bgcolor = API::bgcolor(*widget_);
graph_->rectangle(true, bgcolor);
item_renderer ird(*widget_, *graph_);
nana::point item_pos(2, 2);
nana::size item_s(0, 23);
unsigned long index = 0;
for(auto i : items_->cont())
{
//Transform the text if it contains the hotkey character
::nana::char_t hotkey;
::nana::string::size_type hotkey_pos;
auto text = API::transform_shortkey_text(i->text, hotkey, &hotkey_pos);
nana::size text_s = graph_->text_extent_size(text);
item_s.width = text_s.width + 16;
i->pos = item_pos;
i->size = item_s;
using state = item_renderer::state;
state item_state = (index != state_.active ? state::normal : (state_.menu_active ? state::selected : state::highlighted));
ird.background(item_pos, item_s, item_state);
if (state::selected == item_state)
{
int x = item_pos.x + item_s.width;
int y1 = item_pos.y + 2, y2 = item_pos.y + item_s.height - 1;
graph_->line({ x, y1 }, { x, y2 }, bgcolor.blend(colors::gray_border, 0.4));
graph_->line({ x + 1, y1 }, { x + 1, y2 }, bgcolor.blend(colors::button_face_shadow_end, 0.5));
}
//Draw text, the text is transformed from orignal for hotkey character
int text_top_off = (item_s.height - text_s.height) / 2;
ird.caption({ item_pos.x + 8, item_pos.y + text_top_off }, text);
if(hotkey)
{
unsigned off_w = (hotkey_pos ? graph_->text_extent_size(text, static_cast<unsigned>(hotkey_pos)).width : 0);
nana::size hotkey_size = graph_->text_extent_size(text.c_str() + hotkey_pos, 1);
unsigned ascent, descent, inleading;
graph_->text_metrics(ascent, descent, inleading);
int x = item_pos.x + 8 + off_w;
int y = item_pos.y + text_top_off + ascent + 1;
graph_->line({ x, y }, { x + static_cast<int>(hotkey_size.width) - 1, y }, ::nana::colors::black);
}
item_pos.x += i->size.width;
++index;
}
}
*/
//struct state_type //struct state_type
trigger::state_type::state_type() trigger::state_type::state_type()
: active(npos), : active(npos),

View File

@ -259,6 +259,11 @@ namespace nana{ namespace widgets
virtual bool adjust_caret_into_screen() = 0; virtual bool adjust_caret_into_screen() = 0;
}; };
inline bool is_right_text(const unicode_bidi::entity& e)
{
return ((e.bidi_char_type != unicode_bidi::bidi_char::L) && (e.level & 1));
}
class text_editor::behavior_normal class text_editor::behavior_normal
: public editor_behavior_interface : public editor_behavior_interface
@ -362,7 +367,7 @@ namespace nana{ namespace widgets
{ {
std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]); std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
res.x = editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, _m_is_right_text(ent)); res.x = editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, is_right_text(ent));
res.x += static_cast<unsigned>(ent.begin - lnstr.data()); res.x += static_cast<unsigned>(ent.begin - lnstr.data());
return res; return res;
} }
@ -425,9 +430,8 @@ namespace nana{ namespace widgets
editor_._m_get_scrollbar_size(); editor_._m_get_scrollbar_size();
const auto delta_pixels = editor_._m_text_extent_size(STR(" "), 4).width; auto x = points.caret.x;
auto x = points.caret.x; auto& lnstr = textbase.getline(points.caret.y);
const string_type& lnstr = textbase.getline(points.caret.y);
if (x > lnstr.size()) x = static_cast<unsigned>(lnstr.size()); if (x > lnstr.size()) x = static_cast<unsigned>(lnstr.size());
@ -437,7 +441,10 @@ namespace nana{ namespace widgets
bool adjusted_cond = true; bool adjusted_cond = true;
if (static_cast<int>(text_w) < points.offset.x) if (static_cast<int>(text_w) < points.offset.x)
{
auto delta_pixels = editor_._m_text_extent_size(STR(" "), 4).width;
points.offset.x = (text_w > delta_pixels ? text_w - delta_pixels : 0); points.offset.x = (text_w > delta_pixels ? text_w - delta_pixels : 0);
}
else if (area_w && (text_w >= points.offset.x + area_w)) else if (area_w && (text_w >= points.offset.x + area_w))
points.offset.x = text_w - area_w + 2; points.offset.x = text_w - area_w + 2;
else else
@ -828,7 +835,7 @@ namespace nana{ namespace widgets
{ {
std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]); std::unique_ptr<unsigned[]> pxbuf(new unsigned[len]);
res.x += editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, _m_is_right_text(ent)); res.x += editor_._m_char_by_pixels(ent.begin, len, pxbuf.get(), str_px, scrpos.x, is_right_text(ent));
res.x += static_cast<unsigned>(ent.begin - str); res.x += static_cast<unsigned>(ent.begin - str);
return res; return res;
} }
@ -1765,16 +1772,16 @@ namespace nana{ namespace widgets
const unsigned line_pixels = line_height(); const unsigned line_pixels = line_height();
auto pos = this->behavior_->caret_to_screen(crtpos); auto pos = this->behavior_->caret_to_screen(crtpos);
const int end_y = pos.y + static_cast<int>(line_pixels); const int line_bottom = pos.y + static_cast<int>(line_pixels);
bool visible = false; bool visible = false;
if (hit_text_area(pos) && (end_y > text_area_.area.y)) if (hit_text_area(pos) && (line_bottom > text_area_.area.y))
{ {
visible = true; visible = true;
if (end_y > _m_endy()) if (line_bottom > _m_end_pos(false))
API::caret_size(window_, nana::size(1, line_pixels - (end_y - _m_endy()))); API::caret_size(window_, nana::size(1, line_pixels - (line_bottom - _m_end_pos(false))));
else if (API::caret_size(window_).height != line_pixels) else if (API::caret_size(window_).height != line_pixels)
reset_caret_height(); reset_caret_pixels();
} }
API::caret_visible(window_, visible); API::caret_visible(window_, visible);
@ -1790,7 +1797,7 @@ namespace nana{ namespace widgets
points_.caret.x = static_cast<unsigned>(textbase_.getline(points_.caret.y).size()); points_.caret.x = static_cast<unsigned>(textbase_.getline(points_.caret.y).size());
} }
void text_editor::reset_caret_height() const void text_editor::reset_caret_pixels() const
{ {
API::caret_size(window_, nana::size(1, line_height())); API::caret_size(window_, nana::size(1, line_height()));
} }
@ -1845,7 +1852,7 @@ namespace nana{ namespace widgets
bool text_editor::hit_text_area(const point& pos) const bool text_editor::hit_text_area(const point& pos) const
{ {
return ((text_area_.area.x <= pos.x && pos.x < _m_endx()) && (text_area_.area.y <= pos.y && pos.y < _m_endy())); return ((text_area_.area.x <= pos.x && pos.x < _m_end_pos(true)) && (text_area_.area.y <= pos.y && pos.y < _m_end_pos(false)));
} }
bool text_editor::hit_select_area(nana::upoint pos) const bool text_editor::hit_select_area(nana::upoint pos) const
@ -2439,7 +2446,7 @@ namespace nana{ namespace widgets
} }
} }
upoint text_editor::mouse_caret(const point& scrpos) //From screen position const upoint& text_editor::mouse_caret(const point& scrpos) //From screen position
{ {
points_.caret = behavior_->screen_to_caret(scrpos); points_.caret = behavior_->screen_to_caret(scrpos);
@ -2450,7 +2457,7 @@ namespace nana{ namespace widgets
return points_.caret; return points_.caret;
} }
upoint text_editor::caret() const const upoint& text_editor::caret() const
{ {
return points_.caret; return points_.caret;
} }
@ -2493,7 +2500,7 @@ namespace nana{ namespace widgets
::nana::color text_editor::_m_bgcolor() const ::nana::color text_editor::_m_bgcolor() const
{ {
return (!API::window_enabled(window_) ? color{ 0xE0, 0xE0, 0xE0 } : API::bgcolor(window_)); return (!API::window_enabled(window_) ? static_cast<color_rgb>(0xE0E0E0) : API::bgcolor(window_));
} }
bool text_editor::_m_scroll_text(bool vert) bool text_editor::_m_scroll_text(bool vert)
@ -2539,8 +2546,12 @@ namespace nana{ namespace widgets
void text_editor::_m_scrollbar() void text_editor::_m_scrollbar()
{ {
_m_get_scrollbar_size(); _m_get_scrollbar_size();
nana::size tx_area = _m_text_area(); nana::size tx_area = _m_text_area();
auto scroll_fn = [this](const arg_mouse& arg) {
_m_on_scroll(arg);
};
if (text_area_.vscroll) if (text_area_.vscroll)
{ {
const int x = text_area_.area.x + static_cast<int>(tx_area.width); const int x = text_area_.area.x + static_cast<int>(tx_area.width);
@ -2552,15 +2563,10 @@ namespace nana{ namespace widgets
wdptr->create(window_, nana::rectangle(x, text_area_.area.y, text_area_.vscroll, tx_area.height)); wdptr->create(window_, nana::rectangle(x, text_area_.area.y, text_area_.vscroll, tx_area.height));
auto & evts = wdptr->events(); auto & evts = wdptr->events();
auto fn = [this](const arg_mouse& arg){ evts.mouse_down(scroll_fn);
_m_on_scroll(arg); evts.mouse_move(scroll_fn);
}; evts.mouse_wheel(scroll_fn);
evts.mouse_down(fn);
evts.mouse_move(fn);
evts.mouse_wheel([this](const arg_wheel& arg)
{
_m_on_scroll(arg);
});
API::take_active(wdptr->handle(), false, window_); API::take_active(wdptr->handle(), false, window_);
} }
@ -2590,13 +2596,10 @@ namespace nana{ namespace widgets
wdptr->create(window_, nana::rectangle(text_area_.area.x, y, tx_area.width, text_area_.hscroll)); wdptr->create(window_, nana::rectangle(text_area_.area.x, y, tx_area.width, text_area_.hscroll));
auto & evts = wdptr->events(); auto & evts = wdptr->events();
auto fn = [this](const arg_mouse& arg) evts.mouse_down(scroll_fn);
{ evts.mouse_move(scroll_fn);
_m_on_scroll(arg); evts.mouse_wheel(scroll_fn);
};
evts.mouse_down(fn);
evts.mouse_move(fn);
evts.mouse_wheel(fn);
wdptr->step(20); wdptr->step(20);
API::take_active(wdptr->handle(), false, window_); API::take_active(wdptr->handle(), false, window_);
} }
@ -2633,24 +2636,25 @@ namespace nana{ namespace widgets
return; return;
} }
//Only the textbox is multi_lines, it enables the scrollbars //No scrollbar if it is not multi-line
if(attributes_.multi_lines) if (!attributes_.multi_lines)
{ {
text_area_.vscroll = (textbase_.lines() > screen_lines() ? text_area_.scroll_pixels : 0); text_area_.vscroll = 0;
return;
}
std::pair<size_t, size_t> max_line = textbase_.max_line(); text_area_.vscroll = (textbase_.lines() > screen_lines() ? text_area_.scroll_pixels : 0);
if(max_line.second)
auto max_line = textbase_.max_line();
if(max_line.second)
{
if(points_.offset.x || _m_text_extent_size(textbase_.getline(max_line.first).c_str(), max_line.second).width > _m_text_area().width)
{ {
if(points_.offset.x || _m_text_extent_size(textbase_.getline(max_line.first).c_str(), max_line.second).width > _m_text_area().width) text_area_.hscroll = text_area_.scroll_pixels;
{ if((text_area_.vscroll == 0) && (textbase_.lines() > screen_lines()))
text_area_.hscroll = text_area_.scroll_pixels; text_area_.vscroll = text_area_.scroll_pixels;
if((text_area_.vscroll == 0) && (textbase_.lines() > screen_lines()))
text_area_.vscroll = text_area_.scroll_pixels;
}
} }
} }
else
text_area_.vscroll = 0;
} }
void text_editor::_m_reset() void text_editor::_m_reset()
@ -2898,9 +2902,9 @@ namespace nana{ namespace widgets
else else
{ {
width += text_area_.area.x; width += text_area_.area.x;
if(static_cast<int>(width) - points_.offset.x >= _m_endx()) if(static_cast<int>(width) - points_.offset.x >= _m_end_pos(true))
{ //Out of screen text area { //Out of screen text area
points_.offset.x = static_cast<int>(width) -_m_endx() + 1; points_.offset.x = static_cast<int>(width) -_m_end_pos(false) + 1;
auto rest_size = lnstr.size() - points_.caret.x; auto rest_size = lnstr.size() - points_.caret.x;
points_.offset.x += static_cast<int>(_m_text_extent_size(lnstr.c_str() + points_.caret.x, (rest_size >= static_cast<unsigned>(many) ? static_cast<unsigned>(many) : rest_size)).width); points_.offset.x += static_cast<int>(_m_text_extent_size(lnstr.c_str() + points_.caret.x, (rest_size >= static_cast<unsigned>(many) ? static_cast<unsigned>(many) : rest_size)).width);
return true; return true;
@ -2966,17 +2970,11 @@ namespace nana{ namespace widgets
return text_area_.area.y; return text_area_.area.y;
} }
//_m_endx int text_editor::_m_end_pos(bool right) const
//@brief: Get the right point of text area
int text_editor::_m_endx() const
{ {
return static_cast<int>(text_area_.area.x + text_area_.area.width - text_area_.vscroll); if(right)
} return static_cast<int>(text_area_.area.x + text_area_.area.width - text_area_.vscroll);
//_m_endy
//@brief: Get the bottom point of text area
int text_editor::_m_endy() const
{
return static_cast<int>(text_area_.area.y + text_area_.area.height - text_area_.hscroll); return static_cast<int>(text_area_.area.y + text_area_.area.height - text_area_.hscroll);
} }
@ -3045,7 +3043,7 @@ namespace nana{ namespace widgets
void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const nana::string& str, bool if_mask) const void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const nana::string& str, bool if_mask) const
{ {
::nana::point text_pos{ text_area_.area.x - points_.offset.x, top }; ::nana::point text_pos{ text_area_.area.x - points_.offset.x, top };
const int xend = text_area_.area.x + static_cast<int>(text_area_.area.width); const int text_right = text_area_.area.right();
std::unique_ptr<nana::string> mask_str; std::unique_ptr<nana::string> mask_str;
if (if_mask && mask_char_) if (if_mask && mask_char_)
@ -3082,7 +3080,7 @@ namespace nana{ namespace widgets
std::size_t len = ent.end - ent.begin; std::size_t len = ent.end - ent.begin;
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 < xend)) if ((text_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_pos.x < text_right))
{ {
if (selected && focused) if (selected && focused)
{ {
@ -3091,7 +3089,7 @@ namespace nana{ namespace widgets
graph_.string(text_pos, ent.begin, len); graph_.string(text_pos, ent.begin, len);
} }
else else
_m_draw_parse_string(parser, _m_is_right_text(ent), text_pos, clr, ent.begin, len); _m_draw_parse_string(parser, is_right_text(ent), text_pos, clr, ent.begin, len);
} }
text_pos.x += static_cast<int>(str_w); text_pos.x += static_cast<int>(str_w);
} }
@ -3122,7 +3120,7 @@ namespace nana{ namespace widgets
{ {
std::size_t len = ent.end - ent.begin; std::size_t len = ent.end - ent.begin;
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 < xend)) 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; std::size_t pos = ent.begin - strbeg + str_pos.x;
const auto str_end = pos + len; const auto str_end = pos + len;
@ -3151,7 +3149,7 @@ namespace nana{ namespace widgets
auto sel_w = std::accumulate(pxbuf + (a.x - pos), pxbuf + (endpos - pos), unsigned()); auto sel_w = std::accumulate(pxbuf + (a.x - pos), pxbuf + (endpos - pos), unsigned());
graph_.set_text_color(clr); graph_.set_text_color(clr);
if (_m_is_right_text(ent)) if (is_right_text(ent))
{ //RTL { //RTL
rtl_string(text_pos, ent.begin, len, str_w, head_w, sel_w); rtl_string(text_pos, ent.begin, len, str_w, head_w, sel_w);
} }
@ -3180,7 +3178,7 @@ namespace nana{ namespace widgets
int endpos = b.x; int endpos = b.x;
unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, endpos - pos).width; unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, endpos - pos).width;
if (_m_is_right_text(ent)) if (is_right_text(ent))
{ //RTL { //RTL
graph_.set_text_color(clr); graph_.set_text_color(clr);
rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w); rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w);
@ -3205,7 +3203,7 @@ namespace nana{ namespace widgets
{ {
std::size_t len = ent.end - ent.begin; std::size_t len = ent.end - ent.begin;
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 < xend)) if ((text_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_pos.x < text_right))
{ {
graph_.set_text_color(clr); graph_.set_text_color(clr);
std::size_t pos = ent.begin - strbeg + str_pos.x; std::size_t pos = ent.begin - strbeg + str_pos.x;
@ -3224,7 +3222,7 @@ namespace nana{ namespace widgets
else else
{ {
unsigned head_w = graph_.glyph_extent_size(ent.begin, len, 0, a.x - pos).width; unsigned head_w = graph_.glyph_extent_size(ent.begin, len, 0, a.x - pos).width;
if (_m_is_right_text(ent)) if (is_right_text(ent))
{ //RTL { //RTL
rtl_string(text_pos, ent.begin, len, str_w, head_w, str_w - head_w); rtl_string(text_pos, ent.begin, len, str_w, head_w, str_w - head_w);
} }
@ -3257,7 +3255,7 @@ namespace nana{ namespace widgets
{ {
std::size_t len = ent.end - ent.begin; std::size_t len = ent.end - ent.begin;
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 < xend)) 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; std::size_t pos = ent.begin - strbeg + str_pos.x;
graph_.set_text_color(clr); graph_.set_text_color(clr);
@ -3271,7 +3269,7 @@ namespace nana{ namespace widgets
else if (pos <= b.x && b.x < pos + len) else if (pos <= b.x && b.x < pos + len)
{ {
unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, b.x - pos).width; unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, b.x - pos).width;
if (_m_is_right_text(ent)) if (is_right_text(ent))
{ //RTL { //RTL
rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w); rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w);
} }
@ -3298,7 +3296,7 @@ namespace nana{ namespace widgets
{ {
if (false == behavior_->adjust_caret_into_screen()) if (false == behavior_->adjust_caret_into_screen())
{ {
if (behavior_->caret_to_screen(points_.caret).x < _m_endx()) if (behavior_->caret_to_screen(points_.caret).x < _m_end_pos(true))
{ {
behavior_->update_line(points_.caret.y, secondary_before); behavior_->update_line(points_.caret.y, secondary_before);
return false; return false;
@ -3386,7 +3384,7 @@ namespace nana{ namespace widgets
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 <= ch && ch <= ent.end)
{ {
if (_m_is_right_text(ent)) if (is_right_text(ent))
{ {
//Characters of some bidi languages may transform in a word. //Characters of some bidi languages may transform in a word.
//RTL //RTL
@ -3403,11 +3401,6 @@ namespace nana{ namespace widgets
return text_w; return text_w;
} }
bool text_editor::_m_is_right_text(const unicode_bidi::entity& e)
{
return ((e.bidi_char_type != unicode_bidi::bidi_char::L) && (e.level & 1));
}
//end class text_editor //end class text_editor
}//end namespace skeletons }//end namespace skeletons
}//end namespace widgets }//end namespace widgets

View File

@ -242,7 +242,7 @@ namespace drawerbase {
internal_scope_guard lock; internal_scope_guard lock;
auto editor = get_drawer_trigger().editor(); auto editor = get_drawer_trigger().editor();
if (editor) if (editor)
editor->textbase().store(std::move(file)); editor->textbase().store(std::move(file), false, nana::unicode::utf8); //3rd parameter is just for syntax, it will be ignored
} }
void textbox::store(nana::string file, nana::unicode encoding) void textbox::store(nana::string file, nana::unicode encoding)
@ -250,7 +250,7 @@ namespace drawerbase {
internal_scope_guard lock; internal_scope_guard lock;
auto editor = get_drawer_trigger().editor(); auto editor = get_drawer_trigger().editor();
if (editor) if (editor)
editor->textbase().store(std::move(file), encoding); editor->textbase().store(std::move(file), true, encoding);
} }
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter. /// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
@ -614,7 +614,7 @@ namespace drawerbase {
widget::_m_typeface(font); widget::_m_typeface(font);
auto editor = get_drawer_trigger().editor(); auto editor = get_drawer_trigger().editor();
if(editor) if(editor)
editor->reset_caret_height(); editor->reset_caret_pixels();
} }
//end class textbox //end class textbox
}//end namespace nana }//end namespace nana