diff --git a/include/eepp/ui/uimenu.hpp b/include/eepp/ui/uimenu.hpp index 252ecfe0f..d418ea331 100644 --- a/include/eepp/ui/uimenu.hpp +++ b/include/eepp/ui/uimenu.hpp @@ -43,7 +43,7 @@ class EE_API UIMenu : public UIWidget { UIMenuItem* getItem( const String& text ); - UIMenuItem* getItemId( const String& id ); + UIMenuItem* getItemId( const std::string& id ); Uint32 getItemIndex( UIWidget* item ); diff --git a/include/eepp/ui/uimenubar.hpp b/include/eepp/ui/uimenubar.hpp index ea536c1d6..0894e311a 100644 --- a/include/eepp/ui/uimenubar.hpp +++ b/include/eepp/ui/uimenubar.hpp @@ -12,8 +12,6 @@ class EE_API UIMenuBar : public UIWidget { public: static UIMenuBar* New(); - UIMenuBar(); - virtual ~UIMenuBar(); virtual Uint32 getType() const; @@ -26,9 +24,19 @@ class EE_API UIMenuBar : public UIWidget { virtual void setTheme( UITheme* theme ); - UISelectButton* getButton( const String& buttonText ); + UISelectButton* getButton( const String& buttonText ) const; - UIPopUpMenu* getPopUpMenu( const String& buttonText ); + UISelectButton* getButton( const Uint32& index ) const; + + UIPopUpMenu* getPopUpMenu( const String& buttonText ) const; + + UIPopUpMenu* getPopUpMenu( const Uint32& index ) const; + + UIMenuBar* setPopUpMenu( const Uint32& index, UIPopUpMenu* menu ); + + size_t getButtonsCount() const; + + UIPopUpMenu* getMenuFromButton( UISelectButton* Button ); Uint32 getMenuHeight() const; @@ -38,7 +46,13 @@ class EE_API UIMenuBar : public UIWidget { virtual void loadFromXmlNode( const pugi::xml_node& node ); + UIPopUpMenu* getCurrentMenu() const; + + void setCurrentMenu( UIPopUpMenu* currentMenu ); + protected: + UIMenuBar(); + typedef std::vector> MenuBarList; Uint32 mMenuHeight; @@ -54,8 +68,6 @@ class EE_API UIMenuBar : public UIWidget { virtual void onPaddingChange(); - UIPopUpMenu* getMenuFromButton( UISelectButton* Button ); - bool isPopUpMenuChild( Node* node ); void unselectButtons(); diff --git a/include/eepp/ui/uimenusubmenu.hpp b/include/eepp/ui/uimenusubmenu.hpp index 3fac5d43a..4fc473ca2 100644 --- a/include/eepp/ui/uimenusubmenu.hpp +++ b/include/eepp/ui/uimenusubmenu.hpp @@ -54,8 +54,6 @@ class EE_API UIMenuSubMenu : public UIMenuItem { virtual void onAlphaChange(); void onSubMenuFocusLoss( const Event* Event ); - - void onHideByClick( const Event* Event ); }; }} // namespace EE::UI diff --git a/src/eepp/ui/uimenu.cpp b/src/eepp/ui/uimenu.cpp index fdc708652..a32220d64 100644 --- a/src/eepp/ui/uimenu.cpp +++ b/src/eepp/ui/uimenu.cpp @@ -214,7 +214,7 @@ UIMenuItem* UIMenu::getItem( const String& text ) { return nullptr; } -UIMenuItem* UIMenu::getItemId( const String& id ) { +UIMenuItem* UIMenu::getItemId( const std::string& id ) { for ( Uint32 i = 0; i < mItems.size(); i++ ) { if ( mItems[i]->isType( UI_TYPE_MENUITEM ) ) { UIMenuItem* tMenuItem = mItems[i]->asType(); diff --git a/src/eepp/ui/uimenubar.cpp b/src/eepp/ui/uimenubar.cpp index dab33ef7e..e6186bba3 100644 --- a/src/eepp/ui/uimenubar.cpp +++ b/src/eepp/ui/uimenubar.cpp @@ -23,6 +23,15 @@ UIMenuBar::UIMenuBar() : applyDefaultTheme(); } +UIPopUpMenu* UIMenuBar::getCurrentMenu() const { + return mCurrentMenu; +} + +void UIMenuBar::setCurrentMenu( UIPopUpMenu* currentMenu ) { + mCurrentMenu = currentMenu; + mWaitingUp = nullptr; +} + UIMenuBar::~UIMenuBar() { destroyMenues(); } @@ -30,7 +39,7 @@ UIMenuBar::~UIMenuBar() { void UIMenuBar::destroyMenues() { if ( !SceneManager::instance()->isShuttingDown() ) { for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->second->getParent() != this ) { + if ( it->second && it->second->getParent() != this ) { // Changing the parent ensures that the menu will be destroyed when the menubar is // destroyed it->second->setParent( this ); @@ -48,8 +57,6 @@ bool UIMenuBar::isType( const Uint32& type ) const { } void UIMenuBar::addMenuButton( const String& buttonText, UIPopUpMenu* menu ) { - eeASSERT( nullptr != menu ); - UISelectButton* button = UISelectButton::NewWithTag( "menubar::button" ); button->setParent( this ); button->setText( buttonText ); @@ -58,27 +65,32 @@ void UIMenuBar::addMenuButton( const String& buttonText, UIPopUpMenu* menu ) { button->on( Event::OnSizeChange, [this]( const Event* ) { refreshButtons(); } ); button->on( Event::OnFocus, [this, button]( const Event* ) { if ( getEventDispatcher()->getReleaseTrigger() & EE_BUTTON_LMASK ) { - getMenuFromButton( button )->setFocus(); + UIPopUpMenu* menu = getMenuFromButton( button ); + if ( menu ) + menu->setFocus(); } } ); - menu->setVisible( false ); - menu->setEnabled( false ); - menu->setOwnerNode( button ); - // This will force to change the parent when shown, and force the CSS style reload. - menu->setParent( this ); - menu->on( Event::OnVisibleChange, [this, button]( const Event* event ) { - if ( event->getNode()->isVisible() ) { - button->select(); - mCurrentMenu = event->getNode()->asType(); - } else if ( button->isSelected() ) { - button->unselect(); - } - } ); - menu->on( Event::OnItemClicked, [this]( const Event* ) { - mWaitingUp = nullptr; - mCurrentMenu = nullptr; - } ); + if ( menu ) { + menu->setVisible( false ); + menu->setEnabled( false ); + menu->setOwnerNode( button ); + // This will force to change the parent when shown, and force the CSS style reload. + menu->setParent( this ); + menu->on( Event::OnVisibleChange, [this, button]( const Event* event ) { + if ( event->getNode()->isVisible() ) { + button->select(); + mCurrentMenu = event->getNode()->asType(); + } else if ( button->isSelected() ) { + button->unselect(); + mCurrentMenu = nullptr; + } + } ); + menu->on( Event::OnItemClicked, [this]( const Event* ) { + mWaitingUp = nullptr; + mCurrentMenu = nullptr; + } ); + } mButtons.push_back( std::make_pair( button, menu ) ); @@ -105,7 +117,8 @@ void UIMenuBar::removeMenuButton( const String& buttonText ) { for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { if ( it->first->getText() == buttonText ) { it->first->close(); - it->second->close(); + if ( it->second ) + it->second->close(); mButtons.erase( it ); refreshButtons(); break; @@ -113,24 +126,40 @@ void UIMenuBar::removeMenuButton( const String& buttonText ) { } } -UISelectButton* UIMenuBar::getButton( const String& buttonText ) { - for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first->getText() == buttonText ) { - return it->first; - } - } +UISelectButton* UIMenuBar::getButton( const String& buttonText ) const { + for ( const auto& it : mButtons ) + if ( it.first->getText() == buttonText ) + return it.first; return nullptr; } -UIPopUpMenu* UIMenuBar::getPopUpMenu( const String& buttonText ) { - for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first->getText() == buttonText ) { - return it->second; - } - } +UISelectButton* UIMenuBar::getButton( const Uint32& index ) const { + eeASSERT( index < mButtons.size() ); + return mButtons[index].first; +} + +UIPopUpMenu* UIMenuBar::getPopUpMenu( const String& buttonText ) const { + for ( const auto& it : mButtons ) + if ( it.first->getText() == buttonText ) + return it.second; return nullptr; } +UIPopUpMenu* UIMenuBar::getPopUpMenu( const Uint32& index ) const { + eeASSERT( index < mButtons.size() ); + return mButtons[index].second; +} + +UIMenuBar* UIMenuBar::setPopUpMenu( const Uint32& index, UIPopUpMenu* menu ) { + eeASSERT( index < mButtons.size() ); + mButtons[index].second = menu; + return this; +} + +size_t UIMenuBar::getButtonsCount() const { + return mButtons.size(); +} + Uint32 UIMenuBar::getMenuHeight() const { return mMenuHeight; } @@ -195,11 +224,14 @@ Uint32 UIMenuBar::onMessage( const NodeMessage* msg ) { switch ( msg->getMsg() ) { case NodeMessage::MouseUp: mWaitingUp = nullptr; + break; case NodeMessage::MouseDown: case NodeMessage::MouseOver: { if ( msg->getSender()->isType( UI_TYPE_SELECTBUTTON ) ) { UISelectButton* tbut = msg->getSender()->asType(); UIPopUpMenu* tpop = getMenuFromButton( tbut ); + if ( tpop == nullptr ) + return 1; Vector2f pos( tbut->getPosition().x, tbut->getPosition().y + tbut->getSize().getHeight() ); @@ -238,7 +270,8 @@ Uint32 UIMenuBar::onMessage( const NodeMessage* msg ) { for ( auto& it : mButtons ) { if ( it.first != msg->getSender() ) { it.first->unselect(); - it.second->hide(); + if ( it.second ) + it.second->hide(); } } return 1; @@ -274,21 +307,16 @@ void UIMenuBar::unselectButtons() { } UIPopUpMenu* UIMenuBar::getMenuFromButton( UISelectButton* Button ) { - for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first == Button ) { + for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) + if ( it->first == Button ) return it->second; - } - } - return nullptr; } bool UIMenuBar::isPopUpMenuChild( Node* node ) { - for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->second == node || it->second->isParentOf( node ) ) { + for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) + if ( it->second == node || it->second->isParentOf( node ) ) return true; - } - } return false; } @@ -310,6 +338,18 @@ void UIMenuBar::loadFromXmlNode( const pugi::xml_node& node ) { if ( "menu" == name ) { std::string text( item.attribute( "text" ).as_string() ); + + auto attr = item.find_attribute( []( const pugi::xml_attribute& attribute ) { + if ( strcmp( attribute.name(), "nomenu" ) == 0 ) + return true; + return false; + } ); + + if ( !attr.empty() ) { + addMenuButton( getTranslatorString( text ), nullptr ); + continue; + } + UIPopUpMenu* subMenu = UIPopUpMenu::New(); if ( nullptr != getDrawInvalidator() ) diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index d0d8c5dc7..9009c1084 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -92,6 +92,7 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, ui.panelFontSize = ini.getValue( "ui", "panel_font_size", "11dp" ); ui.showSidePanel = ini.getValueB( "ui", "show_side_panel", true ); ui.showStatusBar = ini.getValueB( "ui", "show_status_bar", true ); + ui.showMenuBar = ini.getValueB( "ui", "show_menu_bar", false ); ui.panelPosition = panelPositionFromString( ini.getValue( "ui", "panel_position", "left" ) ); ui.serifFont = ini.getValue( "ui", "serif_font", "fonts/NotoSans-Regular.ttf" ); ui.monospaceFont = ini.getValue( "ui", "monospace_font", "fonts/DejaVuSansMono.ttf" ); @@ -229,6 +230,7 @@ void AppConfig::save( const std::vector& recentFiles, ini.setValue( "ui", "panel_font_size", ui.panelFontSize.toString() ); ini.setValueB( "ui", "show_side_panel", ui.showSidePanel ); ini.setValueB( "ui", "show_status_bar", ui.showStatusBar ); + ini.setValueB( "ui", "show_menu_bar", ui.showMenuBar ); ini.setValue( "ui", "panel_position", panelPositionToString( ui.panelPosition ) ); ini.setValue( "ui", "serif_font", ui.serifFont ); ini.setValue( "ui", "monospace_font", ui.monospaceFont ); diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index ec93045a3..49a1adf9c 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -30,6 +30,7 @@ struct UIConfig { StyleSheetLength panelFontSize{ 11, StyleSheetLength::Dp }; bool showSidePanel{ true }; bool showStatusBar{ true }; + bool showMenuBar{ false }; PanelPosition panelPosition{ PanelPosition::Left }; std::string serifFont; std::string monospaceFont; diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp index be1bcf258..19d2d3b02 100644 --- a/src/tools/ecode/applayout.xml.hpp +++ b/src/tools/ecode/applayout.xml.hpp @@ -431,6 +431,18 @@ Anchor.error:hover { )html" R"html( + + + + + + + + + + + + @@ -538,4 +550,5 @@ R"html( + )html" diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index f961070c6..5095d171b 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -882,6 +882,11 @@ void App::switchStatusBar() { showStatusBar( mConfig.ui.showStatusBar ); } +void App::switchMenuBar() { + mConfig.ui.showMenuBar = !mConfig.ui.showMenuBar; + mSettings->updateMenu(); +} + void App::panelPosition( const PanelPosition& panelPosition ) { mConfig.ui.panelPosition = panelPosition; @@ -3701,6 +3706,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe mUISceneNode->bind( "doc_info", mDocInfo ); mUISceneNode->bind( "panel", mSidePanel ); mUISceneNode->bind( "project_splitter", mProjectSplitter ); + mUISceneNode->bind( "main_menubar", mMenuBar ); mUISceneNode->on( Event::KeyDown, [this]( const Event* event ) { trySendUnlockedCmd( *static_cast( event ) ); } ); @@ -3786,7 +3792,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe mStatusBar->setApp( this ); mSettings = std::make_unique(); - mSettings->createSettingsMenu( this ); + mSettings->createSettingsMenu( this, mMenuBar ); mSplitter->createEditorWithTabWidget( mBaseLayout ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index f317d5a2e..af748724e 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -273,6 +273,7 @@ class App : public UICodeEditorSplitter::Client { t.setCommand( "ui-scale-factor", [this] { setUIScaleFactor(); } ); t.setCommand( "show-side-panel", [this] { switchSidePanel(); } ); t.setCommand( "toggle-status-bar", [this] { switchStatusBar(); } ); + t.setCommand( "toggle-menu-bar", [this] { switchMenuBar(); } ); t.setCommand( "editor-font-size", [this] { setEditorFontSize(); } ); t.setCommand( "terminal-font-size", [this] { setTerminalFontSize(); } ); t.setCommand( "ui-font-size", [this] { setUIFontSize(); } ); @@ -421,6 +422,8 @@ class App : public UICodeEditorSplitter::Client { void showStatusBar( bool show ); + void switchMenuBar(); + ProjectBuildManager* getProjectBuildManager() const; UITabWidget* getSidePanel() const; @@ -520,6 +523,7 @@ class App : public UICodeEditorSplitter::Client { UISplitter* mMainSplitter{ nullptr }; StyleSheet mAppStyleSheet; UIMessageBox* mCloseMsgBox{ nullptr }; + UIMenuBar* mMenuBar{ nullptr }; void saveAllProcess(); diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index 499c7dc3b..54e9fe932 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -20,11 +20,12 @@ void SettingsMenu::runCommand( const std::string& command ) { mApp->runCommand( command ); } -void SettingsMenu::createSettingsMenu( App* app ) { +void SettingsMenu::createSettingsMenu( App* app, UIMenuBar* menuBar ) { Clock clock; mApp = app; mUISceneNode = app->getUISceneNode(); mSplitter = app->getSplitter(); + mMenuBar = menuBar; mSettingsMenu = UIPopUpMenu::New(); mSettingsMenu->setId( "settings_menu" ); @@ -72,31 +73,57 @@ void SettingsMenu::createSettingsMenu( App* app ) { ->add( i18n( "save_all", "Save All" ), findIcon( "document-save-as" ), getKeybind( "save-all" ) ) ->setId( "save-all" ); - mSettingsMenu->addSeparator(); + mSettingsMenu->addSeparator()->setId( "settings-submenues-sep" ); mProjectMenu = UIPopUpMenu::New(); - mSettingsMenu - ->addSubMenu( i18n( "folder_settings", "Folder/Project Settings" ), - findIcon( "folder-user" ), mProjectMenu ) - ->setId( "project_settings" ); + auto projectMenuButton = mSettingsMenu + ->addSubMenu( i18n( "folder_settings", "Folder/Project Settings" ), + findIcon( "folder-user" ), mProjectMenu ) + ->setId( "project_settings" ) + ->asType(); - mSettingsMenu - ->addSubMenu( i18n( "document", "Document" ), findIcon( "file" ), createDocumentMenu() ) - ->setId( "doc-menu" ); + auto docMenuButton = + mSettingsMenu + ->addSubMenu( i18n( "document", "Document" ), findIcon( "file" ), createDocumentMenu() ) + ->setId( "doc-menu" ) + ->asType(); createProjectMenu(); - mSettingsMenu - ->addSubMenu( i18n( "terminal", "Terminal" ), findIcon( "terminal" ), createTerminalMenu() ) - ->setId( "term-menu" ); - mSettingsMenu->addSubMenu( i18n( "edit", "Edit" ), nullptr, createEditMenu() ); - mSettingsMenu->addSubMenu( i18n( "view", "View" ), nullptr, createViewMenu() ); - mSettingsMenu->addSubMenu( i18n( "tools", "Tools" ), findIcon( "tools" ), createToolsMenu() ); - mSettingsMenu->addSubMenu( i18n( "window", "Window" ), findIcon( "window-opt" ), - createWindowMenu() ); + auto terminalMenuButton = mSettingsMenu + ->addSubMenu( i18n( "terminal", "Terminal" ), + findIcon( "terminal" ), createTerminalMenu() ) + ->setId( "term-menu" ) + ->asType(); + + auto editMenuButton = + mSettingsMenu->addSubMenu( i18n( "edit", "Edit" ), nullptr, createEditMenu() ) + ->setId( "edit-menu" ) + ->asType(); + + auto viewMenuButton = + mSettingsMenu->addSubMenu( i18n( "view", "View" ), nullptr, createViewMenu() ) + ->setId( "view-menu" ) + ->asType(); + + auto toolsMenuButton = + mSettingsMenu + ->addSubMenu( i18n( "tools", "Tools" ), findIcon( "tools" ), createToolsMenu() ) + ->setId( "tools-menu" ) + ->asType(); + + auto windowMenuButton = + mSettingsMenu + ->addSubMenu( i18n( "window", "Window" ), findIcon( "window-opt" ), createWindowMenu() ) + ->setId( "window-menu" ) + ->asType(); + mSettingsMenu->add( i18n( "plugin_manager", "Plugin Manager" ), findIcon( "extensions" ) ) ->setId( "plugin-manager-open" ); - mSettingsMenu->addSubMenu( i18n( "help", "Help" ), findIcon( "help" ), createHelpMenu() ); + auto helpMenuButton = + mSettingsMenu->addSubMenu( i18n( "help", "Help" ), findIcon( "help" ), createHelpMenu() ) + ->setId( "help-menu" ) + ->asType(); mSettingsMenu->addSeparator(); mSettingsMenu ->add( i18n( "close", "Close" ), findIcon( "document-close" ), getKeybind( "close-tab" ) ) @@ -118,6 +145,56 @@ void SettingsMenu::createSettingsMenu( App* app ) { } ); mApp->updateRecentFiles(); mApp->updateRecentFolders(); + + mMenuBar->setPopUpMenu( 0, mSettingsMenu ); + mMenuBar->setPopUpMenu( 1, getEditMenu() ); + mMenuBar->setPopUpMenu( 2, getViewMenu() ); + mMenuBar->setPopUpMenu( 3, getDocMenu() ); + mMenuBar->setPopUpMenu( 4, getTerminalMenu() ); + mMenuBar->setPopUpMenu( 5, getProjectMenu() ); + mMenuBar->setPopUpMenu( 6, getToolsMenu() ); + mMenuBar->setPopUpMenu( 7, getWindowMenu() ); + mMenuBar->setPopUpMenu( 8, getHelpMenu() ); + + const auto onMenuShowEvent = [this]( UIPopUpMenu* menu, UIWidget* menuButton, + Uint32 menuBarIndex ) { + menu->on( Event::OnMenuShow, [this, menuButton, menuBarIndex, menu]( auto ) { + menu->setOwnerNode( mApp->getConfig().ui.showMenuBar + ? mMenuBar->getButton( menuBarIndex )->asType() + : menuButton ); + } ); + + menu->on( Event::OnVisibleChange, [this, menuBarIndex]( const Event* event ) { + if ( mApp->getConfig().ui.showMenuBar ) { + auto button = mMenuBar->getButton( menuBarIndex ); + if ( event->getNode()->isVisible() ) { + button->select(); + mMenuBar->setCurrentMenu( event->getNode()->asType() ); + } else if ( button->isSelected() ) { + button->unselect(); + mMenuBar->setCurrentMenu( nullptr ); + } + } + } ); + + menu->on( Event::OnItemClicked, [this]( const Event* ) { + if ( mApp->getConfig().ui.showMenuBar ) + mMenuBar->setCurrentMenu( nullptr ); + } ); + }; + + onMenuShowEvent( mSettingsMenu, mSettingsButton, 0 ); + onMenuShowEvent( mEditMenu, editMenuButton, 1 ); + onMenuShowEvent( mViewMenu, viewMenuButton, 2 ); + onMenuShowEvent( mDocMenu, docMenuButton, 3 ); + onMenuShowEvent( mTerminalMenu, terminalMenuButton, 4 ); + onMenuShowEvent( mProjectMenu, projectMenuButton, 5 ); + onMenuShowEvent( mToolsMenu, toolsMenuButton, 6 ); + onMenuShowEvent( mWindowMenu, windowMenuButton, 7 ); + onMenuShowEvent( mHelpMenu, helpMenuButton, 8 ); + + updateMenu(); + Log::info( "Settings Menu took: %s", clock.getElapsedTime().toString() ); } @@ -845,72 +922,83 @@ UIMenu* SettingsMenu::createTerminalMenu() { } UIMenu* SettingsMenu::createEditMenu() { - UIPopUpMenu* menu = UIPopUpMenu::New(); - menu->add( i18n( "undo", "Undo" ), findIcon( "undo" ), getKeybind( "undo" ) )->setId( "undo" ); - menu->add( i18n( "redo", "Redo" ), findIcon( "redo" ), getKeybind( "redo" ) )->setId( "redo" ); - menu->addSeparator(); - menu->add( i18n( "cut", "Cut" ), findIcon( "cut" ), getKeybind( "cut" ) )->setId( "cut" ); - menu->add( i18n( "copy", "Copy" ), findIcon( "copy" ), getKeybind( "copy" ) )->setId( "copy" ); - menu->add( i18n( "paste", "Paste" ), findIcon( "paste" ), getKeybind( "paste" ) ) + mEditMenu = UIPopUpMenu::New(); + mEditMenu->add( i18n( "undo", "Undo" ), findIcon( "undo" ), getKeybind( "undo" ) ) + ->setId( "undo" ); + mEditMenu->add( i18n( "redo", "Redo" ), findIcon( "redo" ), getKeybind( "redo" ) ) + ->setId( "redo" ); + mEditMenu->addSeparator(); + mEditMenu->add( i18n( "cut", "Cut" ), findIcon( "cut" ), getKeybind( "cut" ) )->setId( "cut" ); + mEditMenu->add( i18n( "copy", "Copy" ), findIcon( "copy" ), getKeybind( "copy" ) ) + ->setId( "copy" ); + mEditMenu->add( i18n( "paste", "Paste" ), findIcon( "paste" ), getKeybind( "paste" ) ) ->setId( "paste" ); - menu->add( i18n( "delete", "Delete" ), findIcon( "delete-text" ), + mEditMenu + ->add( i18n( "delete", "Delete" ), findIcon( "delete-text" ), getKeybind( "delete-to-next-char" ) ) ->setId( "delete-to-next-char" ); - menu->addSeparator(); - menu->add( i18n( "select_all", "Select All" ), findIcon( "select-all" ), + mEditMenu->addSeparator(); + mEditMenu + ->add( i18n( "select_all", "Select All" ), findIcon( "select-all" ), getKeybind( "select-all" ) ) ->setId( "select-all" ); - menu->addSeparator(); - menu->add( i18n( "find_replace", "Find/Replace" ), findIcon( "find-replace" ), + mEditMenu->addSeparator(); + mEditMenu + ->add( i18n( "find_replace", "Find/Replace" ), findIcon( "find-replace" ), getKeybind( "find-replace" ) ) ->setId( "find-replace" ); - menu->addSeparator(); - menu->add( i18n( "open_containing_folder_ellipsis", "Open Containing Folder..." ), + mEditMenu->addSeparator(); + mEditMenu + ->add( i18n( "open_containing_folder_ellipsis", "Open Containing Folder..." ), findIcon( "folder-open" ), getKeybind( "open-containing-folder" ) ) ->setId( "open-containing-folder" ); - menu->add( i18n( "open_in_new_window_ellipsis", "Open in New Window..." ), findIcon( "window" ), + mEditMenu + ->add( i18n( "open_in_new_window_ellipsis", "Open in New Window..." ), findIcon( "window" ), getKeybind( "open-in-new-window" ) ) ->setId( "open-in-new-window" ); - menu->add( i18n( "copy_containing_folder_path_ellipsis", "Copy Containing Folder Path..." ), + mEditMenu + ->add( i18n( "copy_containing_folder_path_ellipsis", "Copy Containing Folder Path..." ), findIcon( "copy" ), getKeybind( "copy-containing-folder-path" ) ) ->setId( "copy-containing-folder-path" ); - menu->add( i18n( "copy_file_path", "Copy File Path" ), findIcon( "copy" ), + mEditMenu + ->add( i18n( "copy_file_path", "Copy File Path" ), findIcon( "copy" ), getKeybind( "copy-file-path" ) ) ->setId( "copy-file-path" ); - UIMenuSeparator* fileSep = menu->addSeparator(); - menu->add( i18n( "key_bindings", "Key Bindings" ), findIcon( "keybindings" ), + UIMenuSeparator* fileSep = mEditMenu->addSeparator(); + mEditMenu + ->add( i18n( "key_bindings", "Key Bindings" ), findIcon( "keybindings" ), getKeybind( "keybindings" ) ) ->setId( "keybindings" ); - menu->on( Event::OnItemClicked, [this]( const Event* event ) { + mEditMenu->on( Event::OnItemClicked, [this]( const Event* event ) { if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) ) return; runCommand( event->getNode()->getId() ); } ); - menu->on( Event::OnMenuShow, [this, menu, fileSep]( const Event* ) { + mEditMenu->on( Event::OnMenuShow, [this, fileSep]( const Event* ) { if ( !mSplitter->curEditorExistsAndFocused() ) { - menu->getItemId( "undo" )->setEnabled( false ); - menu->getItemId( "redo" )->setEnabled( false ); - menu->getItemId( "copy" )->setEnabled( false ); - menu->getItemId( "cut" )->setEnabled( false ); - menu->getItemId( "open-containing-folder" )->setVisible( false ); - menu->getItemId( "copy-containing-folder-path" )->setVisible( false ); - menu->getItemId( "open-in-new-window" )->setVisible( false ); - menu->getItemId( "copy-file-path" )->setVisible( false ); + mEditMenu->getItemId( "undo" )->setEnabled( false ); + mEditMenu->getItemId( "redo" )->setEnabled( false ); + mEditMenu->getItemId( "copy" )->setEnabled( false ); + mEditMenu->getItemId( "cut" )->setEnabled( false ); + mEditMenu->getItemId( "open-containing-folder" )->setVisible( false ); + mEditMenu->getItemId( "copy-containing-folder-path" )->setVisible( false ); + mEditMenu->getItemId( "open-in-new-window" )->setVisible( false ); + mEditMenu->getItemId( "copy-file-path" )->setVisible( false ); fileSep->setVisible( false ); return; } auto doc = mSplitter->getCurEditor()->getDocumentRef(); - menu->getItemId( "undo" )->setEnabled( doc->hasUndo() ); - menu->getItemId( "redo" )->setEnabled( doc->hasRedo() ); - menu->getItemId( "copy" )->setEnabled( doc->hasSelection() ); - menu->getItemId( "cut" )->setEnabled( doc->hasSelection() ); - menu->getItemId( "open-containing-folder" )->setVisible( doc->hasFilepath() ); - menu->getItemId( "copy-containing-folder-path" )->setVisible( doc->hasFilepath() ); - menu->getItemId( "open-in-new-window" )->setVisible( doc->hasFilepath() ); - menu->getItemId( "copy-file-path" )->setVisible( doc->hasFilepath() ); + mEditMenu->getItemId( "undo" )->setEnabled( doc->hasUndo() ); + mEditMenu->getItemId( "redo" )->setEnabled( doc->hasRedo() ); + mEditMenu->getItemId( "copy" )->setEnabled( doc->hasSelection() ); + mEditMenu->getItemId( "cut" )->setEnabled( doc->hasSelection() ); + mEditMenu->getItemId( "open-containing-folder" )->setVisible( doc->hasFilepath() ); + mEditMenu->getItemId( "copy-containing-folder-path" )->setVisible( doc->hasFilepath() ); + mEditMenu->getItemId( "open-in-new-window" )->setVisible( doc->hasFilepath() ); + mEditMenu->getItemId( "copy-file-path" )->setVisible( doc->hasFilepath() ); fileSep->setVisible( doc->hasFilepath() ); } ); - return menu; + return mEditMenu; } UIMenu* SettingsMenu::createWindowMenu() { @@ -1224,6 +1312,10 @@ UIMenu* SettingsMenu::createViewMenu() { ->addCheckBox( i18n( "show_status_bar", "Show Status Bar" ), mApp->getConfig().ui.showStatusBar, getKeybind( "toggle-status-bar" ) ) ->setId( "toggle-status-bar" ); + mViewMenu + ->addCheckBox( i18n( "show_menu_bar", "Show Menu Bar" ), mApp->getConfig().ui.showMenuBar, + getKeybind( "toggle-menu-bar" ) ) + ->setId( "toggle-menu-bar" ); mViewMenu ->add( i18n( "move_panel_left_ellipsis", "Move panel to left..." ), findIcon( "layout-left" ), getKeybind( "layout-left" ) ) @@ -1346,6 +1438,12 @@ UIMenu* SettingsMenu::createViewMenu() { UIPopUpMenu* SettingsMenu::createToolsMenu() { mToolsMenu = UIPopUpMenu::New(); + + mToolsMenu->add( i18n( "plugin_manager", "Plugin Manager" ), findIcon( "extensions" ) ) + ->setId( "plugin-manager-open" ); + + mToolsMenu->addSeparator(); + mToolsMenu ->add( i18n( "locate_ellipsis", "Locate..." ), findIcon( "search" ), getKeybind( "open-locatebar" ) ) @@ -1409,17 +1507,17 @@ UIPopUpMenu* SettingsMenu::createToolsMenu() { } UIMenu* SettingsMenu::createHelpMenu() { - UIPopUpMenu* helpMenu = UIPopUpMenu::New(); - helpMenu->add( i18n( "ecode_source_ellipsis", "ecode source code..." ), findIcon( "github" ) ) + mHelpMenu = UIPopUpMenu::New(); + mHelpMenu->add( i18n( "ecode_source_ellipsis", "ecode source code..." ), findIcon( "github" ) ) ->setId( "ecode-source" ); - helpMenu + mHelpMenu ->add( i18n( "check_for_updates_ellipsis", "Check for Updates..." ), findIcon( "refresh" ) ) ->setId( "check-for-updates" ); - helpMenu->add( i18n( "about_ecode", "About ecode..." ), findIcon( "ecode" ) ) + mHelpMenu->add( i18n( "about_ecode", "About ecode..." ), findIcon( "ecode" ) ) ->setId( "about-ecode" ); - helpMenu->on( Event::OnItemClicked, - [this]( const Event* event ) { runCommand( event->getNode()->getId() ); } ); - return helpMenu; + mHelpMenu->on( Event::OnItemClicked, + [this]( const Event* event ) { runCommand( event->getNode()->getId() ); } ); + return mHelpMenu; } UIMenu* SettingsMenu::createThemesMenu() { @@ -1982,6 +2080,30 @@ UIPopUpMenu* SettingsMenu::getSettingsMenu() const { return mSettingsMenu; } +UIPopUpMenu* SettingsMenu::getToolsMenu() const { + return mToolsMenu; +} + +UIPopUpMenu* SettingsMenu::getProjectMenu() const { + return mProjectMenu; +} + +UIPopUpMenu* SettingsMenu::getTerminalMenu() const { + return mTerminalMenu; +} + +UIPopUpMenu* SettingsMenu::getDocMenu() const { + return mDocMenu; +} + +UIPopUpMenu* SettingsMenu::getEditMenu() const { + return mEditMenu; +} + +UIPopUpMenu* SettingsMenu::getHelpMenu() const { + return mHelpMenu; +} + void SettingsMenu::deleteFileDialog( const FileInfo& file ) { UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::OK_CANCEL, @@ -2050,4 +2172,38 @@ void SettingsMenu::createProjectMenu() { } ); } +void SettingsMenu::updateMenu() { + bool showMenuBar = mApp->getConfig().ui.showMenuBar; + mSettingsButton->setVisible( !showMenuBar ); + mMenuBar->setVisible( showMenuBar ); + + const auto setMenuParent = [this]( UIPopUpMenu* menu ) { + menu->setParent( mApp->getConfig().ui.showMenuBar ? mMenuBar->asType() + : mSettingsMenu->asType() ); + }; + + mSettingsMenu->setParent( showMenuBar ? mMenuBar->asType() + : mApp->getUISceneNode()->asType() ); + + setMenuParent( mEditMenu ); + setMenuParent( mViewMenu ); + setMenuParent( mDocMenu ); + setMenuParent( mTerminalMenu ); + setMenuParent( mProjectMenu ); + setMenuParent( mToolsMenu ); + setMenuParent( mWindowMenu ); + setMenuParent( mHelpMenu ); + + mSettingsMenu->find( "settings-submenues-sep" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "project_settings" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "doc-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "term-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "edit-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "view-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "tools-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "window-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "help-menu" )->setVisible( !showMenuBar ); + mSettingsMenu->getItemId( "plugin-manager-open" )->setVisible( !showMenuBar ); +} + } // namespace ecode diff --git a/src/tools/ecode/settingsmenu.hpp b/src/tools/ecode/settingsmenu.hpp index 29f063a29..5a495c381 100644 --- a/src/tools/ecode/settingsmenu.hpp +++ b/src/tools/ecode/settingsmenu.hpp @@ -8,7 +8,7 @@ namespace ecode { class SettingsMenu { public: - void createSettingsMenu( App* app ); + void createSettingsMenu( App* app, UIMenuBar* menuBar ); String i18n( const std::string& key, const String& def ); @@ -72,12 +72,26 @@ class SettingsMenu { UIPopUpMenu* getSettingsMenu() const; + UIPopUpMenu* getToolsMenu() const; + + UIPopUpMenu* getProjectMenu() const; + + UIPopUpMenu* getTerminalMenu() const; + + UIPopUpMenu* getDocMenu() const; + + UIPopUpMenu* getEditMenu() const; + + UIPopUpMenu* getHelpMenu() const; + void updateRecentFolders(); void deleteFileDialog( const FileInfo& file ); void createProjectMenu(); + void updateMenu(); + protected: App* mApp{ nullptr }; UIPopUpMenu* mSettingsMenu{ nullptr }; @@ -95,6 +109,9 @@ class SettingsMenu { UIPopUpMenu* mProjectTreeMenu{ nullptr }; UIPopUpMenu* mProjectDocMenu{ nullptr }; UIPopUpMenu* mProjectMenu{ nullptr }; + UIPopUpMenu* mEditMenu{ nullptr }; + UIPopUpMenu* mHelpMenu{ nullptr }; + UIMenuBar* mMenuBar{ nullptr }; std::vector mFileTypeMenues; Float mFileTypeMenuesCreatedWithHeight{ 0 }; std::vector mColorSchemeMenues;