mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-25 23:57:53 +03:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
},
|
||||
|
||||
@@ -236,6 +236,8 @@ class App : public UICodeEditorSplitter::Client {
|
||||
void removeFolderWatches();
|
||||
|
||||
void createDocAlert( UICodeEditor* editor );
|
||||
|
||||
void syncProjectTreeWithEditor( UICodeEditor* editor );
|
||||
};
|
||||
|
||||
#endif // EE_TOOLS_CODEEDITOR_HPP
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user