From 64899a3d6a1b2776271f666b03a6bd177d430a57 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 28 Aug 2017 21:09:04 +0800 Subject: [PATCH] add functions to menubar for auto-close when mouse leave --- include/nana/gui/widgets/menu.hpp | 5 ++++ include/nana/gui/widgets/menubar.hpp | 11 ++++++++ source/gui/widgets/menu.cpp | 5 ++++ source/gui/widgets/menubar.cpp | 40 ++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/include/nana/gui/widgets/menu.hpp b/include/nana/gui/widgets/menu.hpp index f8ec1167..b2315ac0 100644 --- a/include/nana/gui/widgets/menu.hpp +++ b/include/nana/gui/widgets/menu.hpp @@ -181,6 +181,11 @@ namespace nana void renderer(const pat::cloneable&); ///< Sets a user-defined renderer. const pat::cloneable& renderer() const; + /// Returns the handle of menu window + /** + * @return handle of menu window, nullptr if the menu hasn't been popped up. + */ + window handle() const; private: void _m_popup(window, const point& position, bool called_by_menubar); private: diff --git a/include/nana/gui/widgets/menubar.hpp b/include/nana/gui/widgets/menubar.hpp index a76b21bb..c245df4a 100644 --- a/include/nana/gui/widgets/menubar.hpp +++ b/include/nana/gui/widgets/menubar.hpp @@ -64,6 +64,7 @@ namespace nana nana::menu* push_back(const std::string&); nana::menu* at(size_t) const; std::size_t size() const; + bool cancel(); private: void attached(widget_reference, graph_reference) override; void refresh(graph_reference) override; @@ -126,6 +127,16 @@ namespace nana menu& push_back(const std::string&); ///< Appends a new (empty) menu. menu& at(size_t index) const; ///< Gets the menu specified by index. std::size_t length() const; ///< Number of menus. + + /// Deselects the menu + /** + * If a menu is popped up, the menu deselects the item and close the popuped menu. + * @return true if an item is deselected, false otherwise. + */ + bool cancel(); + + /// Determines the mouse is hovered on the menubar or its popped menu. + bool hovered() const; private: ::nana::event_handle evt_resized_{nullptr}; };//end class menubar diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 36dbb7de..26b21812 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -1355,6 +1355,11 @@ namespace nana impl_->mbuilder.renderer(rd); } + window menu::handle() const + { + return (impl_->window_ptr ? impl_->window_ptr->handle() : nullptr); + } + void menu::_m_popup(window wd, const point& pos, bool called_by_menubar) { if (impl_->mbuilder.data().items.size()) diff --git a/source/gui/widgets/menubar.cpp b/source/gui/widgets/menubar.cpp index 4ed24c67..ebf8420e 100644 --- a/source/gui/widgets/menubar.cpp +++ b/source/gui/widgets/menubar.cpp @@ -165,6 +165,15 @@ namespace nana return items_->cont().size(); } + bool trigger::cancel() + { + if (nana::npos == state_.active) + return false; + + _m_total_close(); + return true; + } + void trigger::attached(widget_reference widget, graph_reference graph) { graph_ = &graph; @@ -624,5 +633,36 @@ namespace nana { return get_drawer_trigger().size(); } + + bool menubar::cancel() + { + return get_drawer_trigger().cancel(); + } + + bool menubar::hovered() const + { + auto const native_handle = API::root(this->handle()); + if (native_handle) + { + auto wd = API::find_window(API::cursor_position()); + if (wd == this->handle()) + return true; + + while (wd) + { + auto owner = API::get_owner_window(wd); + if (API::root(owner) == native_handle) + { + for (std::size_t i = 0; i < get_drawer_trigger().size(); ++i) + { + if(get_drawer_trigger().at(i)->handle() == wd) + return true; + } + } + wd = owner; + } + } + return false; + } //end class menubar }//end namespace nana