new features of listbox
text line number and line indent
This commit is contained in:
parent
c6f2f28f81
commit
5590dd293b
@ -14,7 +14,7 @@
|
|||||||
#define NANA_GUI_WIDGETS_COMBOX_HPP
|
#define NANA_GUI_WIDGETS_COMBOX_HPP
|
||||||
#include "widget.hpp"
|
#include "widget.hpp"
|
||||||
#include "float_listbox.hpp"
|
#include "float_listbox.hpp"
|
||||||
#include "skeletons/text_editor_scheme.hpp"
|
#include "skeletons/text_editor_part.hpp"
|
||||||
#include <nana/key_type.hpp>
|
#include <nana/key_type.hpp>
|
||||||
#include <nana/concepts.hpp>
|
#include <nana/concepts.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
#ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
|
#ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
|
||||||
#define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
|
#define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
|
||||||
#include "textbase.hpp"
|
#include "textbase.hpp"
|
||||||
#include "text_editor_scheme.hpp"
|
#include "text_editor_part.hpp"
|
||||||
#include <nana/gui/widgets/scroll.hpp>
|
#include <nana/gui/widgets/scroll.hpp>
|
||||||
#include <nana/unicode_bidi.hpp>
|
#include <nana/unicode_bidi.hpp>
|
||||||
|
|
||||||
@ -135,6 +135,8 @@ namespace nana{ namespace widgets
|
|||||||
using size_type = textbase<char_type>::size_type;
|
using size_type = textbase<char_type>::size_type;
|
||||||
using string_type = textbase<char_type>::string_type;
|
using string_type = textbase<char_type>::string_type;
|
||||||
|
|
||||||
|
using event_interface = text_editor_event_interface;
|
||||||
|
|
||||||
using graph_reference = ::nana::paint::graphics&;
|
using graph_reference = ::nana::paint::graphics&;
|
||||||
|
|
||||||
struct ext_renderer_tag
|
struct ext_renderer_tag
|
||||||
@ -162,6 +164,9 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
void typeface_changed();
|
void typeface_changed();
|
||||||
|
|
||||||
|
void indent(bool, std::function<nana::string()> generator);
|
||||||
|
void set_event(event_interface*);
|
||||||
|
|
||||||
/// Determine whether the text_editor is line wrapped.
|
/// Determine whether the text_editor is line wrapped.
|
||||||
bool line_wrapped() const;
|
bool line_wrapped() const;
|
||||||
/// Set the text_editor whether it is line wrapped, it returns false if the state is not changed.
|
/// Set the text_editor whether it is line wrapped, it returns false if the state is not changed.
|
||||||
@ -174,6 +179,10 @@ namespace nana{ namespace widgets
|
|||||||
/// Sets the text area.
|
/// Sets the text area.
|
||||||
/// @return true if the area is changed with the new value.
|
/// @return true if the area is changed with the new value.
|
||||||
bool text_area(const nana::rectangle&);
|
bool text_area(const nana::rectangle&);
|
||||||
|
|
||||||
|
/// Returns the text area
|
||||||
|
rectangle text_area(bool including_scroll) const;
|
||||||
|
|
||||||
bool tip_string(nana::string&&);
|
bool tip_string(nana::string&&);
|
||||||
|
|
||||||
const attributes & attr() const;
|
const attributes & attr() const;
|
||||||
@ -215,8 +224,13 @@ namespace nana{ namespace widgets
|
|||||||
/// Returns width of text area excluding the vscroll size.
|
/// Returns width of text area excluding the vscroll size.
|
||||||
unsigned width_pixels() const;
|
unsigned width_pixels() const;
|
||||||
window window_handle() const;
|
window window_handle() const;
|
||||||
|
|
||||||
|
/// Returns text position of each line that currently displays on screen
|
||||||
|
const std::vector<upoint>& text_position() const;
|
||||||
|
|
||||||
|
void set_text_position_changed(std::function<void(const std::vector<upoint>&)>);
|
||||||
public:
|
public:
|
||||||
void draw_scroll_rectangle();
|
void draw_corner();
|
||||||
void render(bool focused);
|
void render(bool focused);
|
||||||
public:
|
public:
|
||||||
void put(nana::string);
|
void put(nana::string);
|
||||||
@ -242,6 +256,8 @@ 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;
|
||||||
@ -294,7 +310,8 @@ namespace nana{ namespace widgets
|
|||||||
undoable<command> undo_;
|
undoable<command> undo_;
|
||||||
nana::window window_;
|
nana::window window_;
|
||||||
graph_reference graph_;
|
graph_reference graph_;
|
||||||
const text_editor_scheme* scheme_;
|
const text_editor_scheme* scheme_;
|
||||||
|
event_interface * event_handler_{ nullptr };
|
||||||
std::unique_ptr<keywords> keywords_;
|
std::unique_ptr<keywords> keywords_;
|
||||||
|
|
||||||
skeletons::textbase<nana::char_t> textbase_;
|
skeletons::textbase<nana::char_t> textbase_;
|
||||||
@ -302,6 +319,15 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
mutable ext_renderer_tag ext_renderer_;
|
mutable ext_renderer_tag ext_renderer_;
|
||||||
|
|
||||||
|
std::vector<upoint> text_position_; //position of text from last rendering.
|
||||||
|
std::function<void(const std::vector<upoint>&)> text_position_function_;
|
||||||
|
|
||||||
|
struct indent_rep
|
||||||
|
{
|
||||||
|
bool enabled{ false };
|
||||||
|
std::function<nana::string()> generator;
|
||||||
|
}indent_;
|
||||||
|
|
||||||
struct attributes
|
struct attributes
|
||||||
{
|
{
|
||||||
accepts acceptive{ accepts::no_restrict };
|
accepts acceptive{ accepts::no_restrict };
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#define NANA_WIDGETS_SKELETONS_TEXT_EDITOR_SCHEME_HPP
|
#define NANA_WIDGETS_SKELETONS_TEXT_EDITOR_SCHEME_HPP
|
||||||
|
|
||||||
#include "../../detail/widget_colors.hpp"
|
#include "../../detail/widget_colors.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -16,6 +17,14 @@ namespace nana
|
|||||||
color_proxy selection{static_cast<color_rgb>(0x3399FF)};
|
color_proxy selection{static_cast<color_rgb>(0x3399FF)};
|
||||||
color_proxy selection_text{colors::white};
|
color_proxy selection_text{colors::white};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class text_editor_event_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~text_editor_event_interface() = default;
|
||||||
|
|
||||||
|
virtual void text_position_changed(const std::vector<upoint>&) = 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
#ifndef NANA_GUI_WIDGET_SPINBOX_HPP
|
#ifndef NANA_GUI_WIDGET_SPINBOX_HPP
|
||||||
#define NANA_GUI_WIDGET_SPINBOX_HPP
|
#define NANA_GUI_WIDGET_SPINBOX_HPP
|
||||||
#include "widget.hpp"
|
#include "widget.hpp"
|
||||||
#include "skeletons/text_editor_scheme.hpp"
|
#include "skeletons/text_editor_part.hpp"
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
#define NANA_GUI_WIDGET_TEXTBOX_HPP
|
#define NANA_GUI_WIDGET_TEXTBOX_HPP
|
||||||
#include <nana/gui/widgets/widget.hpp>
|
#include <nana/gui/widgets/widget.hpp>
|
||||||
#include "skeletons/textbase_export_interface.hpp"
|
#include "skeletons/textbase_export_interface.hpp"
|
||||||
#include "skeletons/text_editor_scheme.hpp"
|
#include "skeletons/text_editor_part.hpp"
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -23,10 +23,20 @@ namespace nana
|
|||||||
: public event_arg
|
: public event_arg
|
||||||
{
|
{
|
||||||
textbox& widget;
|
textbox& widget;
|
||||||
|
const std::vector<upoint>* text_position;
|
||||||
|
|
||||||
arg_textbox(textbox&);
|
arg_textbox(textbox&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct arg_textbox_text_position
|
||||||
|
: public event_arg
|
||||||
|
{
|
||||||
|
textbox& widget;
|
||||||
|
const std::vector<upoint>& text_position;
|
||||||
|
|
||||||
|
arg_textbox_text_position(textbox&, const std::vector<upoint>&);
|
||||||
|
};
|
||||||
|
|
||||||
namespace widgets
|
namespace widgets
|
||||||
{
|
{
|
||||||
namespace skeletons
|
namespace skeletons
|
||||||
@ -44,15 +54,30 @@ namespace nana
|
|||||||
{
|
{
|
||||||
basic_event<arg_textbox> first_change;
|
basic_event<arg_textbox> first_change;
|
||||||
basic_event<arg_textbox> text_changed;
|
basic_event<arg_textbox> text_changed;
|
||||||
|
basic_event<arg_textbox_text_position> text_position_changed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class event_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~event_interface() = default;
|
||||||
|
|
||||||
|
virtual void text_position_changed(const std::vector<upoint>&) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class event_agent
|
class event_agent
|
||||||
: public widgets::skeletons::textbase_event_agent_interface
|
: public widgets::skeletons::textbase_event_agent_interface,
|
||||||
|
public widgets::skeletons::text_editor_event_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
event_agent(::nana::textbox&);
|
event_agent(::nana::textbox&);
|
||||||
|
private:
|
||||||
|
//Overrides textbase_event_agent_interface
|
||||||
void first_change() override;
|
void first_change() override;
|
||||||
void text_changed() override;
|
void text_changed() override;
|
||||||
|
private:
|
||||||
|
//Overrides text_editor_event_interface
|
||||||
|
void text_position_changed(const std::vector<upoint>&) override;
|
||||||
private:
|
private:
|
||||||
::nana::textbox & widget_;
|
::nana::textbox & widget_;
|
||||||
};
|
};
|
||||||
@ -128,8 +153,12 @@ namespace nana
|
|||||||
void store(nana::string file);
|
void store(nana::string file);
|
||||||
void store(nana::string file, nana::unicode encoding);
|
void store(nana::string file, nana::unicode encoding);
|
||||||
|
|
||||||
|
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
|
||||||
|
/// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line.
|
||||||
|
void enable_indent(bool, std::function<nana::string()> generator = {});
|
||||||
|
|
||||||
//A workaround for reset, explicit default constructor syntax, because VC2013 incorrectly treats {} as {0}.
|
//A workaround for reset, explicit default constructor syntax, because VC2013 incorrectly treats {} as {0}.
|
||||||
textbox& reset(nana::string = nana::string()); ///< discard the old text and set a newtext
|
textbox& reset(nana::string = nana::string()); ///< discard the old text and set a new text
|
||||||
|
|
||||||
/// The file of last store operation.
|
/// The file of last store operation.
|
||||||
nana::string filename() const;
|
nana::string filename() const;
|
||||||
@ -188,6 +217,16 @@ namespace nana
|
|||||||
void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<nana::string> kw_list);
|
void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<nana::string> kw_list);
|
||||||
void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<std::string> kw_list_utf8);
|
void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<std::string> kw_list_utf8);
|
||||||
void erase_keyword(const nana::string& kw);
|
void erase_keyword(const nana::string& kw);
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns the text position of each line that currently displays on screen.
|
||||||
|
std::vector<upoint> text_position() const;
|
||||||
|
|
||||||
|
/// Returns the rectangle of text area
|
||||||
|
rectangle text_area() const;
|
||||||
|
|
||||||
|
/// Returns the height of line in pixels
|
||||||
|
unsigned line_pixels() const;
|
||||||
protected:
|
protected:
|
||||||
//Overrides widget's virtual functions
|
//Overrides widget's virtual functions
|
||||||
::nana::string _m_caption() const throw() override;
|
::nana::string _m_caption() const throw() override;
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "widgets/form.hpp"
|
#include "widgets/form.hpp"
|
||||||
#include "drawing.hpp"
|
#include "drawing.hpp"
|
||||||
#include "msgbox.hpp"
|
#include "msgbox.hpp"
|
||||||
|
#include "place.hpp"
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
|
|||||||
@ -252,7 +252,7 @@ namespace nana{ namespace widgets
|
|||||||
virtual std::size_t take_lines(std::size_t pos) const = 0;
|
virtual std::size_t take_lines(std::size_t pos) const = 0;
|
||||||
|
|
||||||
virtual void update_line(std::size_t textline, std::size_t secondary_before) = 0;
|
virtual void update_line(std::size_t textline, std::size_t secondary_before) = 0;
|
||||||
virtual void render(const ::nana::color& fgcolor) = 0;
|
virtual std::vector<::nana::upoint> render(const ::nana::color& fgcolor) = 0;
|
||||||
virtual nana::point caret_to_screen(upoint) = 0;
|
virtual nana::point caret_to_screen(upoint) = 0;
|
||||||
virtual nana::upoint screen_to_caret(point scrpos) = 0;
|
virtual nana::upoint screen_to_caret(point scrpos) = 0;
|
||||||
virtual bool move_caret_ns(bool to_north) = 0;
|
virtual bool move_caret_ns(bool to_north) = 0;
|
||||||
@ -290,8 +290,10 @@ namespace nana{ namespace widgets
|
|||||||
editor_._m_draw_string(top, API::fgcolor(editor_.window_), nana::upoint(0, editor_.points_.caret.y), editor_.textbase_.getline(textline), true);
|
editor_._m_draw_string(top, API::fgcolor(editor_.window_), nana::upoint(0, editor_.points_.caret.y), editor_.textbase_.getline(textline), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const ::nana::color& fgcolor) override
|
std::vector<upoint> render(const ::nana::color& fgcolor) override
|
||||||
{
|
{
|
||||||
|
std::vector<upoint> line_index;
|
||||||
|
|
||||||
::nana::upoint str_pos(0, static_cast<unsigned>(editor_.points_.offset.y));
|
::nana::upoint str_pos(0, static_cast<unsigned>(editor_.points_.offset.y));
|
||||||
|
|
||||||
std::size_t scrlines = editor_.screen_lines() + str_pos.y;
|
std::size_t scrlines = editor_.screen_lines() + str_pos.y;
|
||||||
@ -304,9 +306,12 @@ namespace nana{ namespace widgets
|
|||||||
while( str_pos.y < scrlines)
|
while( str_pos.y < scrlines)
|
||||||
{
|
{
|
||||||
editor_._m_draw_string(top, fgcolor, str_pos, editor_.textbase_.getline(str_pos.y), true);
|
editor_._m_draw_string(top, fgcolor, str_pos, editor_.textbase_.getline(str_pos.y), true);
|
||||||
|
line_index.push_back(str_pos);
|
||||||
++str_pos.y;
|
++str_pos.y;
|
||||||
top += pixels;
|
top += pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return line_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
nana::point caret_to_screen(nana::upoint pos) override
|
nana::point caret_to_screen(nana::upoint pos) override
|
||||||
@ -692,12 +697,14 @@ namespace nana{ namespace widgets
|
|||||||
editor_.render(API::is_focus_ready(editor_.window_));
|
editor_.render(API::is_focus_ready(editor_.window_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const ::nana::color& fgcolor) override
|
std::vector<upoint> render(const ::nana::color& fgcolor) override
|
||||||
{
|
{
|
||||||
|
std::vector<upoint> line_index;
|
||||||
|
|
||||||
std::size_t secondary;
|
std::size_t secondary;
|
||||||
auto primary = _m_textline_from_screen(0, secondary);
|
auto primary = _m_textline_from_screen(0, secondary);
|
||||||
if (primary >= linemtr_.size() || secondary >= linemtr_[primary].line_sections.size())
|
if (primary >= linemtr_.size() || secondary >= linemtr_[primary].line_sections.size())
|
||||||
return;
|
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).data());
|
||||||
@ -715,6 +722,7 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
nana::string text(section.begin, section.end);
|
nana::string text(section.begin, section.end);
|
||||||
editor_._m_draw_string(top, fgcolor, str_pos, text, true);
|
editor_._m_draw_string(top, fgcolor, str_pos, text, true);
|
||||||
|
line_index.push_back(str_pos);
|
||||||
++secondary;
|
++secondary;
|
||||||
if (secondary >= mtr.line_sections.size())
|
if (secondary >= mtr.line_sections.size())
|
||||||
{
|
{
|
||||||
@ -729,6 +737,8 @@ namespace nana{ namespace widgets
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return line_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
nana::point caret_to_screen(upoint pos) override
|
nana::point caret_to_screen(upoint pos) override
|
||||||
@ -1436,6 +1446,17 @@ namespace nana{ namespace widgets
|
|||||||
behavior_->pre_calc_lines(width_pixels());
|
behavior_->pre_calc_lines(width_pixels());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void text_editor::indent(bool enb, std::function<nana::string()> generator)
|
||||||
|
{
|
||||||
|
indent_.enabled = enb;
|
||||||
|
indent_.generator.swap(generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_editor::set_event(event_interface* ptr)
|
||||||
|
{
|
||||||
|
event_handler_ = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool text_editor::line_wrapped() const
|
bool text_editor::line_wrapped() const
|
||||||
{
|
{
|
||||||
return attributes_.line_wrapped;
|
return attributes_.line_wrapped;
|
||||||
@ -1500,6 +1521,18 @@ namespace nana{ namespace widgets
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rectangle text_editor::text_area(bool including_scroll) const
|
||||||
|
{
|
||||||
|
if (including_scroll)
|
||||||
|
return text_area_.area;
|
||||||
|
|
||||||
|
auto r = text_area_.area;
|
||||||
|
|
||||||
|
r.width = text_area_.area.width > text_area_.vscroll ? text_area_.area.width - text_area_.vscroll : 0;
|
||||||
|
r.height = text_area_.area.height > text_area_.hscroll ? text_area_.area.height - text_area_.hscroll : 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
bool text_editor::tip_string(nana::string&& str)
|
bool text_editor::tip_string(nana::string&& str)
|
||||||
{
|
{
|
||||||
if(attributes_.tip_string == str)
|
if(attributes_.tip_string == str)
|
||||||
@ -1873,7 +1906,17 @@ namespace nana{ namespace widgets
|
|||||||
return window_;
|
return window_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_editor::draw_scroll_rectangle()
|
const std::vector<upoint>& text_editor::text_position() const
|
||||||
|
{
|
||||||
|
return text_position_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_editor::set_text_position_changed(std::function<void(const std::vector<upoint>&)> fn)
|
||||||
|
{
|
||||||
|
text_position_function_.swap(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_editor::draw_corner()
|
||||||
{
|
{
|
||||||
if(text_area_.vscroll && text_area_.hscroll)
|
if(text_area_.vscroll && text_area_.hscroll)
|
||||||
{
|
{
|
||||||
@ -1906,11 +1949,27 @@ namespace nana{ namespace widgets
|
|||||||
//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)
|
||||||
behavior_->render(fgcolor);
|
{
|
||||||
else //Draw tip string
|
auto && text_pos = behavior_->render(fgcolor);
|
||||||
graph_.string({ text_area_.area.x - points_.offset.x, text_area_.area.y }, attributes_.tip_string, { 0x78, 0x78, 0x78 });
|
|
||||||
|
|
||||||
draw_scroll_rectangle();
|
|
||||||
|
if (text_pos.empty())
|
||||||
|
text_pos.push_back({ 0, 0 });
|
||||||
|
|
||||||
|
if (text_pos != text_position_)
|
||||||
|
{
|
||||||
|
text_position_.swap(text_pos);
|
||||||
|
if (event_handler_)
|
||||||
|
event_handler_->text_position_changed(text_position_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //Draw tip string
|
||||||
|
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())
|
||||||
|
text_position_.push_back({ 0, 0 });
|
||||||
|
|
||||||
|
draw_corner();
|
||||||
|
|
||||||
text_area_.border_renderer(graph_, bgcolor);
|
text_area_.border_renderer(graph_, bgcolor);
|
||||||
}
|
}
|
||||||
@ -1961,7 +2020,7 @@ namespace nana{ namespace widgets
|
|||||||
if (refresh || _m_update_caret_line(secondary_before))
|
if (refresh || _m_update_caret_line(secondary_before))
|
||||||
render(true);
|
render(true);
|
||||||
else
|
else
|
||||||
draw_scroll_rectangle();
|
draw_corner();
|
||||||
|
|
||||||
_m_scrollbar();
|
_m_scrollbar();
|
||||||
|
|
||||||
@ -2049,6 +2108,29 @@ namespace nana{ namespace widgets
|
|||||||
need_refresh = true;
|
need_refresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (indent_.enabled)
|
||||||
|
{
|
||||||
|
nana::string indent_text;
|
||||||
|
if (indent_.generator)
|
||||||
|
{
|
||||||
|
indent_text = indent_.generator();
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
indent_text = text.substr(0, indent_pos);
|
||||||
|
else
|
||||||
|
indent_text = 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);
|
||||||
|
|
||||||
@ -2108,7 +2190,7 @@ namespace nana{ namespace widgets
|
|||||||
if(_m_move_offset_x_while_over_border(-2) == false)
|
if(_m_move_offset_x_while_over_border(-2) == false)
|
||||||
{
|
{
|
||||||
behavior_->update_line(points_.caret.y, secondary);
|
behavior_->update_line(points_.caret.y, secondary);
|
||||||
draw_scroll_rectangle();
|
draw_corner();
|
||||||
has_to_redraw = false;
|
has_to_redraw = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -410,7 +410,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto spins_r = _m_spins_area();
|
auto spins_r = _m_spins_area();
|
||||||
if (spins_r.x == 0)
|
if (spins_r.x == 0)
|
||||||
editor_->text_area({});
|
editor_->text_area(rectangle{});
|
||||||
else
|
else
|
||||||
editor_->text_area({ 2, 2, graph_->width() - spins_r.width - 2, spins_r.height - 2 });
|
editor_->text_area({ 2, 2, graph_->width() - spins_r.width - 2, spins_r.height - 2 });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,12 @@ namespace nana
|
|||||||
: widget(wdg)
|
: widget(wdg)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
arg_textbox_text_position::arg_textbox_text_position(textbox& wdg, const std::vector<upoint>& text_pos)
|
||||||
|
: widget(wdg),
|
||||||
|
text_position(text_pos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
namespace drawerbase {
|
namespace drawerbase {
|
||||||
namespace textbox
|
namespace textbox
|
||||||
{
|
{
|
||||||
@ -41,6 +47,12 @@ namespace drawerbase {
|
|||||||
{
|
{
|
||||||
widget_.events().text_changed.emit(::nana::arg_textbox{ widget_ });
|
widget_.events().text_changed.emit(::nana::arg_textbox{ widget_ });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void event_agent::text_position_changed(const std::vector<upoint>& text_pos)
|
||||||
|
{
|
||||||
|
::nana::arg_textbox_text_position arg(widget_, text_pos);
|
||||||
|
widget_.events().text_position_changed.emit(arg);
|
||||||
|
}
|
||||||
//end class event_agent
|
//end class event_agent
|
||||||
|
|
||||||
//class draweer
|
//class draweer
|
||||||
@ -69,6 +81,7 @@ namespace drawerbase {
|
|||||||
|
|
||||||
editor_ = new text_editor(wd, graph, dynamic_cast<::nana::widgets::skeletons::text_editor_scheme*>(scheme));
|
editor_ = new text_editor(wd, graph, dynamic_cast<::nana::widgets::skeletons::text_editor_scheme*>(scheme));
|
||||||
editor_->textbase().set_event_agent(evt_agent_.get());
|
editor_->textbase().set_event_agent(evt_agent_.get());
|
||||||
|
editor_->set_event(evt_agent_.get());
|
||||||
|
|
||||||
_m_text_area(graph.width(), graph.height());
|
_m_text_area(graph.width(), graph.height());
|
||||||
|
|
||||||
@ -240,6 +253,16 @@ namespace drawerbase {
|
|||||||
editor->textbase().store(std::move(file), encoding);
|
editor->textbase().store(std::move(file), encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
|
||||||
|
/// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line.
|
||||||
|
void textbox::enable_indent(bool enb, std::function<nana::string()> generator)
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().editor();
|
||||||
|
if (editor)
|
||||||
|
editor->indent(enb, generator);
|
||||||
|
}
|
||||||
|
|
||||||
textbox& textbox::reset(nana::string str)
|
textbox& textbox::reset(nana::string str)
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
@ -495,6 +518,7 @@ namespace drawerbase {
|
|||||||
|
|
||||||
void textbox::set_highlight(const std::string& name, const ::nana::color& fgcolor, const ::nana::color& bgcolor)
|
void textbox::set_highlight(const std::string& name, const ::nana::color& fgcolor, const ::nana::color& bgcolor)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto editor = get_drawer_trigger().editor();
|
auto editor = get_drawer_trigger().editor();
|
||||||
if (editor)
|
if (editor)
|
||||||
editor->set_highlight(name, fgcolor, bgcolor);
|
editor->set_highlight(name, fgcolor, bgcolor);
|
||||||
@ -502,6 +526,7 @@ namespace drawerbase {
|
|||||||
|
|
||||||
void textbox::erase_highlight(const std::string& name)
|
void textbox::erase_highlight(const std::string& name)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto editor = get_drawer_trigger().editor();
|
auto editor = get_drawer_trigger().editor();
|
||||||
if (editor)
|
if (editor)
|
||||||
editor->erase_highlight(name);
|
editor->erase_highlight(name);
|
||||||
@ -509,6 +534,7 @@ namespace drawerbase {
|
|||||||
|
|
||||||
void textbox::set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<nana::string> kw_list)
|
void textbox::set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<nana::string> kw_list)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto editor = get_drawer_trigger().editor();
|
auto editor = get_drawer_trigger().editor();
|
||||||
if (editor)
|
if (editor)
|
||||||
{
|
{
|
||||||
@ -519,6 +545,7 @@ namespace drawerbase {
|
|||||||
|
|
||||||
void textbox::set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<std::string> kw_list_utf8)
|
void textbox::set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<std::string> kw_list_utf8)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto editor = get_drawer_trigger().editor();
|
auto editor = get_drawer_trigger().editor();
|
||||||
if (editor)
|
if (editor)
|
||||||
{
|
{
|
||||||
@ -529,11 +556,39 @@ namespace drawerbase {
|
|||||||
|
|
||||||
void textbox::erase_keyword(const nana::string& kw)
|
void textbox::erase_keyword(const nana::string& kw)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto editor = get_drawer_trigger().editor();
|
auto editor = get_drawer_trigger().editor();
|
||||||
if (editor)
|
if (editor)
|
||||||
editor->erase_keyword(kw);
|
editor->erase_keyword(kw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<upoint> textbox::text_position() const
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().editor();
|
||||||
|
if (editor)
|
||||||
|
return editor->text_position();
|
||||||
|
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
|
rectangle textbox::text_area() const
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().editor();
|
||||||
|
if (editor)
|
||||||
|
return editor->text_area(false);
|
||||||
|
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned textbox::line_pixels() const
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().editor();
|
||||||
|
return (editor ? editor->line_height() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
//Override _m_caption for caption()
|
//Override _m_caption for caption()
|
||||||
nana::string textbox::_m_caption() const throw()
|
nana::string textbox::_m_caption() const throw()
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user