diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp index 94b31c1f0..c9d5fad2d 100644 --- a/src/eepp/ui/abstract/uiabstracttableview.cpp +++ b/src/eepp/ui/abstract/uiabstracttableview.cpp @@ -109,6 +109,7 @@ void UIAbstractTableView::createOrUpdateColumns( bool resetColumnData ) { size_t count = model->columnCount(); Float totalWidth = 0; auto visibleColCount = visibleColumnCount(); + bool requiresUpdateCellVisibility = false; if ( resetColumnData ) this->resetColumnData(); @@ -121,7 +122,10 @@ void UIAbstractTableView::createOrUpdateColumns( bool resetColumnData ) { col.widget->setEnabled( true ); col.widget->setVisible( true ); } + bool wasVisible = col.visible; col.visible = !isColumnHidden( i ); + if ( wasVisible != col.visible ) + requiresUpdateCellVisibility = true; col.widget->setVisible( col.visible ); if ( !col.visible ) continue; @@ -196,6 +200,7 @@ void UIAbstractTableView::createOrUpdateColumns( bool resetColumnData ) { ColumnData& col = columnData( i ); col.width = 0; col.visible = false; + requiresUpdateCellVisibility = true; if ( col.widget ) { col.widget->close(); col.widget = nullptr; @@ -209,6 +214,9 @@ void UIAbstractTableView::createOrUpdateColumns( bool resetColumnData ) { mHeader->updateLayout(); mHeader->setVisible( visible ); + if ( requiresUpdateCellVisibility ) + updateCellsVisibility(); + updateColumnsWidth(); } diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp index d320583cd..43a3d7279 100644 --- a/src/tools/ecode/applayout.xml.hpp +++ b/src/tools/ecode/applayout.xml.hpp @@ -384,7 +384,7 @@ Anchor.error:hover { - + diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index a66a2e9e3..3758e2756 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1886,7 +1886,9 @@ std::vector App::getUnlockedCommands() { "tree-view-configure-ignore-files", "show-open-documents", "open-workspace-symbol-search", - "open-document-symbol-search" }; + "open-document-symbol-search", + "show-folder-treeview-tab", + "show-build-tab" }; } bool App::isUnlockedCommand( const std::string& command ) { @@ -2472,6 +2474,18 @@ void App::createNewTerminal() { } } +void App::showFolderTreeViewTab() { + UITab* tab = mSidePanel->find( "treeview_tab" ); + if ( tab ) + tab->setTabSelected(); +} + +void App::showBuildTab() { + UITab* tab = mSidePanel->find( "build_tab" ); + if ( tab ) + tab->setTabSelected(); +} + std::string App::getNewFilePath( const FileInfo& file, UIMessageBox* msgBox, bool keepDir ) { auto fileName( msgBox->getTextInput()->getText().toUtf8() ); auto folderPath( file.getDirectoryPath() ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 4643875c3..1d61a83e5 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -183,6 +183,10 @@ class App : public UICodeEditorSplitter::Client { UIStatusBar* getStatusBar() const { return mStatusBar; } + void showFolderTreeViewTab(); + + void showBuildTab(); + template void registerUnlockedCommands( T& t ) { t.setCommand( "keybindings", [this] { loadFileFromPath( mKeybindingsPath ); } ); t.setCommand( "debug-draw-boxes-toggle", [this] { debugDrawBoxesToggle(); } ); @@ -251,6 +255,8 @@ class App : public UICodeEditorSplitter::Client { mProjectBuildManager->cancelBuild(); } } ); + t.setCommand( "show-folder-treeview-tab", [this] { showFolderTreeViewTab(); } ); + t.setCommand( "show-build-tab", [this] { showBuildTab(); } ); t.setCommand( "open-workspace-symbol-search", [this] { mUniversalLocator->showWorkspaceSymbol(); } ); t.setCommand( "open-document-symbol-search", diff --git a/src/tools/ecode/projectbuild.cpp b/src/tools/ecode/projectbuild.cpp index bf367e720..8ccf5f51f 100644 --- a/src/tools/ecode/projectbuild.cpp +++ b/src/tools/ecode/projectbuild.cpp @@ -624,6 +624,13 @@ ProjectBuildOutputParser ProjectBuildManager::getOutputParser( const std::string return {}; } +ProjectBuild* ProjectBuildManager::getBuild( const std::string& buildName ) { + auto buildIt = mBuilds.find( buildName ); + if ( buildIt != mBuilds.end() ) + return &buildIt->second; + return nullptr; +} + bool ProjectBuildManager::hasBuildCommands( const std::string& name ) { auto buildIt = mBuilds.find( name ); if ( buildIt != mBuilds.end() ) @@ -651,7 +658,25 @@ ProjectBuildConfiguration ProjectBuildManager::getConfig() const { } void ProjectBuildManager::setConfig( const ProjectBuildConfiguration& config ) { - mConfig = config; + bool buildNameChanged = false; + bool buildTypeChanged = false; + + if ( mConfig.buildName != config.buildName ) { + mConfig.buildName = config.buildName; + buildNameChanged = true; + updateSidePanelTab(); + } + + if ( mConfig.buildType != config.buildType ) { + mConfig.buildType = config.buildType; + buildTypeChanged = true; + updateBuildType(); + } + + if ( buildNameChanged ) + updateSidePanelTab(); + else if ( buildTypeChanged ) + updateBuildType(); } void ProjectBuildManager::buildCurrentConfig( StatusBuildOutputController* sboc ) { @@ -852,13 +877,18 @@ void ProjectBuildManager::buildSidePanelTab() { )html" ); mTab = mSidePanel->add( mUISceneNode->getTranslatorStringFromKey( "build", "Build" ), node, icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr ); + mTab->setId( "build_tab" ); mTab->setTextAsFallback( true ); updateSidePanelTab(); } void ProjectBuildManager::updateSidePanelTab() { + if ( mTab == nullptr ) + return; UIWidget* buildTab = mTab->getOwnedWidget()->find( "build_tab" ); + if ( buildTab == nullptr ) + return; UIDropDownList* buildList = buildTab->find( "build_list" ); UIPushButton* buildButton = buildTab->find( "build_button" ); UIPushButton* cleanButton = buildTab->find( "clean_button" ); @@ -938,7 +968,11 @@ void ProjectBuildManager::updateSidePanelTab() { } void ProjectBuildManager::updateBuildType() { + if ( mTab == nullptr ) + return; UIWidget* buildTab = mTab->getOwnedWidget()->find( "build_tab" ); + if ( buildTab == nullptr ) + return; UIDropDownList* buildList = buildTab->find( "build_list" ); UIDropDownList* buildTypeList = buildTab->find( "build_type_list" ); diff --git a/src/tools/ecode/projectbuild.hpp b/src/tools/ecode/projectbuild.hpp index f1203f316..566767a75 100644 --- a/src/tools/ecode/projectbuild.hpp +++ b/src/tools/ecode/projectbuild.hpp @@ -205,8 +205,7 @@ class ProjectBuild { struct ProjectBuildCommand : public ProjectBuildStep { ProjectBuildConfig config; - ProjectBuildCommand( const ProjectBuildStep& step ) : - ProjectBuildStep( step ) {} + ProjectBuildCommand( const ProjectBuildStep& step ) : ProjectBuildStep( step ) {} }; using ProjectBuildCommands = std::vector; @@ -264,6 +263,8 @@ class ProjectBuildManager { const std::string& getProjectFile() const { return mProjectFile; } + ProjectBuild* getBuild( const std::string& buildName ); + bool hasBuild( const std::string& name ) { return mBuilds.find( name ) != mBuilds.end(); } bool hasBuildCommands( const std::string& name ); diff --git a/src/tools/ecode/universallocator.cpp b/src/tools/ecode/universallocator.cpp index a3e4d3b03..e5dcecde9 100644 --- a/src/tools/ecode/universallocator.cpp +++ b/src/tools/ecode/universallocator.cpp @@ -156,6 +156,7 @@ void UniversalLocator::updateFilesTable() { mLocateTable->setModel( res ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); mLocateTable->scrollToTop(); + updateLocateBarSync(); } ); } ); #else @@ -202,11 +203,8 @@ void UniversalLocator::updateCommandPaletteTable() { #endif } else if ( mCommandPalette.getCurModel() ) { mLocateTable->setModel( mCommandPalette.getCurModel() ); - mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); } - - mLocateTable->setColumnsVisible( { 0, 1 } ); } void UniversalLocator::showLocateTable() { @@ -214,6 +212,7 @@ void UniversalLocator::showLocateTable() { Vector2f pos( mLocateInput->convertToWorldSpace( { 0, 0 } ) ); pos.y -= mLocateTable->getPixelsSize().getHeight(); mLocateTable->setPixelsPosition( pos ); + updateFilesTable(); } void UniversalLocator::goToLine() { @@ -222,8 +221,9 @@ void UniversalLocator::goToLine() { } static bool isCommand( const std::string& filename ) { - return !filename.empty() && ( filename == "> " || filename == ": " || filename == "l " || - filename == ". " || filename == "o " ); + return !filename.empty() && + ( filename == "> " || filename == ": " || filename == "l " || filename == ". " || + filename == "o " || filename == "sb " || filename == "sbt " ); } void UniversalLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInput ) { @@ -271,10 +271,14 @@ void UniversalLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locat showOpenDocuments(); } else if ( String::startsWith( inputTxt, ". " ) ) { showDocumentSymbol(); + } else if ( String::startsWith( inputTxt, "sb " ) ) { + showSwitchBuild(); + } else if ( String::startsWith( inputTxt, "sbt " ) ) { + showSwitchBuildType(); } else { showLocateTable(); - updateFilesTable(); } + updateLocateBarSync(); } ); mLocateInput->addEventListener( Event::OnPressEnter, [this]( const Event* ) { KeyEvent keyEvent( mLocateTable, Event::KeyDown, KEY_RETURN, SCANCODE_UNKNOWN, 0, 0 ); @@ -329,6 +333,32 @@ void UniversalLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locat mLocateInput->setText( vName.toString() ); return; } + + if ( String::startsWith( mLocateInput->getText(), "sb " ) ) { + auto pbm = mApp->getProjectBuildManager(); + auto cfg = pbm->getConfig(); + std::string buildName = vName.toString(); + if ( pbm->hasBuild( buildName ) ) { + cfg.buildName = buildName; + pbm->setConfig( cfg ); + mLocateBarLayout->execute( "close-locatebar" ); + } + return; + } else if ( String::startsWith( mLocateInput->getText(), "sbt " ) ) { + auto pbm = mApp->getProjectBuildManager(); + auto cfg = pbm->getConfig(); + auto build = pbm->getBuild( cfg.buildName ); + if ( build != nullptr ) { + std::string buildType = vName.toString(); + if ( build->buildTypes().find( buildType ) != build->buildTypes().end() ) { + cfg.buildType = buildType; + pbm->setConfig( cfg ); + mLocateBarLayout->execute( "close-locatebar" ); + } + } + return; + } + Variant vPath( modelEvent->getModel()->data( modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ), ModelRole::Display ) ); @@ -375,19 +405,26 @@ void UniversalLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locat } ); } -void UniversalLocator::updateLocateBar() { - mLocateBarLayout->runOnMainThread( [this] { - Float width = eeceil( mLocateInput->getPixelsSize().getWidth() ); - mLocateTable->setPixelsSize( width, - mLocateTable->getRowHeight() * LOCATEBAR_MAX_VISIBLE_ITEMS ); - width -= mLocateTable->getVerticalScrollBar()->getPixelsSize().getWidth(); +void UniversalLocator::updateLocateBarSync() { + Float width = eeceil( mLocateInput->getPixelsSize().getWidth() ); + mLocateTable->setPixelsSize( width, + mLocateTable->getRowHeight() * LOCATEBAR_MAX_VISIBLE_ITEMS ); + width -= mLocateTable->getVerticalScrollBar()->getPixelsSize().getWidth(); + if ( mLocateTable->getModel()->columnCount() == 2 ) { mLocateTable->setColumnsVisible( { 0, 1 } ); mLocateTable->setColumnWidth( 0, eeceil( width * 0.5 ) ); mLocateTable->setColumnWidth( 1, width - mLocateTable->getColumnWidth( 0 ) ); - Vector2f pos( mLocateInput->convertToWorldSpace( { 0, 0 } ) ); - pos.y -= mLocateTable->getPixelsSize().getHeight(); - mLocateTable->setPixelsPosition( pos ); - } ); + } else { + mLocateTable->setColumnsVisible( { 0 } ); + mLocateTable->setColumnWidth( 0, width ); + } + Vector2f pos( mLocateInput->convertToWorldSpace( { 0, 0 } ) ); + pos.y -= mLocateTable->getPixelsSize().getHeight(); + mLocateTable->setPixelsPosition( pos ); +} + +void UniversalLocator::updateLocateBar() { + mLocateBarLayout->runOnMainThread( [this] { updateLocateBarSync(); } ); } void UniversalLocator::showBar() { @@ -421,7 +458,10 @@ void UniversalLocator::showLocateBar() { showBar(); if ( !mLocateInput->getText().empty() && - ( mLocateInput->getText()[0] == '>' || mLocateInput->getText()[0] == ':' ) ) + ( mLocateInput->getText()[0] == '>' || mLocateInput->getText()[0] == ':' || + mLocateInput->getText()[0] == '.' || + String::startsWith( mLocateInput->getText(), "sb " ) || + String::startsWith( mLocateInput->getText(), "sbt " ) ) ) mLocateInput->setText( "" ); if ( mApp->getDirTree() && !mLocateTable->getModel() ) { @@ -556,6 +596,94 @@ void UniversalLocator::updateOpenDocumentsTable() { mLocateTable->scrollToTop(); } +void UniversalLocator::showSwitchBuild() { + showBar(); + + if ( mLocateInput->getText().empty() || !String::startsWith( mLocateInput->getText(), "sb " ) ) + mLocateInput->setText( "sb " ); + + if ( mLocateInput->getText().size() >= 3 ) + updateSwitchBuildTable(); + updateLocateBar(); + mApp->getStatusBar()->updateState(); +} + +std::shared_ptr> +UniversalLocator::openBuildModel( const std::string& match ) { + const auto& builds = mApp->getProjectBuildManager()->getBuilds(); + std::vector buildNames; + if ( builds.empty() ) + return ItemListOwnerModel::create( {} ); + buildNames.reserve( builds.size() ); + for ( const auto& build : builds ) { + if ( match.empty() || + String::startsWith( String::toLower( build.first ), String::toLower( match ) ) ) + buildNames.push_back( build.first ); + } + std::stable_sort( buildNames.begin(), buildNames.end() ); + return ItemListOwnerModel::create( buildNames ); +} + +void UniversalLocator::updateSwitchBuildTable() { + mLocateTable->setModel( openBuildModel( mLocateInput->getText().substr( 3 ).trim().toUtf8() ) ); + if ( mLocateTable->getModel()->rowCount() > 0 ) { + ModelIndex idx = + mLocateTable->findRowWithText( mApp->getProjectBuildManager()->getConfig().buildName ); + mLocateTable->getSelection().set( idx.isValid() ? idx + : mLocateTable->getModel()->index( 0 ) ); + } + mLocateTable->scrollToTop(); +} + +void UniversalLocator::showSwitchBuildType() { + showBar(); + + if ( mLocateInput->getText().empty() || !String::startsWith( mLocateInput->getText(), "sbt " ) ) + mLocateInput->setText( "sbt " ); + + if ( mLocateInput->getText().size() >= 4 ) + updateSwitchBuildTypeTable(); + updateLocateBar(); + mApp->getStatusBar()->updateState(); +} + +std::shared_ptr> +UniversalLocator::openBuildTypeModel( const std::string& match ) { + const auto& builds = mApp->getProjectBuildManager()->getBuilds(); + const auto& cfg = mApp->getProjectBuildManager()->getConfig(); + + auto buildIt = builds.find( cfg.buildName ); + if ( buildIt == builds.end() ) + return ItemListOwnerModel::create( {} ); + const auto& build = buildIt->second; + const auto& buildTypes = build.buildTypes(); + if ( buildTypes.empty() ) + return ItemListOwnerModel::create( {} ); + + std::vector buildTypeNames; + buildTypeNames.reserve( builds.size() ); + for ( const auto& build : buildTypes ) { + if ( match.empty() || + String::startsWith( String::toLower( build ), String::toLower( match ) ) ) + buildTypeNames.push_back( build ); + } + std::stable_sort( buildTypeNames.begin(), buildTypeNames.end() ); + return ItemListOwnerModel::create( buildTypeNames ); +} + +void UniversalLocator::updateSwitchBuildTypeTable() { + mLocateTable->setModel( + openBuildTypeModel( mLocateInput->getText().substr( 4 ).trim().toUtf8() ) ); + if ( mLocateTable->getModel()->rowCount() > 0 ) { + ModelIndex idx = + mLocateTable->findRowWithText( mApp->getProjectBuildManager()->getConfig().buildType ); + mLocateTable->getSelection().set( idx.isValid() ? idx + : mLocateTable->getModel()->index( 0 ) ); + } + mLocateTable->scrollToTop(); + mLocateTable->setColumnsVisible( { 0 } ); +} + void UniversalLocator::onCodeEditorFocusChange( UICodeEditor* editor ) { if ( !mLocateTable || !mLocateTable->isVisible() ) return; @@ -725,6 +853,9 @@ std::vector UniversalLocator::getLocatorComma mUISceneNode->i18n( "go_to_line_in_current_document", "Go To Line in Current Document" ), icon } ); vec.push_back( { "o ", mUISceneNode->i18n( "open_documents", "Open Documents" ), icon } ); + vec.push_back( { "sb ", mUISceneNode->i18n( "switch_build", "Switch Build" ), icon } ); + vec.push_back( + { "sbt ", mUISceneNode->i18n( "switch_build_type", "Switch Build Type" ), icon } ); return vec; } diff --git a/src/tools/ecode/universallocator.hpp b/src/tools/ecode/universallocator.hpp index 299c5415c..e303a11e7 100644 --- a/src/tools/ecode/universallocator.hpp +++ b/src/tools/ecode/universallocator.hpp @@ -43,6 +43,10 @@ class UniversalLocator { void showOpenDocuments(); + void showSwitchBuild(); + + void showSwitchBuildType(); + protected: UILocateBar* mLocateBarLayout{ nullptr }; UITableView* mLocateTable{ nullptr }; @@ -60,18 +64,26 @@ class UniversalLocator { void updateLocateBar(); + void updateLocateBarSync(); + void showBar(); PluginRequestHandle processResponse( const PluginMessage& msg ); - void requestWorkspaceSymbol(); - void updateWorkspaceSymbol( const LSPSymbolInformationList& info ); - void requestDocumentSymbol(); - void updateDocumentSymbol( const LSPSymbolInformationList& info ); + void updateOpenDocumentsTable(); + + void updateSwitchBuildTable(); + + void updateSwitchBuildTypeTable(); + + void requestWorkspaceSymbol(); + + void requestDocumentSymbol(); + std::string getCurDocURI(); std::vector getLocatorCommands() const; @@ -83,11 +95,13 @@ class UniversalLocator { const LSPSymbolInformationList& list, const std::string& query, const size_t& limit, std::function )> cb ); - void updateOpenDocumentsTable(); - std::shared_ptr openDocumentsModel( const std::string& match ); void focusOrLoadFile( const std::string& path, const TextRange& range = {} ); + + std::shared_ptr> openBuildModel( const std::string& match ); + + std::shared_ptr> openBuildTypeModel( const std::string& match ); }; } // namespace ecode