diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 932e35c8..6de9ba97 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -29,6 +29,13 @@ namespace nana /// Traits for widget classes template struct widget_traits + { + using event_type = typename Widget::event_type; + using scheme_type = typename Widget::scheme_type; + }; + + template<> + struct widget_traits { using event_type = ::nana::general_events; using scheme_type = ::nana::widget_colors; diff --git a/include/nana/gui/widgets/combox.hpp b/include/nana/gui/widgets/combox.hpp index beb1cece..17bb7cfe 100644 --- a/include/nana/gui/widgets/combox.hpp +++ b/include/nana/gui/widgets/combox.hpp @@ -229,7 +229,8 @@ namespace nana nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override; }; - namespace dev + /* + namespace dev //deprecated { template<> struct widget_traits @@ -238,5 +239,6 @@ namespace nana using scheme_type = ::nana::widgets::skeletons::text_editor_scheme; }; } + */ } #endif diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 140d6dd2..652171a4 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -664,14 +664,16 @@ By \a clicking on one header the list get \a reordered, first up, and then down void _m_erase_key(nana::detail::key_interface*); }; + /* namespace dev { template<> - struct widget_traits + struct widget_traits //deprecated { using event_type = drawerbase::listbox::listbox_events; using scheme_type = drawerbase::listbox::scheme; }; } + */ }//end namespace nana #endif diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index 22b780e4..09e64faf 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -110,15 +110,17 @@ namespace nana void _m_caption(::nana::string&&); }; //end class spinbox + /* namespace dev { template<> - struct widget_traits + struct widget_traits //deprecated { using event_type = drawerbase::spinbox::spinbox_events; using scheme_type = ::nana::widgets::skeletons::text_editor_scheme; }; } + */ }//end namespace nana #endif //NANA_GUI_WIDGET_SPINBOX_HPP diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index 86556cec..3f412f9b 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -336,13 +336,19 @@ namespace nana namespace nana -{ +{ namespace drawerbase { namespace tabbar_lite { class model; + struct events + : public general_events + { + basic_event selected; + }; + class driver : public drawer_trigger { @@ -364,25 +370,39 @@ namespace nana } }//end namespace drawerbase - class tabbar_lite - : public widget_object + class tabbar_lite + : public widget_object + { + public: + tabbar_lite() = default; + tabbar_lite(window, bool visible = true, const::nana::rectangle& = {}); + + public: //capacity + std::size_t length() const; + + public: //modifiers + void attach(std::size_t pos, window); + window attach(std::size_t pos) const; + + void push_back(std::string text, ::nana::any par = {}); + void push_front(std::string text, ::nana::any par = {}); + + std::size_t selected() const; + void erase(std::size_t pos, bool close_attached = true); + }; + + /* + namespace dev + { + /// Traits for widget classes + template<> + struct widget_traits //deprecated { - public: - tabbar_lite() = default; - tabbar_lite(window, bool visible = true, const::nana::rectangle& = {}); - - public: //capacity - std::size_t length() const; - - public: //modifiers - void attach(std::size_t pos, window); - - void push_back(std::string text, ::nana::any par = {}); - void push_front(std::string text, ::nana::any par = {}); - - std::size_t selected() const; - void erase(std::size_t pos, bool close_attached = true); + using event_type = drawerbase::tabbar_lite::events; + using scheme_type = ::nana::widget_colors; }; + } + */ } #endif diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 85bac2a6..4360cd74 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -195,15 +195,17 @@ namespace nana void _m_typeface(const paint::font&) override; }; + /* namespace dev { /// Traits for widget classes template<> - struct widget_traits + struct widget_traits //deprecated { using event_type = drawerbase::textbox::textbox_events; using scheme_type = ::nana::widgets::skeletons::text_editor_scheme; }; } + */ }//end namespace nana #endif diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 0288388e..2da63cda 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -134,7 +134,8 @@ namespace nana protected: typedef DrawerTrigger drawer_trigger_t; public: - using scheme_type = Scheme; + using scheme_type = Scheme; + using event_type = Events; widget_object() : events_{ std::make_shared() }, @@ -147,7 +148,7 @@ namespace nana API::close_window(handle_); } - Events& events() const + event_type& events() const { return *events_; } @@ -228,6 +229,7 @@ namespace nana typedef DrawerTrigger drawer_trigger_t; public: using scheme_type = Scheme; + using event_type = Events; widget_object() : events_{ std::make_shared() }, scheme_{ API::dev::make_scheme() } @@ -239,7 +241,7 @@ namespace nana API::close_window(handle_); } - Events& events() const + event_type& events() const { return *events_; } @@ -297,6 +299,7 @@ namespace nana typedef DrawerTrigger drawer_trigger_t; public: using scheme_type = Scheme; + using event_type = Events; widget_object() { @@ -322,7 +325,7 @@ namespace nana API::close_window(handle_); } - Events& events() const + event_type& events() const { return *events_; } @@ -451,6 +454,7 @@ namespace nana typedef int drawer_trigger_t; public: using scheme_type = Scheme; + using event_type = Events; widget_object() : events_{ std::make_shared() }, scheme_{ API::dev::make_scheme() } @@ -462,7 +466,7 @@ namespace nana API::close_window(handle_); } - Events& events() const + event_type& events() const { return *events_; } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 598bd962..1e8d96ac 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -2829,7 +2829,7 @@ namespace nana { auto i = impl_->dock_factoris.find(factory); if (i == impl_->dock_factoris.end()) - throw std::invalid_argument("nana::place - invalid factory name(" + factory + ")"); + throw std::invalid_argument("invalid factory name(" + factory + ") of dockpane"); auto dock_ptr = i->second; dock_ptr->attached->set_display(true); diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 62bd8753..accb35c9 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -85,7 +85,6 @@ namespace nana //draw caption auto text = API::window_caption(window_handle_); - text = L"dockarea-caption"; text_rd_->render({ 3, 1 }, text.data(), text.size(), graph.size().width - 20, true); //draw x button @@ -303,6 +302,17 @@ namespace nana if (!tabbar_ && panels_.size() > 0) { tabbar_.reset(new tabbar_lite(*this)); + + tabbar_->events().selected.clear(); + tabbar_->events().selected([this] + { + auto handle = tabbar_->attach(tabbar_->selected()); + if (handle) + caption_.caption(API::window_caption(handle)); + else + caption_.caption(::nana::string()); + }); + tabbar_->move({ 0, r.bottom() - 20, r.width, 20 }); r.height -= 20; @@ -319,7 +329,12 @@ namespace nana if (tabbar_) { tabbar_->push_back(::nana::charset(wdg->caption())); - tabbar_->attach(panels_.size(), *wdg); + tabbar_->attach(panels_.size(), wdg->handle()); + } + + if (panels_.empty()) + { + caption_.caption(wdg->caption()); } panels_.emplace_back(); diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index cb6eb878..959d5ff7 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -344,7 +344,7 @@ namespace nana { if(i < list_.size()) return at_no_bound_check(i); - throw std::out_of_range("Nana.GUI.tabbar::at() is out of range"); + throw std::out_of_range("invalid position of tabbar"); } iterator iterator_at(std::size_t pos) @@ -370,7 +370,7 @@ namespace nana { if(pos < list_.size()) return at_no_bound_check(pos); - throw std::out_of_range("Nana.GUI.tabbar::at() const is out of range"); + throw std::out_of_range("invalid position of tabbar"); } const nana::any& at_no_bound_check(std::size_t pos) const @@ -1345,15 +1345,21 @@ namespace nana using graph_reference = ::nana::paint::graphics&; static const std::size_t npos = static_cast(-1); - void set_widget(widget& wdg) + void set_widget(::nana::tabbar_lite& wdg) { widget_ = &wdg; } - ::nana::dev::widget_traits::scheme_type & scheme() + ::nana::tabbar_lite* widget_ptr() const + { + return widget_; + } + /* + ::nana::dev::widget_traits::scheme_type & scheme() //deprecated { return API::scheme(*widget_); } + */ std::forward_list& items() { @@ -1407,7 +1413,7 @@ namespace nana return indexes_; } private: - widget * widget_{ nullptr }; + ::nana::tabbar_lite * widget_{ nullptr }; std::forward_list items_; indexes indexes_; }; @@ -1421,7 +1427,7 @@ namespace nana { _m_calc_metrics(graph, model.items()); - auto & scheme = model.scheme(); + auto & scheme = model.widget_ptr()->scheme(); //draw background graph.rectangle(true, scheme.background); @@ -1499,7 +1505,7 @@ namespace nana void driver::attached(widget_reference wdg, graph_reference) { - model_->set_widget(wdg); + model_->set_widget(dynamic_cast(wdg)); } //Overrides drawer_trigger's method @@ -1533,11 +1539,17 @@ namespace nana if ((indexes.hovered_pos == model_->npos) || (indexes.active_pos == indexes.hovered_pos)) return; - indexes.active_pos = indexes.hovered_pos; - model_->show_attached_window(); + if (indexes.active_pos != indexes.hovered_pos) + { + indexes.active_pos = indexes.hovered_pos; + model_->show_attached_window(); - refresh(graph); - API::lazy_refresh(); + refresh(graph); + API::lazy_refresh(); + + event_arg arg; + model_->widget_ptr()->events().selected.emit(arg); + } } //end class driver } @@ -1577,6 +1589,20 @@ namespace nana throw std::out_of_range("invalid position of tabbar_lite"); } + window tabbar_lite::attach(std::size_t pos_set) const + { + auto model = get_drawer_trigger().get_model(); + internal_scope_guard lock; + + for (auto & m : model->items()) + { + if (0 == pos_set--) + return m.attached_window; + } + + throw std::out_of_range("invalid position of tabbar_lite"); + } + void tabbar_lite::push_back(std::string text, ::nana::any any) { auto & items = get_drawer_trigger().get_model()->items(); @@ -1622,10 +1648,12 @@ namespace nana const auto len = length(); if (len <= pos) - throw std::out_of_range("tabbar_lite: out of range"); + throw std::out_of_range("invalid position of tabbar_lite"); auto active_pos = model->get_indexes().active_pos; + //selection_changed is used to determine whether the title will be updated + bool selection_changed = true; if (pos == active_pos) { if (active_pos + 1 == len) @@ -1638,6 +1666,8 @@ namespace nana } else if (pos < active_pos) --active_pos; + else + selection_changed = false; model->get_indexes().active_pos = active_pos; @@ -1653,6 +1683,12 @@ namespace nana if (close_attached && attached_wd) API::close_window(attached_wd); + + if (selection_changed) + { + event_arg arg; + events().selected.emit(arg); + } } //end class tabbar }//end namespace nana