From cf84fc7cfffac44b860c4ddb5dfdc5a45084ff22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 1 Jan 2025 16:18:26 -0300 Subject: [PATCH] Save side panel tabs order. --- include/eepp/ui/uitabwidget.hpp | 2 + src/eepp/ui/uitabwidget.cpp | 11 +++++ src/tools/ecode/appconfig.cpp | 4 ++ src/tools/ecode/appconfig.hpp | 1 + src/tools/ecode/ecode.cpp | 36 ++++++++++++++- src/tools/ecode/ecode.hpp | 4 ++ .../debugger/dap/debuggerclientdap.cpp | 4 ++ .../debugger/dap/debuggerclientdap.hpp | 2 + .../ecode/plugins/debugger/debuggerclient.hpp | 2 + .../debugger/debuggerclientlistener.cpp | 2 +- .../ecode/plugins/debugger/debuggerplugin.cpp | 45 ++++++++++++------- src/tools/ecode/plugins/git/gitplugin.cpp | 37 +++++++++++---- src/tools/ecode/plugins/git/gitplugin.hpp | 2 +- src/tools/ecode/projectbuild.cpp | 7 --- src/tools/ecode/statusappoutputcontroller.cpp | 11 +++-- src/tools/ecode/statusappoutputcontroller.hpp | 2 +- 16 files changed, 131 insertions(+), 41 deletions(-) diff --git a/include/eepp/ui/uitabwidget.hpp b/include/eepp/ui/uitabwidget.hpp index 1ea53f879..bde8aefe5 100644 --- a/include/eepp/ui/uitabwidget.hpp +++ b/include/eepp/ui/uitabwidget.hpp @@ -68,6 +68,8 @@ class EE_API UITabWidget : public UIWidget { UITab* getTab( const String& text ); + UITab* getTabById( const std::string& text ); + Uint32 getTabIndex( UITab* tab ); Uint32 getTabCount() const; diff --git a/src/eepp/ui/uitabwidget.cpp b/src/eepp/ui/uitabwidget.cpp index 88f316e25..f8f513bf8 100644 --- a/src/eepp/ui/uitabwidget.cpp +++ b/src/eepp/ui/uitabwidget.cpp @@ -565,6 +565,17 @@ UITab* UITabWidget::getTab( const String& text ) { return NULL; } +UITab* UITabWidget::getTabById( const std::string& text ) { + for ( Uint32 i = 0; i < mTabs.size(); i++ ) { + if ( mTabs[i]->isType( UI_TYPE_TAB ) ) { + UITab* tTab = mTabs[i]->asType(); + if ( tTab->getId() == text ) + return tTab; + } + } + return nullptr; +} + Uint32 UITabWidget::getTabIndex( UITab* tab ) { for ( Uint32 i = 0; i < mTabs.size(); i++ ) { if ( mTabs[i] == tab ) diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index 311d246c0..ef4131616 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -102,6 +102,8 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, windowState.position.x = iniState.getValueI( "window", "x", -1 ); windowState.position.y = iniState.getValueI( "window", "y", -1 ); windowState.lastRunVersion = iniState.getValueU( "editor", "last_run_version", 0 ); + windowState.sidePanelTabsOrder = + String::split( iniState.getValue( "ui", "side_panel_tabs_order", "" ), ',' ); editor.showLineNumbers = ini.getValueB( "editor", "show_line_numbers", true ); editor.showWhiteSpaces = ini.getValueB( "editor", "show_white_spaces", true ); editor.showLineEndings = ini.getValueB( "editor", "show_line_endings", false ); @@ -262,6 +264,8 @@ void AppConfig::save( const std::vector& recentFiles, iniState.setValue( "folders", "recentfolders", String::join( urlEncode( recentFolders ), ';' ) ); iniState.setValueU( "editor", "last_run_version", ecode::Version::getVersionNum() ); + iniState.setValue( "ui", "side_panel_tabs_order", + String::join( windowState.sidePanelTabsOrder, ',' ) ); ini.setValueB( "editor", "show_line_numbers", editor.showLineNumbers ); ini.setValueB( "editor", "show_white_spaces", editor.showWhiteSpaces ); ini.setValueB( "editor", "show_indentation_guides", editor.showIndentationGuides ); diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index 704e29ad5..f0ed17dd6 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -54,6 +54,7 @@ struct WindowStateConfig { int displayIndex{ 0 }; Vector2i position{ -1, -1 }; Uint32 lastRunVersion{ 0 }; + std::vector sidePanelTabsOrder; }; struct CodeEditorConfig { diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 4bcdf29dd..4efb83fe1 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -699,6 +699,9 @@ bool App::loadConfig( const LogLevel& logLevel, const Sizeu& displaySize, bool s } void App::saveConfig() { + if ( !mCurrentProject.empty() ) + saveSidePanelTabsOrder(); + mConfig.save( mRecentFiles, mRecentFolders, mProjectSplitter ? mProjectSplitter->getSplitPartition().toString() : "15%", mMainSplitter ? mMainSplitter->getSplitPartition().toString() : "85%", mWindow, @@ -1927,6 +1930,8 @@ void App::closeFolder() { if ( mCurrentProject.empty() ) return; + saveSidePanelTabsOrder(); + saveProject( true ); if ( mProjectBuildManager ) @@ -3119,6 +3124,13 @@ void App::cleanUpRecentFolders() { mRecentFolders = recentFolders; } +void App::saveSidePanelTabsOrder() { + mConfig.windowState.sidePanelTabsOrder.clear(); + mConfig.windowState.sidePanelTabsOrder.reserve( mSidePanel->getTabCount() ); + for ( Uint32 i = 0; i < mSidePanel->getTabCount(); i++ ) + mConfig.windowState.sidePanelTabsOrder.emplace_back( mSidePanel->getTab( i )->getId() ); +} + void App::loadFolder( std::string path ) { Clock dirTreeClock; @@ -3133,7 +3145,10 @@ void App::loadFolder( std::string path ) { return; } - if ( !mCurrentProject.empty() ) { + bool projectWasLoaded = !mCurrentProject.empty(); + if ( projectWasLoaded ) { + saveSidePanelTabsOrder(); + closeEditors(); } else { mSplitter->removeTabWithOwnedWidgetId( "welcome_ecode" ); @@ -3195,6 +3210,25 @@ void App::loadFolder( std::string path ) { mPluginManager->setWorkspaceFolder( rpath ); saveProject( true, false ); + + if ( projectWasLoaded || !mConfig.windowState.sidePanelTabsOrder.empty() ) + mSidePanel->runOnMainThread( [this] { sortSidePanel(); } ); +} + +void App::sortSidePanel() { + mConfig.windowState.sidePanelTabsOrder.erase( + std::remove_if( + mConfig.windowState.sidePanelTabsOrder.begin(), + mConfig.windowState.sidePanelTabsOrder.end(), + [this]( const std::string& id ) { return mSidePanel->getTabById( id ) == nullptr; } ), + mConfig.windowState.sidePanelTabsOrder.end() ); + + for ( size_t i = 0; i < mConfig.windowState.sidePanelTabsOrder.size(); ++i ) { + UITab* targetTab = mSidePanel->getTabById( mConfig.windowState.sidePanelTabsOrder[i] ); + UITab* currentTab = mSidePanel->getTab( i ); + if ( targetTab && currentTab != targetTab ) + mSidePanel->swapTabs( currentTab, targetTab ); + } } #if EE_PLATFORM == EE_PLATFORM_MACOS diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 6d78dbf68..4afe8e8c8 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -566,6 +566,10 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { std::vector mColorSchemes; bool mAsyncResourcesLoaded{ false }; + void sortSidePanel(); + + void saveSidePanelTabsOrder(); + void saveAllProcess(); void initLocateBar(); diff --git a/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.cpp b/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.cpp index 71fdeecba..72ea49475 100644 --- a/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.cpp +++ b/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.cpp @@ -721,4 +721,8 @@ bool DebuggerClientDap::configurationDone() { return true; } +bool DebuggerClientDap::started() const { + return mStarted; +} + } // namespace ecode::dap diff --git a/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.hpp b/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.hpp index ca9bd2735..76a2ac59b 100644 --- a/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.hpp +++ b/src/tools/ecode/plugins/debugger/dap/debuggerclientdap.hpp @@ -74,6 +74,8 @@ class DebuggerClientDap : public DebuggerClient { bool configurationDone() override; + bool started() const override; + protected: std::unique_ptr mBus; UnorderedMap> mBreakpoints; diff --git a/src/tools/ecode/plugins/debugger/debuggerclient.hpp b/src/tools/ecode/plugins/debugger/debuggerclient.hpp index 90482d624..3c5d69e88 100644 --- a/src/tools/ecode/plugins/debugger/debuggerclient.hpp +++ b/src/tools/ecode/plugins/debugger/debuggerclient.hpp @@ -52,6 +52,8 @@ class DebuggerClient { virtual bool start() = 0; + virtual bool started() const = 0; + virtual bool resume( int threadId, bool singleThread = false ) = 0; virtual bool pause( int threadId ) = 0; diff --git a/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp b/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp index 70fffa4c2..804620607 100644 --- a/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp @@ -15,7 +15,7 @@ void DebuggerClientListener::stateChanged( DebuggerClient::State state ) { mPlugin->getManager() ->getPluginContext() ->getStatusAppOutputController() - ->initNewOutput( {} ); + ->initNewOutput( {}, false ); } ); } } diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp index c08f8f0c3..9c884689f 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp @@ -1,8 +1,8 @@ +#include "debuggerplugin.hpp" #include "../../projectbuild.hpp" #include "../../uistatusbar.hpp" #include "busprocess.hpp" #include "dap/debuggerclientdap.hpp" -#include "debuggerplugin.hpp" #include "statusdebuggercontroller.hpp" #include #include @@ -227,7 +227,7 @@ void DebuggerPlugin::buildSidePanelTab() { UIIcon* icon = findIcon( "debug" ); mTab = mSidePanel->add( i18n( "debugger", "Debugger" ), mTabContents, icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr ); - mTab->setId( "debugger" ); + mTab->setId( "debugger_tab" ); mTab->setTextAsFallback( true ); updateSidePanelTab(); @@ -245,7 +245,7 @@ void DebuggerPlugin::buildSidePanelTab() { - + )html"; @@ -307,12 +307,16 @@ void DebuggerPlugin::updateSidePanelTab() { updateDebuggerConfigurationList(); - mRunButton = mTabContents->find( "run_button" ); + mRunButton = mTabContents->find( "debugger_run_button" ); if ( !mRunButton->hasEventsOfType( Event::MouseClick ) ) { mRunButton->onClick( [this]( auto ) { - runConfig( mUIDebuggerList->getListBox()->getItemSelectedText().toUtf8(), - mUIDebuggerConfList->getListBox()->getItemSelectedText().toUtf8() ); + if ( mDebugger && mDebugger->started() ) { + exitDebugger(); + } else { + runConfig( mUIDebuggerList->getListBox()->getItemSelectedText().toUtf8(), + mUIDebuggerConfList->getListBox()->getItemSelectedText().toUtf8() ); + } } ); } } @@ -358,9 +362,9 @@ void DebuggerPlugin::replaceKeysInJson( nlohmann::json& json ) { replaceKeysInJson( j ); } else if ( j.is_string() ) { std::string val( j.get() ); - if ( runConfig && !runConfig->cmd.empty() && val == KEY_FILE ) { + if ( runConfig && val == KEY_FILE ) { j = runConfig->cmd; - } else if ( runConfig && !runConfig->args.empty() && val == KEY_ARGS ) { + } else if ( runConfig && val == KEY_ARGS ) { auto argsArr = nlohmann::json::array(); auto args = Process::parseArgs( runConfig->args ); for ( const auto& arg : args ) @@ -412,13 +416,17 @@ void DebuggerPlugin::runConfig( const std::string& debugger, const std::string& mRunButton->setEnabled( false ); - mThreadPool->run( - [this] { mDebugger->start(); }, - [this]( const Uint64& ) { - if ( !mDebugger || mDebugger->state() != DebuggerClient::State::Running ) { - mRunButton->runOnMainThread( [this] { mRunButton->setEnabled( false ); } ); - } - } ); + mThreadPool->run( [this] { mDebugger->start(); }, + [this]( const Uint64& ) { + if ( !mDebugger || !mDebugger->started() ) { + exitDebugger(); + } else { + mRunButton->runOnMainThread( [this] { + mRunButton->setEnabled( true ); + mRunButton->setText( i18n( "cancel_run", "Cancel Run" ) ); + } ); + } + } ); } void DebuggerPlugin::exitDebugger() { @@ -428,8 +436,11 @@ void DebuggerPlugin::exitDebugger() { mDebugger.reset(); mListener.reset(); } ); - if ( getUISceneNode() ) { - getUISceneNode()->runOnMainThread( [this] { mRunButton->setEnabled( true ); } ); + if ( getUISceneNode() && mRunButton ) { + mRunButton->runOnMainThread( [this] { + mRunButton->setText( i18n( "run", "Run" ) ); + mRunButton->setEnabled( true ); + } ); } } diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index 5a9f9b7c8..9729d5397 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -96,10 +96,18 @@ GitPlugin::~GitPlugin() { if ( getUISceneNode() ) getUISceneNode()->removeActionsByTag( GIT_STATUS_UPDATE_TAG ); - { Lock l( mGitBranchMutex ); } - { Lock l( mGitStatusMutex ); } - { Lock l( mRepoMutex ); } - { Lock l( mReposMutex ); } + { + Lock l( mGitBranchMutex ); + } + { + Lock l( mGitStatusMutex ); + } + { + Lock l( mRepoMutex ); + } + { + Lock l( mReposMutex ); + } // TODO: Add a signal for these waits while ( mRunningUpdateStatus ) @@ -293,6 +301,9 @@ void GitPlugin::updateUINow( bool force ) { if ( !mGit || !getUISceneNode() ) return; + if ( !mProjectPath.empty() ) + getUISceneNode()->runOnMainThread( [this] { buildSidePanelTab(); } ); + updateStatus( force ); updateBranches(); } @@ -339,9 +350,6 @@ void GitPlugin::updateStatusBarSync() { mStatusButton->setIcon( iconDrawable( "source-control", 10 ) ); mStatusButton->reloadStyle( true, true ); mStatusButton->getTextBox()->setUsingCustomStyling( true ); - auto childCount = mStatusBar->getChildCount(); - if ( childCount > 2 ) - mStatusButton->toPosition( mStatusBar->getChildCount() - 2 ); mStatusButton->on( Event::MouseClick, [this]( const Event* event ) { if ( nullptr == mTab ) @@ -398,6 +406,12 @@ void GitPlugin::updateStatusBarSync() { void GitPlugin::updateStatus( bool force ) { if ( !mGit || !mGitFound || mRunningUpdateStatus ) return; + + if ( !mGit || mGit->getGitFolder().empty() ) { + getUISceneNode()->runOnMainThread( [this] { updateStatusBarSync(); } ); + return; + } + mRunningUpdateStatus++; mThreadPool->run( [this, force] { @@ -1311,6 +1325,11 @@ void GitPlugin::updateBranches( bool force ) { if ( !mGit || !mGitFound || ( mRunningUpdateBranches && !force ) ) return; + if ( !mGit || mGit->getGitFolder().empty() ) { + getUISceneNode()->runOnMainThread( [this] { updateBranchesUI( nullptr ); } ); + return; + } + mRunningUpdateBranches++; mThreadPool->run( [this] { @@ -1401,7 +1420,7 @@ void GitPlugin::buildSidePanelTab() { UIIcon* icon = findIcon( "source-control" ); mTab = mSidePanel->add( i18n( "source_control", "Source Control" ), mTabContents, icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr ); - mTab->setId( "source_control" ); + mTab->setId( "source_control_tab" ); mTab->setTextAsFallback( true ); return; } @@ -1471,7 +1490,7 @@ void GitPlugin::buildSidePanelTab() { mTabContents = getUISceneNode()->loadLayoutFromString( String::format( STYLE, color, color ) ); mTab = mSidePanel->add( i18n( "source_control", "Source Control" ), mTabContents, icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr ); - mTab->setId( "source_control" ); + mTab->setId( "source_control_tab" ); mTab->setTextAsFallback( true ); mTabContents->bind( "git_panel_switcher", mPanelSwicher ); diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp index bc8208f88..6ff77e4d5 100644 --- a/src/tools/ecode/plugins/git/gitplugin.hpp +++ b/src/tools/ecode/plugins/git/gitplugin.hpp @@ -37,7 +37,7 @@ static constexpr const char* GIT_STASH_TOOLTIP_CLASS = "git-stash-tooltip"; class GitPlugin : public PluginBase { public: static PluginDefinition Definition() { - return { "git", "Git", "Git integration", GitPlugin::New, { 0, 1, 1 }, GitPlugin::NewSync }; + return { "git", "Git", "Git integration", GitPlugin::New, { 0, 1, 2 }, GitPlugin::NewSync }; } static Plugin* New( PluginManager* pluginManager ); diff --git a/src/tools/ecode/projectbuild.cpp b/src/tools/ecode/projectbuild.cpp index b70141876..7f2d217b9 100644 --- a/src/tools/ecode/projectbuild.cpp +++ b/src/tools/ecode/projectbuild.cpp @@ -1134,13 +1134,6 @@ void ProjectBuildManager::buildSidePanelTab() { mTab->setId( "build_tab" ); mTab->setTextAsFallback( true ); - auto tabIndex = mSidePanel->getTabIndex( mTab ); - if ( tabIndex > 0 ) { - auto prevTab = mSidePanel->getTab( tabIndex - 1 ); - if ( prevTab && prevTab->getId() != "treeview_tab" ) - mSidePanel->swapTabs( mTab, prevTab ); - } - updateSidePanelTab(); } diff --git a/src/tools/ecode/statusappoutputcontroller.cpp b/src/tools/ecode/statusappoutputcontroller.cpp index bd0ca50be..fe6b43976 100644 --- a/src/tools/ecode/statusappoutputcontroller.cpp +++ b/src/tools/ecode/statusappoutputcontroller.cpp @@ -31,7 +31,8 @@ UIPushButton* StatusAppOutputController::getRunButton() { return nullptr; } -void StatusAppOutputController::initNewOutput( const ProjectBuildOutputParser& outputParser ) { +void StatusAppOutputController::initNewOutput( const ProjectBuildOutputParser& outputParser, + bool fromBuildPanel ) { show(); mAppOutput->getDocument().reset(); mAppOutput->invalidateLongestLineWidth(); @@ -66,10 +67,12 @@ void StatusAppOutputController::initNewOutput( const ProjectBuildOutputParser& o mAppOutput->setLineWrapMode( LineWrapMode::Word ); mScrollLocked = true; - UIPushButton* runButton = getRunButton(); + if ( fromBuildPanel ) { + UIPushButton* runButton = getRunButton(); - if ( runButton ) - runButton->setText( mContext->i18n( "cancel_run", "Cancel Run" ) ); + if ( runButton ) + runButton->setText( mContext->i18n( "cancel_run", "Cancel Run" ) ); + } mRunButton->setEnabled( false ); mStopButton->setEnabled( true ); diff --git a/src/tools/ecode/statusappoutputcontroller.hpp b/src/tools/ecode/statusappoutputcontroller.hpp index 1ee5b636e..ab3586bed 100644 --- a/src/tools/ecode/statusappoutputcontroller.hpp +++ b/src/tools/ecode/statusappoutputcontroller.hpp @@ -25,7 +25,7 @@ class StatusAppOutputController : public StatusBarElement { virtual ~StatusAppOutputController() {}; - void initNewOutput( const ProjectBuildOutputParser& outputParser ); + void initNewOutput( const ProjectBuildOutputParser& outputParser, bool fromBuildPanel = true ); void run( const ProjectBuildCommand& runData, const ProjectBuildOutputParser& outputParser );