New border element

This commit is contained in:
cnjinhao
2015-01-14 04:30:35 +08:00
parent 7496fea110
commit bb49ba651c
6 changed files with 122 additions and 48 deletions

View File

@@ -30,19 +30,17 @@ namespace nana
class element_interface class element_interface
{ {
public: public:
typedef paint::graphics & graph_reference; using graph_reference = paint::graphics&;
virtual ~element_interface()
{}
virtual ~element_interface() = default;
virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state) = 0; virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state) = 0;
}; };
class crook_interface class crook_interface
{ {
public: public:
typedef paint::graphics & graph_reference; using graph_reference = paint::graphics&;
typedef checkstate state; using state = checkstate;
struct data struct data
{ {
@@ -50,12 +48,19 @@ namespace nana
bool radio; bool radio;
}; };
virtual ~crook_interface() virtual ~crook_interface() = default;
{}
virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state, const data&) = 0; virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state, const data&) = 0;
}; };
class border_interface
{
public:
using graph_reference = paint::graphics&;
virtual ~border_interface() = default;
virtual bool draw(graph_reference, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle&, element_state, unsigned weight) = 0;
};
class provider class provider
{ {
public: public:
@@ -87,16 +92,27 @@ namespace nana
void add_crook(const std::string& name, const pat::cloneable<factory_interface<crook_interface>>&); void add_crook(const std::string& name, const pat::cloneable<factory_interface<crook_interface>>&);
crook_interface* const * keeper_crook(const std::string& name); crook_interface* const * keeper_crook(const std::string& name);
void add_border(const std::string&, const pat::cloneable<factory_interface<border_interface>>&);
border_interface* const * keeper_border(const std::string&);
}; };
class crook;
template<typename UserElement> template<typename UserElement>
void add_crook(const std::string& name) void add_crook(const std::string& name)
{ {
typedef provider::factory<UserElement, crook_interface> factory_t; using factory_t = provider::factory<UserElement, crook_interface>;
provider().add_crook(name, pat::cloneable<typename factory_t::interface_type>(factory_t())); provider().add_crook(name, pat::cloneable<typename factory_t::interface_type>(factory_t()));
} }
class crook; class border;
template<typename BorderElement>
void add_border(const std::string& name)
{
using factory_t = provider::factory<BorderElement, border_interface>;
provider().add_border(name, pat::cloneable<typename factory_t::interface_type>(factory_t()));
}
}//end namespace element }//end namespace element
template<typename Element> class facade; template<typename Element> class facade;
@@ -106,8 +122,8 @@ namespace nana
: public element::element_interface : public element::element_interface
{ {
public: public:
typedef ::nana::paint::graphics & graph_reference; using graph_reference = ::nana::paint::graphics &;
typedef element::crook_interface::state state; using state = element::crook_interface::state;
facade(); facade();
facade(const char* name); facade(const char* name);
@@ -126,7 +142,24 @@ namespace nana
private: private:
element::crook_interface::data data_; element::crook_interface::data data_;
element::crook_interface* const * keeper_; element::crook_interface* const * keeper_;
}; }; //end class facade<element::crook>
template<>
class facade<element::border>
: public element::element_interface
{
using graph_reference = ::nana::paint::graphics &;
public:
facade();
facade(const char* name);
void switch_to(const char*);
public:
//Implement element_interface
bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state) override;
private:
element::border_interface* const * keeper_;
};//end class facade<element::border>
namespace element namespace element
{ {

View File

@@ -80,7 +80,6 @@ namespace nana
void typeface_changed(graph_reference) override; void typeface_changed(graph_reference) override;
private: private:
void _m_text_area(unsigned width, unsigned height); void _m_text_area(unsigned width, unsigned height);
void _m_draw_border(graph_reference, const ::nana::color& bgcolor);
private: private:
widget* widget_; widget* widget_;
struct status_type struct status_type

View File

@@ -234,7 +234,7 @@ namespace nana
{ {
if(colormap[u][v] & 0xFF000000) if(colormap[u][v] & 0xFF000000)
continue; continue;
graph.set_pixel(x + v, y, static_cast<colors>(colormap[u][v])); graph.set_pixel(x + v, y, static_cast<color_rgb>(colormap[u][v]));
} }
++y; ++y;
} }
@@ -257,7 +257,18 @@ namespace nana
return true; return true;
} }
}; };
}
class border_depressed
: public border_interface
{
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, unsigned weight)
{
graph.rectangle(r, false, static_cast<color_rgb>((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E));
graph.rectangle(::nana::rectangle{r}.pare_off(1), false, bgcolor);
return true;
}
};
}//end namespace element
template<typename ElementInterface> template<typename ElementInterface>
class element_object class element_object
@@ -267,11 +278,6 @@ namespace nana
typedef pat::cloneable<element::provider::factory_interface<element_t>> factory_interface; typedef pat::cloneable<element::provider::factory_interface<element_t>> factory_interface;
public: public:
element_object()
: element_ptr_(nullptr)
{
}
~element_object() ~element_object()
{ {
if(factory_) if(factory_)
@@ -306,7 +312,7 @@ namespace nana
} }
private: private:
factory_interface factory_; //Keep the factory for destroying the element factory_interface factory_; //Keep the factory for destroying the element
element_t * element_ptr_; element_t * element_ptr_{nullptr};
std::vector<std::pair<element_t*, factory_interface>> spare_; std::vector<std::pair<element_t*, factory_interface>> spare_;
}; };
@@ -326,6 +332,7 @@ namespace nana
element_manager() element_manager()
{ {
crook_.employee = nullptr; crook_.employee = nullptr;
border_.employee = nullptr;
} }
public: public:
@@ -339,6 +346,8 @@ namespace nana
element::add_crook<element::crook>(""); element::add_crook<element::crook>("");
element::add_crook<element::menu_crook>("menu_crook"); element::add_crook<element::menu_crook>("menu_crook");
element::add_border<element::border_depressed>("");
} }
return obj; return obj;
} }
@@ -352,8 +361,18 @@ namespace nana
{ {
return _m_get(name, crook_).keeper(); return _m_get(name, crook_).keeper();
} }
void border(const std::string& name, const pat::cloneable<element::provider::factory_interface<element::border_interface>>& factory)
{
_m_add(name, border_, factory);
}
element::border_interface * const * border(const std::string& name) const
{
return _m_get(name, border_).keeper();
}
private: private:
typedef std::lock_guard<std::recursive_mutex> lock_guard; using lock_guard = std::lock_guard<std::recursive_mutex>;
template<typename ElementInterface> template<typename ElementInterface>
void _m_add(const std::string& name, item<ElementInterface>& m, const pat::cloneable<element::provider::factory_interface<ElementInterface>>& factory) void _m_add(const std::string& name, item<ElementInterface>& m, const pat::cloneable<element::provider::factory_interface<ElementInterface>>& factory)
@@ -384,7 +403,8 @@ namespace nana
private: private:
mutable std::recursive_mutex mutex_; mutable std::recursive_mutex mutex_;
item<element::crook_interface> crook_; item<element::crook_interface> crook_;
item<element::border_interface> border_;
}; };
namespace element namespace element
@@ -399,6 +419,16 @@ namespace nana
{ {
return element_manager::instance().crook(name); return element_manager::instance().crook(name);
} }
void provider::add_border(const std::string& name, const pat::cloneable<factory_interface<border_interface>>& factory)
{
element_manager::instance().border(name, factory);
}
border_interface* const * provider::keeper_border(const std::string& name)
{
return element_manager::instance().border(name);
}
}//end namespace element }//end namespace element
//facades //facades
@@ -456,6 +486,26 @@ namespace nana
} }
//end class facade<element::crook> //end class facade<element::crook>
//class facade<element::border>
facade<element::border>::facade()
: facade(nullptr)
{}
facade<element::border>::facade(const char* name)
: keeper_(element::provider().keeper_border(name ? name : ""))
{}
void facade<element::border>::switch_to(const char* name)
{
keeper_ = element::provider().keeper_border(name);
}
bool facade<element::border>::draw(graph_reference graph, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle& r, element_state es)
{
return (*keeper_)->draw(graph, bgcolor, fgcolor, r, es, 2);
}
//end class facade<element::border>
namespace element namespace element
{ {
void set_bground(const char* name, const pat::cloneable<element_interface>& obj) void set_bground(const char* name, const pat::cloneable<element_interface>& obj)

View File

@@ -87,9 +87,6 @@ namespace nana
auto scheme = dynamic_cast< ::nana::widgets::skeletons::text_editor_scheme*>(API::dev::get_scheme(wd)); auto scheme = dynamic_cast< ::nana::widgets::skeletons::text_editor_scheme*>(API::dev::get_scheme(wd));
editor_ = new widgets::skeletons::text_editor(widget_->handle(), graph, scheme); editor_ = new widgets::skeletons::text_editor(widget_->handle(), graph, scheme);
editor_->border_renderer([this](graph_reference graph, const ::nana::color& bgcolor){
draw_border(graph, bgcolor);
});
editor_->multi_lines(false); editor_->multi_lines(false);
editable(false); editable(false);
graph_ = &graph; graph_ = &graph;
@@ -286,13 +283,6 @@ namespace nana
_m_draw_image(); _m_draw_image();
} }
void draw_border(graph_reference graph, const ::nana::color& bgcolor)
{
graph.rectangle(false, (state_.focused ? ::nana::color(0x05, 0x95, 0xE2) : ::nana::color(0x99, 0x9A, 0x9E)));
nana::rectangle r(graph.size());
graph.rectangle(r.pare_off(1), false, bgcolor);
}
std::size_t the_number_of_options() const std::size_t the_number_of_options() const
{ {
return items_.size(); return items_.size();

View File

@@ -12,6 +12,7 @@
*/ */
#include <nana/gui/widgets/skeletons/text_editor.hpp> #include <nana/gui/widgets/skeletons/text_editor.hpp>
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp> #include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
#include <nana/gui/element.hpp>
#include <nana/system/dataexch.hpp> #include <nana/system/dataexch.hpp>
#include <nana/unicode_bidi.hpp> #include <nana/unicode_bidi.hpp>
#include <numeric> #include <numeric>
@@ -1294,6 +1295,15 @@ namespace nana{ namespace widgets
API::create_caret(wd, 1, line_height()); API::create_caret(wd, 1, line_height());
API::bgcolor(wd, colors::white); API::bgcolor(wd, colors::white);
API::fgcolor(wd, colors::black); API::fgcolor(wd, colors::black);
text_area_.border_renderer = [this](graph_reference graph, const ::nana::color& bgcolor)
{
if (!API::widget_borderless(this->window_))
{
::nana::facade<element::border> facade;
facade.draw(graph, bgcolor, API::fgcolor(this->window_), API::window_size(this->window_), API::element_state(this->window_));
}
};
} }
text_editor::~text_editor() text_editor::~text_editor()
@@ -1591,6 +1601,7 @@ namespace nana{ namespace widgets
else else
select_.mode_selection = selection::mode_no_selected; select_.mode_selection = selection::mode_no_selected;
} }
text_area_.border_renderer(graph_, _m_bgcolor()); text_area_.border_renderer(graph_, _m_bgcolor());
return true; return true;
} }
@@ -1848,6 +1859,9 @@ namespace nana{ namespace widgets
if (!API::window_enabled(window_)) if (!API::window_enabled(window_))
fgcolor.blend(bgcolor, 0.5); fgcolor.blend(bgcolor, 0.5);
if (API::widget_borderless(window_))
graph_.rectangle(false, bgcolor);
//Draw background //Draw background
if(attributes_.enable_background) if(attributes_.enable_background)
graph_.rectangle(text_area_.area, true, bgcolor); graph_.rectangle(text_area_.area, true, bgcolor);
@@ -1864,6 +1878,7 @@ namespace nana{ namespace widgets
_m_draw_tip_string(); _m_draw_tip_string();
draw_scroll_rectangle(); draw_scroll_rectangle();
text_area_.border_renderer(graph_, bgcolor); text_area_.border_renderer(graph_, bgcolor);
} }
//public: //public:

View File

@@ -61,9 +61,6 @@ namespace nana{ 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_->border_renderer([this](graph_reference graph, const ::nana::color& clr){
this->_m_draw_border(graph, clr);
});
_m_text_area(graph.width(), graph.height()); _m_text_area(graph.width(), graph.height());
@@ -178,16 +175,6 @@ namespace nana{ namespace drawerbase {
editor_->text_area(r); editor_->text_area(r);
} }
} }
void drawer::_m_draw_border(graph_reference graph, const ::nana::color& bgcolor)
{
if (!API::widget_borderless(widget_->handle()))
{
nana::rectangle r(graph.size());
graph.rectangle(r, false, (status_.has_focus ? ::nana::color(0x05, 0x95, 0xE2) : ::nana::color(0x99, 0x9A, 0x9E)));
graph.rectangle(r.pare_off(1), false, bgcolor);
}
}
//end class drawer //end class drawer
}//end namespace textbox }//end namespace textbox
}//end namespace drawerbase }//end namespace drawerbase