IgnoreMatcher now check for subfolder ignore files and apply the ignore rules from that file.

Added "Save All" to ecode.
Some improvements to UIFileDialog.
Some minor refactor.
This commit is contained in:
Martín Lucas Golini
2020-08-29 21:31:06 -03:00
parent ae1bb00af7
commit f3e1720bc2
20 changed files with 320 additions and 200 deletions

View File

@@ -14,6 +14,8 @@ class EE_API KeyEvent : public Event {
KeyEvent( Node* node, const Uint32& eventNum, const Keycode& keyCode, const Uint32& chr,
const Uint32& mod );
KeyEvent( const KeyEvent& event );
~KeyEvent();
const Keycode& getKeyCode() const;
@@ -23,9 +25,9 @@ class EE_API KeyEvent : public Event {
const Uint32& getMod() const;
protected:
Keycode mKeyCode;
String::StringBaseType mChar;
Uint32 mMod;
Keycode mKeyCode{Keycode::KEY_UNKNOWN};
String::StringBaseType mChar{0};
Uint32 mMod{0};
};
class EE_API TextInputEvent : public Event {

View File

@@ -148,7 +148,7 @@ class EE_API UIAbstractTableView : public UIAbstractView {
virtual void onScrollChange();
virtual void onOpenModelIndex( const ModelIndex& index );
virtual void onOpenModelIndex( const ModelIndex& index, const Event* triggerEvent = nullptr );
virtual void onSortColumn( const size_t& colIndex );

View File

@@ -16,11 +16,13 @@ enum class ModelEventType { Open, OpenTree, CloseTree };
class EE_API ModelEvent : public Event {
public:
ModelEvent( Model* model, const ModelIndex& index, Node* node,
const ModelEventType& modelEventType = ModelEventType::Open ) :
Event( node, Event::OnModelEvent ),
const ModelEventType& modelEventType = ModelEventType::Open,
const Event* triggerEvent = nullptr ) :
Event( node, EventType::OnModelEvent ),
model( model ),
index( index ),
modelEventType( modelEventType ) {}
modelEventType( modelEventType ),
triggerEvent( triggerEvent ) {}
const Model* getModel() const { return model; }
@@ -28,10 +30,13 @@ class EE_API ModelEvent : public Event {
const ModelEventType& getModelEventType() const { return modelEventType; }
const Event* getTriggerEvent() const { return triggerEvent; }
protected:
const Model* model;
ModelIndex index;
ModelEventType modelEventType;
const Event* triggerEvent{nullptr};
};
class EE_API UIAbstractView : public UIScrollableWidget {

View File

@@ -111,6 +111,10 @@ class EE_API UICodeEditorSplitter {
bool editorExists( UICodeEditor* editor ) const;
bool isAnyEditorDirty();
void forEachEditorStoppable( std::function<bool( UICodeEditor* )> run );
protected:
UISceneNode* mUISceneNode{nullptr};
UICodeEditor* mCurEditor{nullptr};

View File

@@ -122,7 +122,7 @@ class EE_API UIFileDialog : public UIWindow {
void disableButtons();
void openFileOrFolder();
void openFileOrFolder( bool shouldOpenFolder );
void goFolderUp();

View File

@@ -1025,6 +1025,8 @@
../../src/tools/codeeditor/projectsearch.hpp
../../src/tools/codeeditor/uicodeeditorsplitter.cpp
../../src/tools/codeeditor/uicodeeditorsplitter.hpp
../../src/tools/codeeditor/uitreeviewglobalsearch.cpp
../../src/tools/codeeditor/uitreeviewglobalsearch.hpp
../../src/tools/mapeditor/mapeditor.cpp
../../src/tools/textureatlaseditor/textureatlaseditor.cpp
../../src/tools/texturepacker/texturepacker.cpp

View File

@@ -7,6 +7,12 @@ KeyEvent::KeyEvent( Node* node, const Uint32& eventNum, const Keycode& keyCode,
const Uint32& mod ) :
Event( node, eventNum ), mKeyCode( keyCode ), mChar( chr ), mMod( mod ) {}
KeyEvent::KeyEvent( const KeyEvent& event ) :
Event( event.getNode(), event.getType() ),
mKeyCode( event.getKeyCode() ),
mChar( event.getChar() ),
mMod( event.getMod() ) {}
KeyEvent::~KeyEvent() {}
const Keycode& KeyEvent::getKeyCode() const {

View File

@@ -335,7 +335,7 @@ UIWidget* UIAbstractTableView::createCell( UIWidget* rowWidget, const ModelIndex
auto mouseEvent = static_cast<const MouseEvent*>( event );
auto idx = mouseEvent->getNode()->getParent()->asType<UITableRow>()->getCurIndex();
if ( mouseEvent->getFlags() & EE_BUTTON_LMASK ) {
onOpenModelIndex( idx );
onOpenModelIndex( idx, event );
}
} );
return widget;
@@ -422,8 +422,8 @@ void UIAbstractTableView::setSortIconSize( const size_t& sortIconSize ) {
mSortIconSize = sortIconSize;
}
void UIAbstractTableView::onOpenModelIndex( const ModelIndex& index ) {
ModelEvent event( getModel(), index, this );
void UIAbstractTableView::onOpenModelIndex( const ModelIndex& index, const Event* triggerEvent ) {
ModelEvent event( getModel(), index, this, ModelEventType::Open, triggerEvent );
sendEvent( &event );
}
@@ -470,7 +470,7 @@ Uint32 UIAbstractTableView::onTextInput( const TextInputEvent& event ) {
mSearchText += String::toLower( event.getText() );
ModelIndex index = findRowWithText( mSearchText );
if ( index.isValid() )
getSelection().set( index );
setSelection( index );
return 1;
}

View File

@@ -400,6 +400,28 @@ void UICodeEditorSplitter::forEachEditor( std::function<void( UICodeEditor* )> r
run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() );
}
void UICodeEditorSplitter::forEachEditorStoppable( std::function<bool( UICodeEditor* )> run ) {
for ( auto tabWidget : mTabWidgets ) {
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
if ( run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() ) ) {
return;
}
}
}
}
bool UICodeEditorSplitter::isAnyEditorDirty() {
bool any = false;
forEachEditorStoppable( [&any]( UICodeEditor* editor ) {
if ( editor->isDirty() ) {
any = true;
return true;
}
return false;
} );
return any;
}
void UICodeEditorSplitter::zoomIn() {
forEachEditor( []( UICodeEditor* editor ) { editor->fontSizeGrow(); } );
}

View File

@@ -100,8 +100,18 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
if ( modelEvent->getModelEventType() == ModelEventType::Open ) {
Variant vPath(
modelEvent->getModel()->data( modelEvent->getModelIndex(), Model::Role::Custom ) );
if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) )
openFileOrFolder();
if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) ) {
bool shouldOpenFolder = false;
if ( getAllowFolderSelect() && modelEvent->getTriggerEvent() &&
modelEvent->getTriggerEvent()->getType() == Event::EventType::KeyDown ) {
const KeyEvent* keyEvent =
static_cast<const KeyEvent*>( modelEvent->getTriggerEvent() );
if ( keyEvent->getMod() & KEYMOD_CTRL ) {
shouldOpenFolder = true;
}
}
openFileOrFolder( shouldOpenFolder );
}
}
} );
mList->setOnSelectionChange( [&] {
@@ -110,9 +120,9 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
auto* node = (FileSystemModel::Node*)mList->getSelection().first().data();
if ( !isSaveDialog() ) {
if ( getAllowFolderSelect() || !FileSystem::isDirectory( node->fullPath() ) )
mFile->setText( node->getName() );
setFileName( node->getName() );
} else if ( !FileSystem::isDirectory( node->fullPath() ) ) {
mFile->setText( node->getName() );
setFileName( node->getName() );
}
} );
mList->setAutoExpandOnSingleColumn( true );
@@ -252,7 +262,8 @@ void UIFileDialog::setCurPath( const std::string& path ) {
mCurPath = path;
FileSystem::dirAddSlashAtEnd( mCurPath );
mPath->setText( mCurPath );
mFile->setText( "" );
if ( !isSaveDialog() )
mFile->setText( "" );
refreshFolder();
}
@@ -283,7 +294,7 @@ void UIFileDialog::disableButtons() {
mButtonMaximize->setEnabled( false );
}
void UIFileDialog::openFileOrFolder() {
void UIFileDialog::openFileOrFolder( bool shouldOpenFolder = false ) {
if ( mList->getSelection().isEmpty() )
return;
auto* node = (FileSystemModel::Node*)mList->getSelection().first().data();
@@ -291,7 +302,11 @@ void UIFileDialog::openFileOrFolder() {
std::string newPath = mCurPath + node->getName();
if ( FileSystem::isDirectory( newPath ) ) {
setCurPath( newPath );
if ( shouldOpenFolder ) {
open();
} else {
setCurPath( newPath );
}
} else {
open();
}

View File

@@ -231,7 +231,7 @@ Uint32 UITableView::onKeyDown( const KeyEvent& event ) {
case KEY_RETURN:
case KEY_KP_ENTER: {
if ( curIndex.isValid() )
onOpenModelIndex( curIndex );
onOpenModelIndex( curIndex, &event );
return 1;
}
default:

View File

@@ -127,7 +127,7 @@ UIWidget* UITreeView::setupCell( UITableCell* widget, UIWidget* rowWidget,
createOrUpdateColumns();
onOpenTreeModelIndex( idx, data.open );
} else {
onOpenModelIndex( idx );
onOpenModelIndex( idx, event );
}
}
} );
@@ -586,7 +586,7 @@ Uint32 UITreeView::onKeyDown( const KeyEvent& event ) {
metadata.open = !metadata.open;
createOrUpdateColumns();
} else {
onOpenModelIndex( curIndex );
onOpenModelIndex( curIndex, &event );
}
}
return 1;

View File

@@ -6,6 +6,18 @@
App* appInstance = nullptr;
static bool isRelativePath( const std::string& path ) {
if ( !path.empty() ) {
if ( path[0] == '/' )
return false;
#if EE_PLATFORM == EE_PLATFORM_WIN
if ( path.size() >= 2 && String::isLetter( path[0] ) && path[1] == ':' )
return false;
#endif
}
return true;
}
void appLoop() {
appInstance->mainLoop();
}
@@ -33,21 +45,63 @@ void App::saveDoc() {
if ( mEditorSplitter->getCurEditor()->save() )
updateEditorState();
} else {
saveFileDialog();
saveFileDialog( mEditorSplitter->getCurEditor() );
}
}
void App::saveAllProcess() {
if ( mTmpDocs.empty() )
return;
mEditorSplitter->forEachEditorStoppable( [&]( UICodeEditor* editor ) {
if ( editor->getDocument().isDirty() &&
std::find( mTmpDocs.begin(), mTmpDocs.end(), &editor->getDocument() ) !=
mTmpDocs.end() ) {
if ( editor->getDocument().hasFilepath() ) {
editor->save();
updateEditorTabTitle( editor );
mTmpDocs.erase( &editor->getDocument() );
} else {
UIFileDialog* dialog = saveFileDialog( editor, false );
dialog->addEventListener( Event::SaveFile, [&, editor]( const Event* ) {
updateEditorTabTitle( editor );
} );
dialog->addEventListener( Event::OnWindowClose, [&, editor]( const Event* ) {
mTmpDocs.erase( &editor->getDocument() );
if ( !SceneManager::instance()->isShootingDown() && !mTmpDocs.empty() )
saveAllProcess();
} );
return true;
}
}
return false;
} );
}
void App::saveAll() {
mEditorSplitter->forEachEditor( [&]( UICodeEditor* editor ) {
if ( editor->isDirty() )
mTmpDocs.insert( &editor->getDocument() );
} );
saveAllProcess();
}
std::string App::titleFromEditor( UICodeEditor* editor ) {
std::string title( editor->getDocument().getFilename() );
return editor->getDocument().isDirty() ? title + "*" : title;
}
void App::updateEditorTitle( UICodeEditor* editor ) {
void App::updateEditorTabTitle( UICodeEditor* editor ) {
std::string title( titleFromEditor( editor ) );
if ( editor->getData() ) {
UITab* tab = (UITab*)editor->getData();
tab->setText( title );
}
}
void App::updateEditorTitle( UICodeEditor* editor ) {
std::string title( titleFromEditor( editor ) );
updateEditorTabTitle( editor );
setAppTitle( title );
}
@@ -111,8 +165,11 @@ void App::openFolderDialog() {
}
void App::openFontDialog( std::string& fontPath ) {
std::string absoluteFontPath( fontPath );
if ( isRelativePath( absoluteFontPath ) )
absoluteFontPath = mResPath + fontPath;
UIFileDialog* dialog = UIFileDialog::New( UIFileDialog::DefaultFlags, "*.ttf; *.otf; *.wolff",
FileSystem::fileRemoveFileName( fontPath ) );
FileSystem::fileRemoveFileName( absoluteFontPath ) );
ModelIndex index =
dialog->getList()->findRowWithText( FileSystem::fileNameFromPath( fontPath ), true, true );
if ( index.isValid() )
@@ -140,23 +197,24 @@ void App::openFontDialog( std::string& fontPath ) {
dialog->show();
}
void App::saveFileDialog() {
UIFileDialog* App::saveFileDialog( UICodeEditor* editor, bool focusOnClose ) {
if ( !editor )
return nullptr;
UIFileDialog* dialog =
UIFileDialog::New( UIFileDialog::DefaultFlags | UIFileDialog::SaveDialog, "." );
dialog->setWinFlags( UI_WIN_DEFAULT_FLAGS | UI_WIN_MAXIMIZE_BUTTON | UI_WIN_MODAL );
dialog->setTitle( "Save File As" );
dialog->setCloseShortcut( KEY_ESCAPE );
std::string filename( mEditorSplitter->getCurEditor()->getDocument().getFilename() );
if ( FileSystem::fileExtension( mEditorSplitter->getCurEditor()->getDocument().getFilename() )
.empty() )
filename += mEditorSplitter->getCurEditor()->getSyntaxDefinition().getFileExtension();
std::string filename( editor->getDocument().getFilename() );
if ( FileSystem::fileExtension( editor->getDocument().getFilename() ).empty() )
filename += editor->getSyntaxDefinition().getFileExtension();
dialog->setFileName( filename );
dialog->addEventListener( Event::SaveFile, [&]( const Event* event ) {
if ( mEditorSplitter->getCurEditor() ) {
dialog->addEventListener( Event::SaveFile, [&, editor]( const Event* event ) {
if ( editor ) {
std::string path( event->getNode()->asType<UIFileDialog>()->getFullPath() );
if ( !path.empty() && !FileSystem::isDirectory( path ) &&
FileSystem::fileCanWrite( FileSystem::fileRemoveFileName( path ) ) ) {
if ( mEditorSplitter->getCurEditor()->getDocument().save( path ) ) {
if ( editor->getDocument().save( path ) ) {
updateEditorState();
} else {
UIMessageBox* msg =
@@ -172,12 +230,15 @@ void App::saveFileDialog() {
}
}
} );
dialog->addEventListener( Event::OnWindowClose, [&]( const Event* ) {
if ( mEditorSplitter->getCurEditor() && !SceneManager::instance()->isShootingDown() )
mEditorSplitter->getCurEditor()->setFocus();
} );
if ( focusOnClose ) {
dialog->addEventListener( Event::OnWindowClose, [&, editor]( const Event* ) {
if ( editor && !SceneManager::instance()->isShootingDown() )
editor->setFocus();
} );
}
dialog->center();
dialog->show();
return dialog;
}
bool App::findPrevText( SearchState& search ) {
@@ -683,83 +744,6 @@ void App::hideGlobalSearchBar() {
mGlobalSearchTree->setVisible( false );
}
class UITreeViewCellGlobalSearch : public UITreeViewCell {
public:
static UITreeViewCellGlobalSearch* New() { return eeNew( UITreeViewCellGlobalSearch, () ); }
UITreeViewCellGlobalSearch() : UITreeViewCell() {}
UIPushButton* setText( const String& text );
UIPushButton* updateText( const String& text );
};
class UITreeViewGlobalSearch : public UITreeView {
public:
static UITreeViewGlobalSearch* New( const SyntaxColorScheme& colorScheme ) {
return eeNew( UITreeViewGlobalSearch, ( colorScheme ) );
}
UITreeViewGlobalSearch( const SyntaxColorScheme& colorScheme ) :
UITreeView(), mColorScheme( colorScheme ) {
mLineNumColor = Color::fromString(
mUISceneNode->getRoot()->getUIStyle()->getVariable( "--font-hint" ).getValue() );
}
UIWidget* createCell( UIWidget* rowWidget, const ModelIndex& index ) {
UITableCell* widget = index.column() == (Int64)getModel()->treeColumn()
? UITreeViewCellGlobalSearch::New()
: UITableCell::New();
return setupCell( widget, rowWidget, index );
}
const SyntaxColorScheme& getColorScheme() const { return mColorScheme; }
const Color& getLineNumColor() const { return mLineNumColor; }
void updateColorScheme( const SyntaxColorScheme& colorScheme ) { mColorScheme = colorScheme; }
protected:
Color mLineNumColor;
SyntaxColorScheme mColorScheme;
};
UIPushButton* UITreeViewCellGlobalSearch::updateText( const String& text ) {
if ( getCurIndex().internalId() != -1 ) {
UITreeViewGlobalSearch* pp = getParent()->getParent()->asType<UITreeViewGlobalSearch>();
ProjectSearch::ResultData* res = (ProjectSearch::ResultData*)getCurIndex().parent().data();
auto styleDef = SyntaxDefinitionManager::instance()->getStyleByExtension( res->file );
auto tokens =
SyntaxTokenizer::tokenize( styleDef, text, SYNTAX_TOKENIZER_STATE_NONE ).first;
size_t start = 0;
for ( auto& token : tokens ) {
mTextBox->setFontFillColor( pp->getColorScheme().getSyntaxStyle( token.type ).color,
start, start + token.text.size() );
start += token.text.size();
}
Uint32 from = text.find_first_not_of( ' ' );
if ( from != String::InvalidPos )
mTextBox->setFontFillColor( pp->getLineNumColor(), from,
text.find_first_of( ' ', from ) );
}
return this;
}
UIPushButton* UITreeViewCellGlobalSearch::setText( const String& text ) {
if ( text != mTextBox->getText() ) {
mTextBox->setVisible( !text.empty() );
mTextBox->setText( text );
updateText( text );
updateLayout();
}
return this;
}
void App::initGlobalSearchBar() {
auto addClickListener = [&]( UIWidget* widget, std::string cmd ) {
widget->addEventListener( Event::MouseClick, [this, cmd]( const Event* event ) {
@@ -793,8 +777,9 @@ void App::initGlobalSearchBar() {
eePRINTL( "Global search for \"%s\" took %.2fms", search.c_str(),
clock->getElapsedTime().asMilliseconds() );
eeDelete( clock );
mUISceneNode->runOnMainThread( [&, loader, res] {
mUISceneNode->runOnMainThread( [&, loader, res, search] {
updateGlobalSearchBar();
mGlobalSearchTree->setSearchStr( search );
mGlobalSearchTree->setModel( ProjectSearch::asModel( res ) );
if ( mGlobalSearchTree->getModel()->rowCount() < 50 )
mGlobalSearchTree->expandAll();
@@ -1636,8 +1621,7 @@ void App::onCodeEditorFocusChange( UICodeEditor* editor ) {
void App::onColorSchemeChanged( const std::string& ) {
updateColorSchemeMenu();
mGlobalSearchTree->asType<UITreeViewGlobalSearch>()->updateColorScheme(
mEditorSplitter->getCurrentColorScheme() );
mGlobalSearchTree->updateColorScheme( mEditorSplitter->getCurrentColorScheme() );
}
void App::onDocumentLoaded( UICodeEditor* codeEditor, const std::string& path ) {
@@ -1685,6 +1669,7 @@ std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
{{KEY_F, KEYMOD_CTRL | KEYMOD_SHIFT}, "open-global-search"},
{{KEY_L, KEYMOD_CTRL}, "go-to-line"},
{{KEY_M, KEYMOD_CTRL}, "menu-toggle"},
{{KEY_S, KEYMOD_CTRL | KEYMOD_SHIFT}, "save-all"},
};
}
@@ -1723,7 +1708,8 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
editor->addKeyBinds( getLocalKeybindings() );
editor->addUnlockedCommands( getUnlockedCommands() );
doc.setCommand( "save-doc", [&] { saveDoc(); } );
doc.setCommand( "save-as-doc", [&] { saveFileDialog(); } );
doc.setCommand( "save-as-doc", [&] { saveFileDialog( mEditorSplitter->getCurEditor() ); } );
doc.setCommand( "save-all", [&] { saveAll(); } );
doc.setCommand( "find-replace", [&] { showFindView(); } );
doc.setCommand( "open-global-search", [&] { showGlobalSearch(); } );
doc.setCommand( "open-locatebar", [&] { showLocateBar(); } );
@@ -1875,6 +1861,7 @@ void App::createSettingsMenu() {
mSettingsMenu->addSeparator();
mSettingsMenu->add( "Save", findIcon( "document-save" ), getKeybind( "save-doc" ) );
mSettingsMenu->add( "Save as...", findIcon( "document-save-as" ), getKeybind( "save-as-doc" ) );
mSettingsMenu->add( "Save All", findIcon( "document-save-as" ), getKeybind( "save-all" ) );
mSettingsMenu->addSeparator();
mSettingsMenu->addSubMenu( "Filetype", nullptr, createFiletypeMenu() );
mSettingsMenu->addSubMenu( "Color Scheme", nullptr, createColorSchemeMenu() );
@@ -1904,6 +1891,8 @@ void App::createSettingsMenu() {
runCommand( "save-doc" );
} else if ( name == "Save as..." ) {
runCommand( "save-as-doc" );
} else if ( name == "Save All" ) {
runCommand( "save-all" );
} else if ( name == "Close" ) {
runCommand( "close-doc" );
} else if ( name == "Quit" ) {
@@ -2073,16 +2062,6 @@ void App::loadFolder( const std::string& path ) {
mEditorSplitter->getCurEditor()->setFocus();
}
static bool isRelativePath( const std::string& path ) {
if ( !path.empty() ) {
if ( path[0] == '/' )
return false;
if ( path.size() >= 2 && String::isLetter( path[0] ) && path[1] == ':' )
return false;
}
return true;
}
FontTrueType* App::loadFont( const std::string& name, std::string fontPath,
const std::string& fallback ) {
if ( fontPath.empty() )

View File

@@ -2,28 +2,29 @@
#define EE_TOOLS_CODEEDITOR_HPP
#include "projectdirectorytree.hpp"
#include "uitreeviewglobalsearch.hpp"
#include <eepp/ee.hpp>
class UISearchBar : public UILinearLayout {
class WidgetCommandExecuter {
public:
typedef std::function<void()> CommandCallback;
static UISearchBar* New() { return eeNew( UISearchBar, () ); }
UISearchBar() :
UILinearLayout( "searchbar", UIOrientation::Horizontal ),
mKeyBindings( getUISceneNode()->getWindow()->getInput() ) {}
public:
WidgetCommandExecuter( const KeyBindings& keybindings ) : mKeyBindings( keybindings ) {}
void addCommand( const std::string& name, const CommandCallback& cb ) { mCommands[name] = cb; }
void execute( const std::string& command ) {
auto cmdIt = mCommands.find( command );
if ( cmdIt != mCommands.end() )
cmdIt->second();
}
KeyBindings& getKeyBindings() { return mKeyBindings; }
protected:
KeyBindings mKeyBindings;
std::unordered_map<std::string, std::function<void()>> mCommands;
Uint32 onKeyDown( const KeyEvent& event ) {
std::string cmd =
mKeyBindings.getCommandFromKeyBind( {event.getKeyCode(), event.getMod()} );
@@ -38,71 +39,41 @@ class UISearchBar : public UILinearLayout {
}
};
class UILocateBar : public UILinearLayout {
class UISearchBar : public UILinearLayout, public WidgetCommandExecuter {
public:
static UISearchBar* New() { return eeNew( UISearchBar, () ); }
UISearchBar() :
UILinearLayout( "searchbar", UIOrientation::Horizontal ),
WidgetCommandExecuter( getUISceneNode()->getWindow()->getInput() ) {}
virtual Uint32 onKeyDown( const KeyEvent& event ) {
return WidgetCommandExecuter::onKeyDown( event );
}
};
class UILocateBar : public UILinearLayout, public WidgetCommandExecuter {
public:
typedef std::function<void()> CommandCallback;
static UILocateBar* New() { return eeNew( UILocateBar, () ); }
UILocateBar() :
UILinearLayout( "locatebar", UIOrientation::Horizontal ),
mKeyBindings( getUISceneNode()->getWindow()->getInput() ) {}
WidgetCommandExecuter( getUISceneNode()->getWindow()->getInput() ) {}
public:
void addCommand( const std::string& name, const CommandCallback& cb ) { mCommands[name] = cb; }
void execute( const std::string& command ) {
auto cmdIt = mCommands.find( command );
if ( cmdIt != mCommands.end() )
cmdIt->second();
}
KeyBindings& getKeyBindings() { return mKeyBindings; }
protected:
KeyBindings mKeyBindings;
std::unordered_map<std::string, std::function<void()>> mCommands;
Uint32 onKeyDown( const KeyEvent& event ) {
std::string cmd =
mKeyBindings.getCommandFromKeyBind( {event.getKeyCode(), event.getMod()} );
if ( !cmd.empty() ) {
auto cmdIt = mCommands.find( cmd );
if ( cmdIt != mCommands.end() ) {
cmdIt->second();
return 1;
}
}
return 0;
virtual Uint32 onKeyDown( const KeyEvent& event ) {
return WidgetCommandExecuter::onKeyDown( event );
}
};
class UIGlobalSearchBar : public UILinearLayout {
class UIGlobalSearchBar : public UILinearLayout, public WidgetCommandExecuter {
public:
typedef std::function<void()> CommandCallback;
static UIGlobalSearchBar* New() { return eeNew( UIGlobalSearchBar, () ); }
UIGlobalSearchBar() :
UILinearLayout( "globalsearchbar", UIOrientation::Vertical ),
mKeyBindings( getUISceneNode()->getWindow()->getInput() ) {}
WidgetCommandExecuter( getUISceneNode()->getWindow()->getInput() ) {}
public:
void addCommand( const std::string& name, const CommandCallback& cb ) { mCommands[name] = cb; }
void execute( const std::string& command ) {
auto cmdIt = mCommands.find( command );
if ( cmdIt != mCommands.end() )
cmdIt->second();
}
KeyBindings& getKeyBindings() { return mKeyBindings; }
protected:
KeyBindings mKeyBindings;
std::unordered_map<std::string, std::function<void()>> mCommands;
Uint32 onKeyDown( const KeyEvent& event ) {
std::string cmd =
mKeyBindings.getCommandFromKeyBind( {event.getKeyCode(), event.getMod()} );
if ( !cmd.empty() ) {
auto cmdIt = mCommands.find( cmd );
if ( cmdIt != mCommands.end() ) {
cmdIt->second();
return 1;
}
}
return 0;
virtual Uint32 onKeyDown( const KeyEvent& event ) {
return WidgetCommandExecuter::onKeyDown( event );
}
};
@@ -182,7 +153,7 @@ class App : public UICodeEditorSplitter::Client {
void openFontDialog( std::string& fontPath );
void saveFileDialog();
UIFileDialog* saveFileDialog( UICodeEditor* editor, bool focusOnClose = true );
bool findPrevText( SearchState& search );
@@ -214,6 +185,8 @@ class App : public UICodeEditorSplitter::Client {
std::vector<std::string> getUnlockedCommands();
void saveAll();
protected:
EE::Window::Window* mWindow{nullptr};
UISceneNode* mUISceneNode{nullptr};
@@ -257,10 +230,13 @@ class App : public UICodeEditorSplitter::Client {
UITreeView* mProjectTreeView{nullptr};
UITableView* mLocateTable{nullptr};
UITextInput* mLocateInput{nullptr};
UITreeView* mGlobalSearchTree{nullptr};
UITreeViewGlobalSearch* mGlobalSearchTree{nullptr};
UITextInput* mGlobalSearchInput;
size_t mMenuIconSize;
bool mDirTreeReady{false};
std::unordered_set<Doc::TextDocument*> mTmpDocs;
void saveAllProcess();
void initLocateBar();
@@ -276,6 +252,8 @@ class App : public UICodeEditorSplitter::Client {
void updateEditorTitle( UICodeEditor* editor );
void updateEditorTabTitle( UICodeEditor* editor );
std::string titleFromEditor( UICodeEditor* editor );
bool tryTabClose( UICodeEditor* editor );

View File

@@ -177,7 +177,7 @@ bool GitIgnoreMatcher::parse() {
return !mPatterns.empty();
}
bool GitIgnoreMatcher::match( const std::string& value ) {
bool GitIgnoreMatcher::match( const std::string& value ) const {
for ( size_t i = 0; i < mPatterns.size(); i++ ) {
if ( gitignore_glob_match( value, mPatterns[i].first ) ) {
if ( mHasNegates ) {
@@ -204,7 +204,12 @@ bool IgnoreMatcherManager::foundMatch() const {
return mMatcher != nullptr;
}
bool IgnoreMatcherManager::match( const std::string& value ) {
bool IgnoreMatcherManager::match( const std::string& value ) const {
eeASSERT( foundMatch() );
return mMatcher->match( value );
}
const std::string& IgnoreMatcherManager::getPath() const {
eeASSERT( foundMatch() );
return mMatcher->getPath();
}

View File

@@ -16,7 +16,9 @@ class IgnoreMatcher {
virtual bool canMatch() = 0;
virtual bool match( const std::string& value ) = 0;
virtual bool match( const std::string& value ) const = 0;
const std::string& getPath() const { return mPath; }
protected:
std::string mPath;
@@ -30,7 +32,7 @@ class GitIgnoreMatcher : public IgnoreMatcher {
bool canMatch() override;
bool match( const std::string& value ) override;
bool match( const std::string& value ) const override;
protected:
bool parse() override;
@@ -45,7 +47,9 @@ class IgnoreMatcherManager {
bool foundMatch() const;
bool match( const std::string& value );
bool match( const std::string& value ) const;
const std::string& getPath() const;
protected:
std::unique_ptr<IgnoreMatcher> mMatcher;

View File

@@ -24,7 +24,7 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent&
for ( auto& strPattern : acceptedPattern )
patterns.emplace_back( LuaPattern( strPattern ) );
std::set<std::string> info;
getDirectoryFiles( files, names, mPath, info, ignoreHidden );
getDirectoryFiles( files, names, mPath, info, ignoreHidden, mIgnoreMatcher );
size_t namesCount = names.size();
bool found;
for ( size_t i = 0; i < namesCount; i++ ) {
@@ -42,7 +42,7 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent&
}
} else {
std::set<std::string> info;
getDirectoryFiles( mFiles, mNames, mPath, info, ignoreHidden );
getDirectoryFiles( mFiles, mNames, mPath, info, ignoreHidden, mIgnoreMatcher );
}
mIsReady = true;
#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN
@@ -120,15 +120,17 @@ void ProjectDirectoryTree::getDirectoryFiles( std::vector<std::string>& files,
std::vector<std::string>& names,
std::string directory,
std::set<std::string> currentDirs,
const bool& ignoreHidden ) {
const bool& ignoreHidden,
const IgnoreMatcherManager& ignoreMatcher ) {
currentDirs.insert( directory );
std::string localDirPath( directory.substr( mPath.size() ) );
std::string localDirPath( directory.substr(
ignoreMatcher.foundMatch() ? ignoreMatcher.getPath().size() : mPath.size() ) );
std::vector<std::string> pathFiles =
FileSystem::filesGetInPath( directory, false, false, ignoreHidden );
for ( auto& file : pathFiles ) {
std::string fullpath( directory + file );
std::string localpath( localDirPath + file );
if ( mIgnoreMatcher.foundMatch() && mIgnoreMatcher.match( localpath ) )
if ( ignoreMatcher.foundMatch() && ignoreMatcher.match( localpath ) )
continue;
if ( FileSystem::isDirectory( fullpath ) ) {
fullpath += FileSystem::getOSSlash();
@@ -139,7 +141,9 @@ void ProjectDirectoryTree::getDirectoryFiles( std::vector<std::string>& files,
if ( currentDirs.find( fullpath ) == currentDirs.end() )
continue;
}
getDirectoryFiles( files, names, fullpath, currentDirs, ignoreHidden );
IgnoreMatcherManager dirMatcher( fullpath );
getDirectoryFiles( files, names, fullpath, currentDirs, ignoreHidden,
dirMatcher.foundMatch() ? dirMatcher : ignoreMatcher );
} else {
files.emplace_back( fullpath );
names.emplace_back( file );

View File

@@ -75,7 +75,7 @@ class ProjectDirectoryTree {
void getDirectoryFiles( std::vector<std::string>& files, std::vector<std::string>& names,
std::string directory, std::set<std::string> currentDirs,
const bool& ignoreHidden );
const bool& ignoreHidden, const IgnoreMatcherManager& ignoreMatcher );
};
#endif // EE_TOOLS_PROJECTDIRECTORYTREE_HPP

View File

@@ -0,0 +1,50 @@
#include "uitreeviewglobalsearch.hpp"
UITreeViewGlobalSearch::UITreeViewGlobalSearch(const SyntaxColorScheme& colorScheme) :
UITreeView(), mColorScheme( colorScheme ) {
mLineNumColor = Color::fromString(
mUISceneNode->getRoot()->getUIStyle()->getVariable( "--font-hint" ).getValue() );
}
UIWidget* UITreeViewGlobalSearch::createCell(UIWidget* rowWidget, const ModelIndex& index) {
UITableCell* widget = index.column() == (Int64)getModel()->treeColumn()
? UITreeViewCellGlobalSearch::New()
: UITableCell::New();
return setupCell( widget, rowWidget, index );
}
UIPushButton* UITreeViewCellGlobalSearch::setText(const String& text) {
if ( text != mTextBox->getText() ) {
mTextBox->setVisible( !text.empty() );
mTextBox->setText( text );
updateText( text );
updateLayout();
}
return this;
}
UIPushButton* UITreeViewCellGlobalSearch::updateText(const String& text) {
if ( getCurIndex().internalId() != -1 ) {
UITreeViewGlobalSearch* pp = getParent()->getParent()->asType<UITreeViewGlobalSearch>();
ProjectSearch::ResultData* res = (ProjectSearch::ResultData*)getCurIndex().parent().data();
auto styleDef = SyntaxDefinitionManager::instance()->getStyleByExtension( res->file );
auto tokens =
SyntaxTokenizer::tokenize( styleDef, text, SYNTAX_TOKENIZER_STATE_NONE ).first;
size_t start = 0;
for ( auto& token : tokens ) {
mTextBox->setFontFillColor( pp->getColorScheme().getSyntaxStyle( token.type ).color,
start, start + token.text.size() );
start += token.text.size();
}
Uint32 from = text.find_first_not_of( ' ' );
if ( from != String::InvalidPos )
mTextBox->setFontFillColor( pp->getLineNumColor(), from,
text.find_first_of( ' ', from ) );
}
return this;
}

View File

@@ -0,0 +1,44 @@
#ifndef UITREEVIEWGLOBALSEARCH_HPP
#define UITREEVIEWGLOBALSEARCH_HPP
#include <eepp/ee.hpp>
#include "projectsearch.hpp"
class UITreeViewCellGlobalSearch : public UITreeViewCell {
public:
static UITreeViewCellGlobalSearch* New() { return eeNew( UITreeViewCellGlobalSearch, () ); }
UITreeViewCellGlobalSearch() : UITreeViewCell() {}
UIPushButton* setText( const String& text );
UIPushButton* updateText( const String& text );
};
class UITreeViewGlobalSearch : public UITreeView {
public:
static UITreeViewGlobalSearch* New( const SyntaxColorScheme& colorScheme ) {
return eeNew( UITreeViewGlobalSearch, ( colorScheme ) );
}
UITreeViewGlobalSearch( const SyntaxColorScheme& colorScheme );
UIWidget* createCell( UIWidget* rowWidget, const ModelIndex& index );
const SyntaxColorScheme& getColorScheme() const { return mColorScheme; }
const Color& getLineNumColor() const { return mLineNumColor; }
void updateColorScheme( const SyntaxColorScheme& colorScheme ) { mColorScheme = colorScheme; }
void setSearchStr( const String& searchStr ) { mSearchStr = searchStr; }
const String& getSearchStr() const { return mSearchStr; }
protected:
Color mLineNumColor;
SyntaxColorScheme mColorScheme;
String mSearchStr;
};
#endif // UITREEVIEWGLOBALSEARCH_HPP