diff --git a/include/eepp/ui/uidatabind.hpp b/include/eepp/ui/uidatabind.hpp index 2f26d368c..73f54a577 100644 --- a/include/eepp/ui/uidatabind.hpp +++ b/include/eepp/ui/uidatabind.hpp @@ -247,15 +247,9 @@ class UIDataBindString { } }; -class UIDataBindHolder { +template class UIDataBindHolder { public: - using UIDataBindVariant = - std::variant>, std::unique_ptr>, - std::unique_ptr>, std::unique_ptr>, - std::unique_ptr>, std::unique_ptr>, - std::unique_ptr>, std::unique_ptr>, - std::unique_ptr>, std::unique_ptr>>; + using UIDataBindVariant = std::variant>...>; UIDataBindHolder& hold( UIDataBindVariant&& ptr ) { mHolder.emplace_back( std::move( ptr ) ); @@ -273,6 +267,26 @@ class UIDataBindHolder { std::vector mHolder; }; +template class UIDataBindHolderKV { + public: + using UIDataBindVariant = std::variant>...>; + + UIDataBindHolderKV& hold( std::string key, UIDataBindVariant&& ptr ) { + mHolder[std::move( key )] = std::move( ptr ); + return *this; + } + + UIDataBindHolderKV& operator+=( std::pair pair ) { + mHolder[std::move( pair.first )] = std::move( pair.second ); + return *this; + } + + void clear() { mHolder.clear(); } + + protected: + UnorderedMap mHolder; +}; + }} // namespace EE::UI #endif // EE_UI_UIDATABIND_HPP diff --git a/include/eepp/ui/uipopupmenu.hpp b/include/eepp/ui/uipopupmenu.hpp index 8ac5e497f..86bf192ce 100644 --- a/include/eepp/ui/uipopupmenu.hpp +++ b/include/eepp/ui/uipopupmenu.hpp @@ -23,15 +23,22 @@ class EE_API UIPopUpMenu : public UIMenu { virtual bool hide(); + virtual void close(); + bool isHiding() const; - bool getCloseOnHide() const; + bool closeOnHide() const; void setCloseOnHide( bool closeOnHide ); + bool closeSubMenusOnClose() const; + + void setCloseSubMenusOnClose( bool closeSubMenusOnClose ); + protected: Action* mHidingAction{ nullptr }; bool mCloseOnHide{ false }; + bool mCloseSubMenusOnClose{ false }; }; class EE_API ContextMenuEvent : public MouseEvent { diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 14a573cb2..a3b2e9a0c 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1118,6 +1118,7 @@ bool UICodeEditor::onCreateContextMenu( const Vector2i& position, const Uint32& } menu->setCloseOnHide( true ); + menu->setCloseSubMenusOnClose( true ); UICodeEditor* editor = this; const auto registerMenu = [editor, this]( UIMenu* menu ) { @@ -1132,11 +1133,8 @@ bool UICodeEditor::onCreateContextMenu( const Vector2i& position, const Uint32& }; registerMenu( menu ); auto subMenus = menu->findAllByType( UI_TYPE_MENUSUBMENU ); - for ( auto* subMenu : subMenus ) { + for ( auto* subMenu : subMenus ) registerMenu( subMenu->getSubMenu() ); - if ( subMenu->getSubMenu()->isType( UI_TYPE_POPUPMENU ) ) - subMenu->getSubMenu()->asType()->setCloseOnHide( true ); - } Vector2f pos( position.asFloat() ); runOnMainThread( [this, menu, pos]() { diff --git a/src/eepp/ui/uimenusubmenu.cpp b/src/eepp/ui/uimenusubmenu.cpp index 8c4d7bcba..7f9835e32 100644 --- a/src/eepp/ui/uimenusubmenu.cpp +++ b/src/eepp/ui/uimenusubmenu.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -70,8 +71,10 @@ void UIMenuSubMenu::onStateChange() { } void UIMenuSubMenu::setSubMenu( UIMenu* subMenu ) { - if ( nullptr != mSubMenu && mSubMenu != subMenu ) + if ( nullptr != mSubMenu && mSubMenu != subMenu ) { + getActionManager()->removeActionsByTagFromTarget( this, String::hash( "subMenu" ) ); mSubMenu->setOwnerNode( nullptr ); + } mSubMenu = subMenu; if ( nullptr != mSubMenu ) mSubMenu->setOwnerNode( this ); @@ -92,11 +95,8 @@ void UIMenuSubMenu::showSubMenu() { mSubMenu->getParent()->worldToNode( pos ); mSubMenu->setPosition( pos ); if ( !mSubMenu->isVisible() ) { - if ( menu->mCurrentSubMenu != nullptr ) { - if ( menu->mCurrentSubMenu != mSubMenu ) { - menu->mCurrentSubMenu->hide(); - } - } + if ( menu->mCurrentSubMenu != nullptr && menu->mCurrentSubMenu != mSubMenu ) + menu->mCurrentSubMenu->hide(); mSubMenu->show(); menu->mCurrentSubMenu = mSubMenu; } @@ -106,11 +106,12 @@ Uint32 UIMenuSubMenu::onMouseOver( const Vector2i& pos, const Uint32& flags ) { if ( nullptr == mCurWait ) { mCurWait = Actions::Runnable::New( [this] { - if ( isMouseOver() ) + if ( isMouseOver() && mSubMenu ) showSubMenu(); mCurWait = nullptr; }, mMaxTime ); + mCurWait->setTag( String::hash( "subMenu" ) ); runAction( mCurWait ); } return UIMenuItem::onMouseOver( pos, flags ); diff --git a/src/eepp/ui/uipopupmenu.cpp b/src/eepp/ui/uipopupmenu.cpp index 1f316a22f..bbd4bb081 100644 --- a/src/eepp/ui/uipopupmenu.cpp +++ b/src/eepp/ui/uipopupmenu.cpp @@ -85,11 +85,19 @@ bool UIPopUpMenu::hide() { return false; } +void UIPopUpMenu::close() { + UIMenu::close(); + + auto menuSubMenus = findAllByType( UI_TYPE_MENUSUBMENU ); + for ( auto* menu : menuSubMenus ) + menu->asType()->getSubMenu()->close(); +} + bool UIPopUpMenu::isHiding() const { return mHidingAction != nullptr; } -bool UIPopUpMenu::getCloseOnHide() const { +bool UIPopUpMenu::closeOnHide() const { return mCloseOnHide; } @@ -97,4 +105,12 @@ void UIPopUpMenu::setCloseOnHide( bool closeOnHide ) { mCloseOnHide = closeOnHide; } +bool UIPopUpMenu::closeSubMenusOnClose() const { + return mCloseSubMenusOnClose; +} + +void UIPopUpMenu::setCloseSubMenusOnClose( bool closeSubMenusOnClose ) { + mCloseSubMenusOnClose = closeSubMenusOnClose; +} + }} // namespace EE::UI diff --git a/src/tools/ecode/uibuildsettings.cpp b/src/tools/ecode/uibuildsettings.cpp index 4624773ee..75fe08f24 100644 --- a/src/tools/ecode/uibuildsettings.cpp +++ b/src/tools/ecode/uibuildsettings.cpp @@ -145,9 +145,8 @@ class UICustomOutputParserWindow : public UIWindow { return true; } ); - mOptDb = UIDataBind::New( + mDataBindHolder += UIDataBind::New( &mTmpCfg.type, cpTypeddl, projectOutputParserTypesConverter, "selected-index" ); - mDataBindHolder += UIDataBind::New( &mTmpCfg.patternOrder.file, find( "file_name_pos" ) ); mDataBindHolder += @@ -181,8 +180,7 @@ class UICustomOutputParserWindow : public UIWindow { UIWidget* mLayoutCont{ nullptr }; ProjectBuildOutputParserConfig mTmpCfg; ProjectBuildOutputParserConfig& mCfg; - UIDataBindHolder mDataBindHolder; - std::unique_ptr> mOptDb; + UIDataBindHolder mDataBindHolder; virtual void onWindowReady() { forcedApplyStyle(); @@ -298,7 +296,7 @@ class UIBuildStep : public UILinearLayout { UIBuildSettings* mBuildSettings{ nullptr }; size_t mStepNum{ 0 }; ProjectBuildStep* mStep; - UIDataBindHolder mDataBindHolder; + UIDataBindHolder mDataBindHolder; }; static const auto SETTINGS_PANEL_XML = R"xml( diff --git a/src/tools/ecode/uibuildsettings.hpp b/src/tools/ecode/uibuildsettings.hpp index 5bc4e0c17..5b33c212c 100644 --- a/src/tools/ecode/uibuildsettings.hpp +++ b/src/tools/ecode/uibuildsettings.hpp @@ -27,7 +27,7 @@ class UIBuildSettings : public UIRelativeLayout { ProjectBuild& mBuild; ProjectBuildConfiguration& mConfig; - UIDataBindHolder mDataBindHolder; + UIDataBindHolder mDataBindHolder; UITab* mTab{ nullptr }; String mOldName; std::unordered_map> mCbs;