From bb49ba651c56cd77aec604c2bc5d01cbdf50f151 Mon Sep 17 00:00:00 2001 From: cnjinhao Date: Wed, 14 Jan 2015 04:30:35 +0800 Subject: [PATCH] New border element --- include/nana/gui/element.hpp | 61 +++++++++++++---- include/nana/gui/widgets/textbox.hpp | 1 - source/gui/element.cpp | 70 +++++++++++++++++--- source/gui/widgets/combox.cpp | 10 --- source/gui/widgets/skeletons/text_editor.cpp | 15 +++++ source/gui/widgets/textbox.cpp | 13 ---- 6 files changed, 122 insertions(+), 48 deletions(-) diff --git a/include/nana/gui/element.hpp b/include/nana/gui/element.hpp index 4a496601..e5da56a1 100644 --- a/include/nana/gui/element.hpp +++ b/include/nana/gui/element.hpp @@ -30,19 +30,17 @@ namespace nana class element_interface { public: - typedef paint::graphics & graph_reference; - - virtual ~element_interface() - {} + using graph_reference = paint::graphics&; + virtual ~element_interface() = default; virtual bool draw(graph_reference, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle&, element_state) = 0; }; class crook_interface { public: - typedef paint::graphics & graph_reference; - typedef checkstate state; + using graph_reference = paint::graphics&; + using state = checkstate; struct data { @@ -50,12 +48,19 @@ namespace nana 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; }; + 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 { public: @@ -87,16 +92,27 @@ namespace nana void add_crook(const std::string& name, const pat::cloneable>&); crook_interface* const * keeper_crook(const std::string& name); + + void add_border(const std::string&, const pat::cloneable>&); + border_interface* const * keeper_border(const std::string&); }; + class crook; template void add_crook(const std::string& name) { - typedef provider::factory factory_t; + using factory_t = provider::factory; provider().add_crook(name, pat::cloneable(factory_t())); } - class crook; + class border; + + template + void add_border(const std::string& name) + { + using factory_t = provider::factory; + provider().add_border(name, pat::cloneable(factory_t())); + } }//end namespace element template class facade; @@ -106,8 +122,8 @@ namespace nana : public element::element_interface { public: - typedef ::nana::paint::graphics & graph_reference; - typedef element::crook_interface::state state; + using graph_reference = ::nana::paint::graphics &; + using state = element::crook_interface::state; facade(); facade(const char* name); @@ -126,7 +142,24 @@ namespace nana private: element::crook_interface::data data_; element::crook_interface* const * keeper_; - }; + }; //end class facade + + template<> + class facade + : 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 namespace element { diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 16028c70..9f5f7552 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -80,7 +80,6 @@ namespace nana void typeface_changed(graph_reference) override; private: void _m_text_area(unsigned width, unsigned height); - void _m_draw_border(graph_reference, const ::nana::color& bgcolor); private: widget* widget_; struct status_type diff --git a/source/gui/element.cpp b/source/gui/element.cpp index 42c0756a..693c279c 100644 --- a/source/gui/element.cpp +++ b/source/gui/element.cpp @@ -234,7 +234,7 @@ namespace nana { if(colormap[u][v] & 0xFF000000) continue; - graph.set_pixel(x + v, y, static_cast(colormap[u][v])); + graph.set_pixel(x + v, y, static_cast(colormap[u][v])); } ++y; } @@ -257,7 +257,18 @@ namespace nana 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((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 class element_object @@ -267,11 +278,6 @@ namespace nana typedef pat::cloneable> factory_interface; public: - element_object() - : element_ptr_(nullptr) - { - } - ~element_object() { if(factory_) @@ -306,7 +312,7 @@ namespace nana } private: factory_interface factory_; //Keep the factory for destroying the element - element_t * element_ptr_; + element_t * element_ptr_{nullptr}; std::vector> spare_; }; @@ -326,6 +332,7 @@ namespace nana element_manager() { crook_.employee = nullptr; + border_.employee = nullptr; } public: @@ -339,6 +346,8 @@ namespace nana element::add_crook(""); element::add_crook("menu_crook"); + + element::add_border(""); } return obj; } @@ -352,8 +361,18 @@ namespace nana { return _m_get(name, crook_).keeper(); } + + void border(const std::string& name, const pat::cloneable>& factory) + { + _m_add(name, border_, factory); + } + + element::border_interface * const * border(const std::string& name) const + { + return _m_get(name, border_).keeper(); + } private: - typedef std::lock_guard lock_guard; + using lock_guard = std::lock_guard; template void _m_add(const std::string& name, item& m, const pat::cloneable>& factory) @@ -384,7 +403,8 @@ namespace nana private: mutable std::recursive_mutex mutex_; - item crook_; + item crook_; + item border_; }; namespace element @@ -399,6 +419,16 @@ namespace nana { return element_manager::instance().crook(name); } + + void provider::add_border(const std::string& name, const pat::cloneable>& 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 //facades @@ -456,6 +486,26 @@ namespace nana } //end class facade + //class facade + facade::facade() + : facade(nullptr) + {} + + facade::facade(const char* name) + : keeper_(element::provider().keeper_border(name ? name : "")) + {} + + void facade::switch_to(const char* name) + { + keeper_ = element::provider().keeper_border(name); + } + + bool facade::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 + namespace element { void set_bground(const char* name, const pat::cloneable& obj) diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index 8e134047..dcd8aad8 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -87,9 +87,6 @@ namespace nana 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_->border_renderer([this](graph_reference graph, const ::nana::color& bgcolor){ - draw_border(graph, bgcolor); - }); editor_->multi_lines(false); editable(false); graph_ = &graph; @@ -286,13 +283,6 @@ namespace nana _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 { return items_.size(); diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 45538fbf..89f43b9c 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -1294,6 +1295,15 @@ namespace nana{ namespace widgets API::create_caret(wd, 1, line_height()); API::bgcolor(wd, colors::white); 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 facade; + facade.draw(graph, bgcolor, API::fgcolor(this->window_), API::window_size(this->window_), API::element_state(this->window_)); + } + }; } text_editor::~text_editor() @@ -1591,6 +1601,7 @@ namespace nana{ namespace widgets else select_.mode_selection = selection::mode_no_selected; } + text_area_.border_renderer(graph_, _m_bgcolor()); return true; } @@ -1848,6 +1859,9 @@ namespace nana{ namespace widgets if (!API::window_enabled(window_)) fgcolor.blend(bgcolor, 0.5); + if (API::widget_borderless(window_)) + graph_.rectangle(false, bgcolor); + //Draw background if(attributes_.enable_background) graph_.rectangle(text_area_.area, true, bgcolor); @@ -1864,6 +1878,7 @@ namespace nana{ namespace widgets _m_draw_tip_string(); draw_scroll_rectangle(); + text_area_.border_renderer(graph_, bgcolor); } //public: diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index a68fd317..5e6b1e5a 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -61,9 +61,6 @@ namespace nana{ namespace drawerbase { editor_ = new text_editor(wd, graph, dynamic_cast<::nana::widgets::skeletons::text_editor_scheme*>(scheme)); 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()); @@ -178,16 +175,6 @@ namespace nana{ namespace drawerbase { 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 namespace textbox }//end namespace drawerbase