Added UITreeView::selectRowWithPath.

ecode: Added new option "Synchronize project tree with editor". The watcher now watch for all subdirectories in the project tree.
This commit is contained in:
Martín Lucas Golini
2021-11-22 01:34:42 -03:00
parent 1ac37e1468
commit 27d1b3722d
9 changed files with 112 additions and 7 deletions
@@ -69,7 +69,7 @@ class EE_API UIAbstractTableView : public UIAbstractView {
void moveSelection( int steps );
void setSelection( const ModelIndex& index, bool scrollToSelection = true );
virtual void setSelection( const ModelIndex& index, bool scrollToSelection = true );
const size_t& getIconSize() const;
+4
View File
@@ -129,6 +129,10 @@ class EE_API UITreeView : public UIAbstractTableView {
virtual ModelIndex findRowWithText( const std::string& text, const bool& caseSensitive = false,
const bool& exactMatch = false ) const;
virtual ModelIndex selectRowWithPath( std::string path );
virtual void setSelection( const ModelIndex& index, bool scrollToSelection = true );
bool getFocusOnSelection() const;
void setFocusOnSelection( bool focusOnSelection );
+75
View File
@@ -643,6 +643,81 @@ ModelIndex UITreeView::findRowWithText( const std::string& text, const bool& cas
return foundIndex;
}
ModelIndex UITreeView::selectRowWithPath( std::string path ) {
const Model* model = getModel();
if ( !model || model->rowCount() == 0 )
return {};
String::replaceAll( path, "\\", "/" );
auto pathPart = String::split( path, "/" );
if ( pathPart.empty() )
return {};
for ( size_t i = 0; i < pathPart.size(); i++ ) {
ModelIndex foundIndex = {};
const auto& part = pathPart[i];
traverseTree( [&]( const int&, const ModelIndex& index, const size_t&, const Float& ) {
Variant var = model->data( index );
if ( var.isValid() && var.toString() == part ) {
foundIndex = index;
return IterationDecision::Stop;
}
return IterationDecision::Continue;
} );
if ( foundIndex == ModelIndex() )
break;
if ( getModel()->rowCount( foundIndex ) ) {
auto& data = getIndexMetadata( foundIndex );
if ( !data.open ) {
data.open = true;
createOrUpdateColumns();
onOpenTreeModelIndex( foundIndex, data.open );
}
}
if ( i == pathPart.size() - 1 ) {
setSelection( foundIndex );
return foundIndex;
}
}
return {};
}
void UITreeView::setSelection( const ModelIndex& index, bool scrollToSelection ) {
if ( !getModel() )
return;
auto& model = *this->getModel();
if ( model.isValid( index ) && scrollToSelection ) {
getSelection().set( index );
ModelIndex prevIndex;
ModelIndex foundIndex;
Float curY = 0;
traverseTree(
[&]( const int&, const ModelIndex& _index, const size_t&, const Float& offsetY ) {
if ( index == _index ) {
foundIndex = prevIndex;
curY = offsetY;
return IterationDecision::Break;
}
prevIndex = index;
return IterationDecision::Continue;
} );
if ( foundIndex.isValid() ) {
if ( curY < mScrollOffset.y + getHeaderHeight() + getRowHeight() ||
curY > mScrollOffset.y + getPixelsSize().getHeight() - mPaddingPx.Top -
mPaddingPx.Bottom - getRowHeight() ) {
curY -= getHeaderHeight() + getRowHeight();
mVScroll->setValue( eemin<Float>(
1.f, eemax<Float>( 0.f, curY / getScrollableArea().getHeight() ) ) );
}
}
}
}
bool UITreeView::getFocusOnSelection() const {
return mFocusOnSelection;
}
+3
View File
@@ -75,6 +75,8 @@ void AppConfig::load( std::string& confPath, std::string& keybindingsPath,
editor.hideTabBarOnSingleTab = ini.getValueB( "editor", "hide_tab_bar_on_single_tab", true );
editor.singleClickTreeNavigation =
ini.getValueB( "editor", "single_click_tree_navigation", false );
editor.syncProjectTreeWithEditor =
ini.getValueB( "editor", "sync_project_tree_with_editor", false );
iniInfo = FileInfo( ini.path() );
}
@@ -130,6 +132,7 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
ini.setValueB( "editor", "show_doc_info", editor.showDocInfo );
ini.setValueB( "editor", "hide_tab_bar_on_single_tab", editor.hideTabBarOnSingleTab );
ini.setValueB( "editor", "single_click_tree_navigation", editor.singleClickTreeNavigation );
ini.setValueB( "editor", "sync_project_tree_with_editor", editor.syncProjectTreeWithEditor );
ini.writeFile();
iniState.writeFile();
}
+1
View File
@@ -54,6 +54,7 @@ struct CodeEditorConfig {
bool formatter{ true };
bool hideTabBarOnSingleTab{ true };
bool singleClickTreeNavigation{ false };
bool syncProjectTreeWithEditor{ true };
std::string autoCloseBrackets{ "" };
int indentWidth{ 4 };
int tabWidth{ 4 };
+23 -4
View File
@@ -625,6 +625,10 @@ UIMenu* App::createViewMenu() {
->setActive( mConfig.editor.singleClickTreeNavigation )
->setTooltipText(
"Uses single click to open files and expand subfolders in\nthe directory tree." );
mViewMenu->addCheckBox( "Synchronize project tree with editor" )
->setActive( mConfig.editor.syncProjectTreeWithEditor )
->setTooltipText( "Syncronizes the current focused document as the selected\nfile in the "
"directory tree." );
mViewMenu->add( "Line Breaking Column" );
mViewMenu->addEventListener( Event::OnItemClicked, [&]( const Event* event ) {
@@ -689,6 +693,8 @@ UIMenu* App::createViewMenu() {
} else if ( item->getText() == "Single Click Navigation in Tree View" ) {
mConfig.editor.singleClickTreeNavigation = item->asType<UIMenuCheckBox>()->isActive();
mProjectTreeView->setSingleClickNavigation( mConfig.editor.singleClickTreeNavigation );
} else if ( item->getText() == "Synchronize project tree with editor" ) {
mConfig.editor.syncProjectTreeWithEditor = item->asType<UIMenuCheckBox>()->isActive();
} else if ( item->getText() == "Line Breaking Column" ) {
UIMessageBox* msgBox =
UIMessageBox::New( UIMessageBox::INPUT, "Set Line Breaking Column:\n"
@@ -1042,10 +1048,21 @@ void App::updateDocInfo( TextDocument& doc ) {
}
}
void App::syncProjectTreeWithEditor( UICodeEditor* editor ) {
if ( mConfig.editor.syncProjectTreeWithEditor && editor->getDocument().hasFilepath() ) {
std::string path = editor->getDocument().getFilePath();
if ( path.size() >= mCurrentProject.size() ) {
path = path.substr( mCurrentProject.size() );
mProjectTreeView->selectRowWithPath( path );
}
}
}
void App::onCodeEditorFocusChange( UICodeEditor* editor ) {
updateDocInfo( editor->getDocument() );
updateDocumentMenu();
mDocSearchController->onCodeEditorFocusChange( editor );
syncProjectTreeWithEditor( editor );
}
void App::onColorSchemeChanged( const std::string& ) {
@@ -1666,12 +1683,14 @@ void App::loadDirTree( const std::string& path ) {
clock->getElapsedTime().asMilliseconds(), dirTree.getFilesCount() );
eeDelete( clock );
mDirTreeReady = true;
mUISceneNode->runOnMainThread( [&] { mFileLocator->updateLocateTable(); } );
mUISceneNode->runOnMainThread( [&] {
mFileLocator->updateLocateTable();
syncProjectTreeWithEditor( mEditorSplitter->getCurEditor() );
} );
if ( mFileWatcher ) {
removeFolderWatches();
auto newDirs = dirTree.getDirectories();
for ( const auto& dir : newDirs )
mFolderWatches.insert( mFileWatcher->addWatch( dir, mFileSystemListener ) );
mFolderWatches.insert(
mFileWatcher->addWatch( dirTree.getPath(), mFileSystemListener, true ) );
mFileSystemListener->setDirTree( mDirTree );
}
},
+2
View File
@@ -236,6 +236,8 @@ class App : public UICodeEditorSplitter::Client {
void removeFolderWatches();
void createDocAlert( UICodeEditor* editor );
void syncProjectTreeWithEditor( UICodeEditor* editor );
};
#endif // EE_TOOLS_CODEEDITOR_HPP
+1 -1
View File
@@ -14,7 +14,7 @@ void FileSystemListener::handleFileAction( efsw::WatchID, const std::string& dir
case efsw::Actions::Delete:
case efsw::Actions::Moved: {
auto* node = mFileSystemModel.get()->getNodeFromPath( file.getFilepath(), true, false );
if ( node ) {
if ( node && mDirTree && mDirTree.get()->isDirInTree( file.getDirectoryPath() ) ) {
if ( !mFileSystemModel.get()->getDisplayConfig().ignoreHidden ||
!file.isHidden() ) {
node->invalidate();
@@ -90,6 +90,8 @@ class ProjectDirectoryTree {
void onChange( const Action& action, const FileInfo& file, const std::string& oldFilename );
const std::string& getPath() const { return mPath; }
protected:
std::string mPath;
std::shared_ptr<ThreadPool> mPool;
@@ -115,7 +117,6 @@ class ProjectDirectoryTree {
IgnoreMatcherManager getIgnoreMatcherFromPath( const std::string& path );
size_t findFileIndex( const std::string& path );
};
#endif // EE_TOOLS_PROJECTDIRECTORYTREE_HPP