From 91a9a97dc5042ea5da25913adc76e0dac31d25e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 6 Aug 2020 00:50:19 -0300 Subject: [PATCH] Some minor improvements to ecode and general minor fixes. --- include/eepp/scene/node.hpp | 6 +- include/eepp/ui/uicodeeditor.hpp | 1 + include/eepp/ui/uiscenenode.hpp | 3 + src/eepp/scene/node.cpp | 12 +-- src/eepp/ui/tools/uicodeeditorsplitter.cpp | 2 +- src/eepp/ui/uicodeeditor.cpp | 25 +++--- src/eepp/ui/uiscenenode.cpp | 4 + src/tools/codeeditor/codeeditor.cpp | 100 ++++++++++++++------- src/tools/codeeditor/codeeditor.hpp | 22 +++-- src/tools/codeeditor/projectsearch.hpp | 5 ++ 10 files changed, 124 insertions(+), 56 deletions(-) diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp index 093de3cf5..6960d6508 100644 --- a/include/eepp/scene/node.hpp +++ b/include/eepp/scene/node.hpp @@ -394,11 +394,11 @@ class EE_API Node : public Transformable { virtual void nodeDraw(); - void forceKeyDown( const KeyEvent& event ); + Uint32 forceKeyDown( const KeyEvent& event ); - void foceKeyUp( const KeyEvent& event ); + Uint32 foceKeyUp( const KeyEvent& event ); - void forceTextInput( const TextInputEvent& Event ); + Uint32 forceTextInput( const TextInputEvent& Event ); protected: typedef std::map> EventsMap; diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index de237b217..d13fa28ae 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -363,6 +363,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { void setColorPreview( bool colorPreview ); + void goToLine( const TextPosition& position ); protected: struct LastXOffset { TextPosition position; diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index 2141da136..f8218872a 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -15,6 +15,7 @@ namespace EE { namespace UI { class UIThemeManager; class UIIconThemeManager; +class UIEventDispatcher; class UIWidget; class UIWindow; class UIWidget; @@ -127,6 +128,8 @@ class EE_API UISceneNode : public SceneNode { void executeKeyBindingCommand( const std::string& command ); + UIEventDispatcher* getUIEventDispatcher() const; + protected: friend class EE::UI::UIWindow; friend class EE::UI::UIWidget; diff --git a/src/eepp/scene/node.cpp b/src/eepp/scene/node.cpp index 6a37d3607..40386a64a 100644 --- a/src/eepp/scene/node.cpp +++ b/src/eepp/scene/node.cpp @@ -530,16 +530,16 @@ void Node::nodeDraw() { } } -void Node::forceKeyDown( const KeyEvent& event ) { - onKeyDown( event ); +Uint32 Node::forceKeyDown( const KeyEvent& event ) { + return onKeyDown( event ); } -void Node::foceKeyUp( const KeyEvent& event ) { - onKeyUp( event ); +Uint32 Node::foceKeyUp( const KeyEvent& event ) { + return onKeyUp( event ); } -void Node::forceTextInput( const TextInputEvent& event ) { - onTextInput( event ); +Uint32 Node::forceTextInput( const TextInputEvent& event ) { + return onTextInput( event ); } void Node::clipStart() { diff --git a/src/eepp/ui/tools/uicodeeditorsplitter.cpp b/src/eepp/ui/tools/uicodeeditorsplitter.cpp index ace0ac304..de7041fe5 100644 --- a/src/eepp/ui/tools/uicodeeditorsplitter.cpp +++ b/src/eepp/ui/tools/uicodeeditorsplitter.cpp @@ -20,7 +20,7 @@ const std::map UICodeEditorSplitter::getLocalDefaultKeybindings() { return { {{KEY_S, KEYMOD_CTRL}, "save-doc"}, - {{KEY_L, KEYMOD_CTRL}, "lock-toggle"}, + {{KEY_L, KEYMOD_CTRL | KEYMOD_SHIFT}, "lock-toggle"}, {{KEY_T, KEYMOD_CTRL}, "create-new"}, {{KEY_W, KEYMOD_CTRL}, "close-doc"}, {{KEY_TAB, KEYMOD_CTRL}, "next-doc"}, diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index bf5403e70..626378f2e 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -649,45 +649,45 @@ Uint32 UICodeEditor::onFocusLoss() { Uint32 UICodeEditor::onTextInput( const TextInputEvent& event ) { if ( mLocked || NULL == mFont ) - return 1; + return 0; Input* input = getUISceneNode()->getWindow()->getInput(); if ( ( input->isLeftAltPressed() && !event.getText().empty() && event.getText()[0] == '\t' ) || ( input->isLeftAltPressed() && input->isShiftPressed() ) || input->isControlPressed() ) - return 1; + return 0; mDoc->textInput( event.getText() ); for ( auto& module : mModules ) if ( module->onTextInput( this, event ) ) - return 0; + return 1; - return 1; + return 0; } Uint32 UICodeEditor::onKeyDown( const KeyEvent& event ) { - if ( NULL == mFont ) - return 1; + if ( NULL == mFont || mUISceneNode->getUIEventDispatcher()->justGainedFocus() ) + return 0; for ( auto& module : mModules ) if ( module->onKeyDown( this, event ) ) - return 0; + return 1; std::string cmd = mKeyBindings.getCommandFromKeyBind( {event.getKeyCode(), event.getMod()} ); if ( !cmd.empty() ) { // Allow copy selection on locked mode if ( !mLocked || mUnlockedCmd.find( cmd ) != mUnlockedCmd.end() ) { mDoc->execute( cmd ); - return 0; + return 1; } } - return 1; + return 0; } Uint32 UICodeEditor::onKeyUp( const KeyEvent& event ) { for ( auto& module : mModules ) if ( module->onKeyUp( this, event ) ) - return 0; + return 1; return UIWidget::onKeyUp( event ); } @@ -943,6 +943,11 @@ void UICodeEditor::updateScrollBar() { setScrollY( mScroll.y ); } +void UICodeEditor::goToLine( const TextPosition& position ) { + mDoc->setSelection( position ); + scrollToMakeVisible( mDoc->getSelection().start() ); +} + void UICodeEditor::updateEditor() { mDoc->setPageSize( getVisibleLinesCount() ); if ( mDoc->getActiveClient() == this ) diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 9be5c8e41..6cf19ee12 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -845,4 +845,8 @@ void UISceneNode::executeKeyBindingCommand( const std::string& command ) { } } +UIEventDispatcher* UISceneNode::getUIEventDispatcher() const { + return static_cast( mEventDispatcher ); +} + }} // namespace EE::UI diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index d10484440..2dd106485 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -406,6 +406,23 @@ void App::updateLocateTable() { mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); } +bool App::trySendUnlockedCmd( const KeyEvent& keyEvent ) { + if ( mEditorSplitter->getCurEditor() ) { + std::string cmd = mEditorSplitter->getCurEditor()->getKeyBindings().getCommandFromKeyBind( + {keyEvent.getKeyCode(), keyEvent.getMod()} ); + if ( !cmd.empty() && mEditorSplitter->getCurEditor()->isUnlockedCommand( cmd ) ) { + mEditorSplitter->getCurEditor()->getDocument().execute( cmd ); + return true; + } + } + return false; +} + +void App::goToLine() { + showLocateBar(); + mLocateInput->setText( "l " ); +} + void App::initLocateBar() { auto addClickListener = [&]( UIWidget* widget, std::string cmd ) { widget->addEventListener( Event::MouseClick, [this, cmd]( const Event* event ) { @@ -420,19 +437,30 @@ void App::initLocateBar() { mLocateTable->setHeadersVisible( false ); mLocateTable->setVisible( false ); mLocateInput->addEventListener( Event::OnTextChanged, [&]( const Event* ) { - Vector2f pos( mLocateInput->convertToWorldSpace( {0, 0} ) ); - pos.y -= mLocateTable->getPixelsSize().getHeight(); - mLocateTable->setPixelsPosition( pos ); - if ( !mDirTreeReady ) - return; - updateLocateTable(); + if ( mEditorSplitter->getCurEditor() && + String::startsWith( mLocateInput->getText(), String( "l " ) ) ) { + String number( mLocateInput->getText().substr( 2 ) ); + Int64 val; + if ( String::fromString( val, number ) && val - 1 >= 0 ) { + mEditorSplitter->getCurEditor()->goToLine( {val - 1, 0} ); + mLocateTable->setVisible( false ); + } + } else { + mLocateTable->setVisible( true ); + Vector2f pos( mLocateInput->convertToWorldSpace( {0, 0} ) ); + pos.y -= mLocateTable->getPixelsSize().getHeight(); + mLocateTable->setPixelsPosition( pos ); + if ( !mDirTreeReady ) + return; + updateLocateTable(); + } } ); mLocateInput->addEventListener( Event::OnPressEnter, [&]( const Event* ) { KeyEvent keyEvent( mLocateTable, Event::KeyDown, KEY_RETURN, 0, 0 ); mLocateTable->forceKeyDown( keyEvent ); } ); mLocateInput->addEventListener( Event::KeyDown, [&]( const Event* event ) { - const KeyEvent* keyEvent = reinterpret_cast( event ); + const KeyEvent* keyEvent = static_cast( event ); mLocateTable->forceKeyDown( *keyEvent ); } ); mLocateBarLayout->addCommand( "close-locatebar", [&] { @@ -443,7 +471,7 @@ void App::initLocateBar() { {"escape", "close-locatebar"}, } ); mLocateTable->addEventListener( Event::KeyDown, [&]( const Event* event ) { - const KeyEvent* keyEvent = reinterpret_cast( event ); + const KeyEvent* keyEvent = static_cast( event ); if ( keyEvent->getKeyCode() == KEY_ESCAPE ) mLocateBarLayout->execute( "close-locatebar" ); } ); @@ -495,6 +523,7 @@ void App::showLocateBar() { mLocateBarLayout->setVisible( true ); mLocateInput->setFocus(); mLocateTable->setVisible( true ); + mLocateInput->getDocument().selectAll(); mLocateInput->addEventListener( Event::OnSizeChange, [&]( const Event* ) { updateLocateBar(); } ); if ( mDirTree && !mLocateTable->getModel() ) { @@ -590,6 +619,7 @@ void App::showGlobalSearch() { mGlobalSearchBarLayout->setVisible( true )->setEnabled( true ); mGlobalSearchInput->setFocus(); mGlobalSearchTree->setVisible( true ); + mGlobalSearchInput->getDocument().selectAll(); updateGlobalSearchBar(); } @@ -623,9 +653,6 @@ void App::initGlobalSearchBar() { UICheckBox* caseSensitiveBox = mGlobalSearchBarLayout->find( "case_sensitive" ); UIWidget* searchBarClose = mGlobalSearchBarLayout->find( "global_searchbar_close" ); mGlobalSearchInput = mGlobalSearchBarLayout->find( "global_search_find" ); - mGlobalSearchInput->addEventListener( Event::OnPressEnter, [this]( const Event* ) { - mGlobalSearchBarLayout->execute( "search-in-files" ); - } ); mGlobalSearchBarLayout->addCommand( "search-in-files", [&, caseSensitiveBox] { if ( mDirTree && mDirTree->getFilesCount() > 0 && !mGlobalSearchInput->getText().empty() ) { UILoader* loader = UILoader::New(); @@ -668,12 +695,20 @@ void App::initGlobalSearchBar() { {"escape", "close-global-searchbar"}, } ); mGlobalSearchInput->addEventListener( Event::OnPressEnter, [&]( const Event* ) { - KeyEvent keyEvent( mGlobalSearchTree, Event::KeyDown, KEY_RETURN, 0, 0 ); - mGlobalSearchTree->forceKeyDown( keyEvent ); + if ( mGlobalSearchInput->hasFocus() ) { + mGlobalSearchBarLayout->execute( "search-in-files" ); + } else { + KeyEvent keyEvent( mGlobalSearchTree, Event::KeyDown, KEY_RETURN, 0, 0 ); + mGlobalSearchTree->forceKeyDown( keyEvent ); + } } ); mGlobalSearchInput->addEventListener( Event::KeyDown, [&]( const Event* event ) { - const KeyEvent* keyEvent = reinterpret_cast( event ); - mGlobalSearchTree->forceKeyDown( *keyEvent ); + const KeyEvent* keyEvent = static_cast( event ); + Uint32 keyCode = keyEvent->getKeyCode(); + if ( ( keyCode == KEY_UP || keyCode == KEY_DOWN ) && + mGlobalSearchTree->forceKeyDown( *keyEvent ) && !mGlobalSearchTree->hasFocus() ) { + mGlobalSearchTree->setFocus(); + } } ); addClickListener( searchButton, "search-in-files" ); addClickListener( searchBarClose, "close-global-searchbar" ); @@ -685,7 +720,7 @@ void App::initGlobalSearchBar() { mGlobalSearchTree->setColumnsHidden( {ProjectSearch::ResultModel::Line, ProjectSearch::ResultModel::ColumnPosition}, true ); mGlobalSearchTree->addEventListener( Event::KeyDown, [&]( const Event* event ) { - const KeyEvent* keyEvent = reinterpret_cast( event ); + const KeyEvent* keyEvent = static_cast( event ); if ( keyEvent->getKeyCode() == KEY_ESCAPE ) mGlobalSearchBarLayout->execute( "close-global-searchbar" ); } ); @@ -695,9 +730,9 @@ void App::initGlobalSearchBar() { const Model* model = modelEvent->getModel(); if ( !model ) return; - Variant vPath( - model->data( model->index( modelEvent->getModelIndex().internalId(), - ProjectSearch::ResultModel::FileOrPosition ) ) ); + Variant vPath( model->data( model->index( modelEvent->getModelIndex().internalId(), + ProjectSearch::ResultModel::FileOrPosition ), + Model::Role::Custom ) ); if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) ) { std::string path( vPath.asCStr() ); UITab* tab = mEditorSplitter->isDocumentOpen( path ); @@ -722,6 +757,7 @@ void App::initGlobalSearchBar() { lineNum.is( Variant::Type::Int64 ) && colNum.is( Variant::Type::Int64 ) ) { mEditorSplitter->getCurEditor()->getDocument().setSelection( {lineNum.asInt64(), colNum.asInt64()} ); + hideGlobalSearchBar(); } } } @@ -1451,7 +1487,8 @@ std::map App::getLocalKeybindings() { {{KEY_F7, KEYMOD_NONE}, "debug-draw-boxes-toggle"}, {{KEY_F8, KEYMOD_NONE}, "debug-draw-debug-data"}, {{KEY_K, KEYMOD_CTRL}, "open-locatebar"}, - {{KEY_F, KEYMOD_CTRL | KEYMOD_SHIFT}, "global-find"}, + {{KEY_F, KEYMOD_CTRL | KEYMOD_SHIFT}, "open-global-search"}, + {{KEY_L, KEYMOD_CTRL}, "go-to-line"}, }; } @@ -1483,11 +1520,11 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { editor->addKeyBinds( getLocalKeybindings() ); editor->addUnlockedCommands( {"fullscreen-toggle", "open-file", "open-folder", "console-toggle", - "close-app", "open-locatebar"} ); + "close-app", "open-locatebar", "open-global-search"} ); doc.setCommand( "save-doc", [&] { saveDoc(); } ); doc.setCommand( "save-as-doc", [&] { saveFileDialog(); } ); doc.setCommand( "find-replace", [&] { showFindView(); } ); - doc.setCommand( "global-find", [&] { showGlobalSearch(); } ); + doc.setCommand( "open-global-search", [&] { showGlobalSearch(); } ); doc.setCommand( "open-locatebar", [&] { showLocateBar(); } ); doc.setCommand( "repeat-find", [&] { findNextText( mSearchState ); } ); doc.setCommand( "close-app", [&] { closeApp(); } ); @@ -1534,7 +1571,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { } ); doc.setCommand( "debug-draw-debug-data", [&] { mUISceneNode->setDrawDebugData( !mUISceneNode->getDrawDebugData() ); } ); - + doc.setCommand( "go-to-line", [&] { goToLine(); } ); editor->addEventListener( Event::OnSave, [&]( const Event* event ) { UICodeEditor* editor = event->getNode()->asType(); if ( editor->getDocument().getFilePath() == mKeybindingsPath ) { @@ -1576,7 +1613,8 @@ bool App::setAutoComplete( bool enable ) { UIPopUpMenu* App::createToolsMenu() { mToolsMenu = UIPopUpMenu::New(); mToolsMenu->add( "Locate...", findIcon( "search" ), getKeybind( "open-locatebar" ) ); - mToolsMenu->add( "Project Find...", findIcon( "search" ), getKeybind( "global-find" ) ); + mToolsMenu->add( "Project Find...", findIcon( "search" ), getKeybind( "open-global-search" ) ); + mToolsMenu->add( "Go to line...", findIcon( "go-to-line" ), getKeybind( "go-to-line" ) ); mToolsMenu->addEventListener( Event::OnItemClicked, [&]( const Event* event ) { if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) ) return; @@ -1585,6 +1623,8 @@ UIPopUpMenu* App::createToolsMenu() { showLocateBar(); } else if ( item->getText() == "Project Find..." ) { showGlobalSearch(); + } else if ( item->getText() == "Go to line..." ) { + goToLine(); } } ); return mToolsMenu; @@ -1758,7 +1798,7 @@ void App::initProjectTreeView( const std::string& path ) { } } ); mProjectTreeView->addEventListener( Event::KeyDown, [&]( const Event* event ) { - const KeyEvent* keyEvent = reinterpret_cast( event ); + const KeyEvent* keyEvent = static_cast( event ); if ( mEditorSplitter->getCurEditor() ) { std::string cmd = mEditorSplitter->getCurEditor()->getKeyBindings().getCommandFromKeyBind( @@ -1990,7 +2030,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) { - + @@ -2053,6 +2093,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) { addIcon( "cancel", 0xeb98, buttonIconSize ); addIcon( "color-picker", 0xf13d, buttonIconSize ); addIcon( "pixel-density", 0xed8c, buttonIconSize ); + addIcon( "go-to-line", 0xf1f8, buttonIconSize ); addIcon( "tree-expanded", 0xea50, PixelDensity::dpToPx( 24 ) ); addIcon( "tree-contracted", 0xea54, PixelDensity::dpToPx( 24 ) ); addIcon( "search", 0xf0d1, menuIconSize ); @@ -2073,6 +2114,9 @@ void App::init( const std::string& file, const Float& pidelDensity ) { mUISceneNode->bind( "panel", mSidePanel ); mUISceneNode->bind( "project_splitter", mProjectSplitter ); mUISceneNode->bind( "locate_find", mLocateInput ); + mUISceneNode->addEventListener( Event::KeyDown, [&]( const Event* event ) { + trySendUnlockedCmd( *static_cast( event ) ); + } ); mDocInfo->setVisible( mConfig.editor.showDocInfo ); mSearchBarLayout->setVisible( false )->setEnabled( false ); mGlobalSearchBarLayout->setVisible( false )->setEnabled( false ); @@ -2096,10 +2140,6 @@ void App::init( const std::string& file, const Float& pidelDensity ) { mEditorSplitter->createEditorWithTabWidget( mBaseLayout ); - std::string locateKeybind( getKeybind( "open-locatebar" ) ); - if ( !locateKeybind.empty() ) - mLocateInput->setHint( "Type to locate (" + locateKeybind + ")" ); - mConsole = eeNew( Console, ( fontMono, true, true, 1024 * 1000, 0, mWindow ) ); initProjectTreeView( file ); diff --git a/src/tools/codeeditor/codeeditor.hpp b/src/tools/codeeditor/codeeditor.hpp index ace7faf03..e8b2954b7 100644 --- a/src/tools/codeeditor/codeeditor.hpp +++ b/src/tools/codeeditor/codeeditor.hpp @@ -11,6 +11,8 @@ class UISearchBar : public UILinearLayout { UISearchBar() : UILinearLayout( "searchbar", UIOrientation::Horizontal ), mKeyBindings( 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 ); @@ -29,10 +31,10 @@ class UISearchBar : public UILinearLayout { auto cmdIt = mCommands.find( cmd ); if ( cmdIt != mCommands.end() ) { cmdIt->second(); - return 0; + return 1; } } - return 1; + return 0; } }; @@ -43,6 +45,8 @@ class UILocateBar : public UILinearLayout { UILocateBar() : UILinearLayout( "locatebar", UIOrientation::Horizontal ), mKeyBindings( 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 ); @@ -61,10 +65,10 @@ class UILocateBar : public UILinearLayout { auto cmdIt = mCommands.find( cmd ); if ( cmdIt != mCommands.end() ) { cmdIt->second(); - return 0; + return 1; } } - return 1; + return 0; } }; @@ -75,6 +79,8 @@ class UIGlobalSearchBar : public UILinearLayout { UIGlobalSearchBar() : UILinearLayout( "globalsearchbar", UIOrientation::Vertical ), mKeyBindings( 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 ); @@ -93,10 +99,10 @@ class UIGlobalSearchBar : public UILinearLayout { auto cmdIt = mCommands.find( cmd ); if ( cmdIt != mCommands.end() ) { cmdIt->second(); - return 0; + return 1; } } - return 1; + return 0; } }; @@ -349,6 +355,10 @@ class App : public UICodeEditorSplitter::Client { void hideSearchBar(); void hideLocateBar(); + + bool trySendUnlockedCmd( const KeyEvent& keyEvent ); + + void goToLine(); }; #endif // EE_TOOLS_CODEEDITOR_HPP diff --git a/src/tools/codeeditor/projectsearch.hpp b/src/tools/codeeditor/projectsearch.hpp index 9eeab87cd..7ad7a9657 100644 --- a/src/tools/codeeditor/projectsearch.hpp +++ b/src/tools/codeeditor/projectsearch.hpp @@ -101,6 +101,11 @@ class ProjectSearch { .results[index.row()] .position.column() ); } + } else { + switch ( index.column() ) { + case FileOrPosition: + return Variant( mResult[index.row()].file.c_str() ); + } } } return Variant( EMPTY );