diff --git a/include/eepp/ui/abstract/uiabstracttableview.hpp b/include/eepp/ui/abstract/uiabstracttableview.hpp index 1d2e1f8e3..a5330a87b 100644 --- a/include/eepp/ui/abstract/uiabstracttableview.hpp +++ b/include/eepp/ui/abstract/uiabstracttableview.hpp @@ -68,6 +68,8 @@ class EE_API UIAbstractTableView : public UIAbstractView { void moveSelection( int steps ); + void setSelection( const ModelIndex& index, bool scrollToSelection = true ); + const size_t& getIconSize() const; void setIconSize( const size_t& iconSize ); @@ -87,6 +89,8 @@ class EE_API UIAbstractTableView : public UIAbstractView { void setRowSearchByName( bool rowSearchByName ); + virtual ModelIndex findRowWithText( const std::string& text ); + protected: friend class EE::UI::UITableHeaderColumn; @@ -148,8 +152,6 @@ class EE_API UIAbstractTableView : public UIAbstractView { virtual Uint32 onTextInput( const TextInputEvent& event ); - virtual ModelIndex findRowWithText( const std::string& text ); - void updateHeaderSize(); int visibleColumn(); diff --git a/include/eepp/ui/uitableview.hpp b/include/eepp/ui/uitableview.hpp index 4a08d13db..ebd047e2e 100644 --- a/include/eepp/ui/uitableview.hpp +++ b/include/eepp/ui/uitableview.hpp @@ -21,6 +21,7 @@ class EE_API UITableView : public UIAbstractTableView { Float getMaxColumnContentWidth( const size_t& colIndex ); + virtual ModelIndex findRowWithText( const std::string& text ); protected: Sizef mContentSize; @@ -35,8 +36,6 @@ class EE_API UITableView : public UIAbstractTableView { void onColumnSizeChange( const size_t& ); virtual Uint32 onKeyDown( const KeyEvent& event ); - - virtual ModelIndex findRowWithText( const std::string& text ); }; }} // namespace EE::UI diff --git a/include/eepp/ui/uitreeview.hpp b/include/eepp/ui/uitreeview.hpp index 8d0f596cb..3c5a311d5 100644 --- a/include/eepp/ui/uitreeview.hpp +++ b/include/eepp/ui/uitreeview.hpp @@ -59,6 +59,8 @@ class EE_API UITreeView : public UIAbstractTableView { void setExpanderIconSize( const size_t& expanderSize ); + virtual ModelIndex findRowWithText( const std::string& text ); + protected: enum class IterationDecision { Continue, @@ -102,8 +104,6 @@ class EE_API UITreeView : public UIAbstractTableView { virtual void onSortColumn( const size_t& colIndex ); - virtual ModelIndex findRowWithText( const std::string& text ); - void updateContentSize(); void setAllExpanded( const ModelIndex& index = {}, bool expanded = true ); diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp index f98d5eeb9..9834622bb 100644 --- a/src/eepp/ui/abstract/uiabstracttableview.cpp +++ b/src/eepp/ui/abstract/uiabstracttableview.cpp @@ -392,10 +392,17 @@ void UIAbstractTableView::moveSelection( int steps ) { } else { newIndex = model.index( 0, 0 ); } - if ( model.isValid( newIndex ) ) { - getSelection().set( newIndex ); - scrollToPosition( {{mScrollOffset.x, getHeaderHeight() + newIndex.row() * getRowHeight()}, - {columnData( newIndex.column() ).width, getRowHeight()}} ); + setSelection( newIndex ); +} + +void UIAbstractTableView::setSelection( const ModelIndex& index, bool scrollToSelection ) { + if ( !getModel() ) + return; + auto& model = *this->getModel(); + if ( model.isValid( index ) && scrollToSelection ) { + getSelection().set( index ); + scrollToPosition( {{mScrollOffset.x, getHeaderHeight() + index.row() * getRowHeight()}, + {columnData( index.column() ).width, getRowHeight()}} ); } } diff --git a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp index 3e1f35783..f6247d999 100644 --- a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp +++ b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp @@ -180,7 +180,8 @@ SyntaxDefinitionManager::SyntaxDefinitionManager() { {"typeof", "keyword"}, {"undefined", "literal"}, {"var", "keyword"}, {"void", "keyword"}, {"while", "keyword"}, {"with", "keyword"}, {"yield", "keyword"}, {"implements", "keyword"}, {"Array", "keyword2"}, - {"any", "keyword"}, {"from", "keyword"}, {"public", "keyword"}}, + {"any", "keyword"}, {"from", "keyword"}, {"public", "keyword"}, + {"private", "keyword"}, {"declare", "keyword"}, {"namespace", "keyword"}}, "//"} ); // Python @@ -1750,6 +1751,30 @@ SyntaxDefinitionManager::SyntaxDefinitionManager() { {"null", "literal"}, }, "//"} ); + + // YAML + add( {"YAML", + {"%.yml$", "%.yaml$"}, + { + {{"^#.-\n"}, "comment"}, + {{"%s#.-\n"}, "comment"}, + {{"\"", "\"", "\\"}, "string"}, + {{"'", "'", "\\"}, "string"}, + {{"!!str", "\n", "\\"}, "string"}, + {{"%s-%-%s+.*\n"}, "keyword2"}, + {{"%s+[%w%s-_]+:%s+"}, "keyword"}, + {{"^[%w%s-_]+:%s+"}, "keyword"}, + {{"%f[%S]%-?0x%x+"}, "number"}, + {{"%f[%S]%-?%d+[%d%.eE]*f?"}, "number"}, + {{"%f[%S]%-?%.?%d+f?"}, "number"}, + {{"!!float", "\n", "\\"}, "number"}, + {{"https?://(([%w_.~!*:@&+$/?%%#-]-)(%w[-.%w]*%.)(%w%w%w?%w?)(:?)(%d*)(/" + "?)([%w_.~!*:@&+$/?%%#=-]*))"}, + "link"}, + {{"%-%-%-"}, "literal"}, + }, + {}, + "#"} ); } SyntaxDefinition& SyntaxDefinitionManager::add( SyntaxDefinition&& syntaxStyle ) { diff --git a/src/eepp/ui/uifiledialog.cpp b/src/eepp/ui/uifiledialog.cpp index c833ee825..edf749d37 100644 --- a/src/eepp/ui/uifiledialog.cpp +++ b/src/eepp/ui/uifiledialog.cpp @@ -252,6 +252,7 @@ void UIFileDialog::setCurPath( const std::string& path ) { mCurPath = path; FileSystem::dirAddSlashAtEnd( mCurPath ); mPath->setText( mCurPath ); + mFile->setText( "" ); refreshFolder(); } @@ -297,7 +298,11 @@ void UIFileDialog::openFileOrFolder() { } void UIFileDialog::goFolderUp() { + std::string prevFolderName( FileSystem::fileNameFromPath( mCurPath ) ); setCurPath( FileSystem::removeLastFolderFromPath( mCurPath ) ); + ModelIndex index = mList->findRowWithText( prevFolderName ); + if ( index.isValid() ) + mList->setSelection( index ); } Uint32 UIFileDialog::onMessage( const NodeMessage* Msg ) { diff --git a/src/eepp/ui/uitabwidget.cpp b/src/eepp/ui/uitabwidget.cpp index 913b290ec..36cb3d68a 100644 --- a/src/eepp/ui/uitabwidget.cpp +++ b/src/eepp/ui/uitabwidget.cpp @@ -593,11 +593,11 @@ UITab* UITabWidget::setTabSelected( UITab* tab ) { if ( tab->getOwnedWidget() ) tab->getOwnedWidget()->setFocus(); - Uint32 TabIndex = getTabIndex( tab ); + Uint32 tabIndex = getTabIndex( tab ); - if ( eeINDEX_NOT_FOUND != TabIndex ) { + if ( eeINDEX_NOT_FOUND != tabIndex ) { mTabSelected = tab; - mTabSelectedIndex = TabIndex; + mTabSelectedIndex = tabIndex; refreshOwnedWidget( mTabSelected ); @@ -689,6 +689,10 @@ void UITabWidget::swapTabs( UITab* left, UITab* right ) { Uint32 leftIndex = getTabIndex( left ); Uint32 rightIndex = getTabIndex( right ); if ( leftIndex != eeINDEX_NOT_FOUND && rightIndex != eeINDEX_NOT_FOUND ) { + if ( leftIndex == mTabSelectedIndex ) + mTabSelectedIndex = rightIndex; + else if ( rightIndex == mTabSelectedIndex ) + mTabSelectedIndex = leftIndex; mTabs[leftIndex] = right; mTabs[rightIndex] = left; posTabs(); diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index c67f534d1..dc4aa4f18 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -1498,15 +1498,22 @@ std::map App::getLocalKeybindings() { {{KEY_F, KEYMOD_CTRL}, "find-replace"}, {{KEY_Q, KEYMOD_CTRL}, "close-app"}, {{KEY_O, KEYMOD_CTRL}, "open-file"}, + {{KEY_O, KEYMOD_CTRL | KEYMOD_SHIFT}, "open-folder"}, {{KEY_F6, KEYMOD_NONE}, "debug-draw-highlight-toggle"}, {{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}, "open-global-search"}, {{KEY_L, KEYMOD_CTRL}, "go-to-line"}, + {{KEY_M, KEYMOD_CTRL}, "menu-toggle"}, }; } +std::vector App::getUnlockedCommands() { + return {"fullscreen-toggle", "open-file", "open-folder", "console-toggle", + "close-app", "open-locatebar", "open-global-search", "menu-toggle"}; +} + void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { const CodeEditorConfig& config = mConfig.editor; editor->setFontSize( config.fontSize.asDp( 0, Sizef(), mUISceneNode->getDPI() ) ); @@ -1534,8 +1541,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { doc.setBOM( config.writeUnicodeBOM ); editor->addKeyBinds( getLocalKeybindings() ); - editor->addUnlockedCommands( {"fullscreen-toggle", "open-file", "open-folder", "console-toggle", - "close-app", "open-locatebar", "open-global-search"} ); + editor->addUnlockedCommands( getUnlockedCommands() ); doc.setCommand( "save-doc", [&] { saveDoc(); } ); doc.setCommand( "save-as-doc", [&] { saveFileDialog(); } ); doc.setCommand( "find-replace", [&] { showFindView(); } ); @@ -1588,6 +1594,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { [&] { mUISceneNode->setDrawDebugData( !mUISceneNode->getDrawDebugData() ); } ); doc.setCommand( "go-to-line", [&] { goToLine(); } ); doc.setCommand( "load-current-dir", [&] { loadCurrentDirectory(); } ); + doc.setCommand( "menu-toggle", [&] { toggleSettingsMenu(); } ); editor->addEventListener( Event::OnSave, [&]( const Event* event ) { UICodeEditor* editor = event->getNode()->asType(); if ( editor->getDocument().getFilePath() == mKeybindingsPath ) { @@ -1663,6 +1670,19 @@ UIPopUpMenu* App::createToolsMenu() { return mToolsMenu; } +void App::toggleSettingsMenu() { + if ( ( !mSettingsMenu->isVisible() || mSettingsMenu->isHiding() ) && + mSettingsMenu->getInactiveTime().getElapsedTime().asMilliseconds() > 1 ) { + Vector2f pos( mSettingsButton->getPixelsPosition() ); + mSettingsButton->nodeToWorldTranslation( pos ); + UIMenu::findBestMenuPos( pos, mSettingsMenu ); + mSettingsMenu->setPixelsPosition( pos ); + mSettingsMenu->show(); + } else { + mSettingsMenu->hide(); + } +} + void App::createSettingsMenu() { mSettingsMenu = UIPopUpMenu::New(); mSettingsMenu->add( "New", findIcon( "document-new" ), getKeybind( "create-new" ) ); @@ -1688,18 +1708,8 @@ void App::createSettingsMenu() { mSettingsMenu->addSeparator(); mSettingsMenu->add( "Quit", findIcon( "quit" ), getKeybind( "close-app" ) ); mSettingsButton = mUISceneNode->find( "settings" ); - mSettingsButton->addEventListener( Event::MouseClick, [&]( const Event* ) { - if ( ( !mSettingsMenu->isVisible() || mSettingsMenu->isHiding() ) && - mSettingsMenu->getInactiveTime().getElapsedTime().asMilliseconds() > 1 ) { - Vector2f pos( mSettingsButton->getPixelsPosition() ); - mSettingsButton->nodeToWorldTranslation( pos ); - UIMenu::findBestMenuPos( pos, mSettingsMenu ); - mSettingsMenu->setPixelsPosition( pos ); - mSettingsMenu->show(); - } else { - mSettingsMenu->hide(); - } - } ); + mSettingsButton->addEventListener( Event::MouseClick, + [&]( const Event* ) { toggleSettingsMenu(); } ); mSettingsMenu->addEventListener( Event::OnItemClicked, [&]( const Event* event ) { if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) ) return; @@ -2090,49 +2100,45 @@ void App::init( const std::string& file, const Float& pidelDensity ) { UIIconTheme* iconTheme = UIIconTheme::New( "remixicon" ); mMenuIconSize = mConfig.ui.fontSize.asPixels( 0, Sizef(), mDisplayDPI ); - /*Float buttonIconSize = - StyleSheetLength::fromString( "16dp" ).asPixels( 0, Sizef(), mDisplayDPI );*/ - auto addIcon = [iconTheme, iconFont]( const std::string& name, - const Uint32& codePoint ) -> UIIcon* { - auto* icon = UIGlyphIcon::New( name, iconFont, codePoint ); - iconTheme->add( icon ); - return icon; + std::unordered_map icons = { + {"document-new", 0xecc3}, + {"document-open", 0xed70}, + {"document-save", 0xf0b3}, + {"document-save-as", 0xf0b3}, + {"document-close", 0xeb99}, + {"quit", 0xeb97}, + {"undo", 0xea58}, + {"redo", 0xea5a}, + {"cut", 0xf0c1}, + {"copy", 0xecd5}, + {"paste", 0xeb91}, + {"split-horizontal", 0xf17a}, + {"split-vertical", 0xf17b}, + {"find-replace", 0xed2b}, + {"folder", 0xed54}, + {"folder-open", 0xed70}, + {"folder-add", 0xed5a}, + {"file", 0xecc3}, + {"file-code", 0xecd1}, + {"file-edit", 0xecdb}, + {"font-size", 0xed8d}, + {"zoom-in", 0xf2db}, + {"zoom-out", 0xf2dd}, + {"zoom-reset", 0xeb47}, + {"fullscreen", 0xed9c}, + {"keybindings", 0xee75}, + {"tree-expanded", 0xea50}, + {"tree-contracted", 0xea54}, + {"search", 0xf0d1}, + {"go-up", 0xea78}, + {"ok", 0xeb7a}, + {"cancel", 0xeb98}, + {"color-picker", 0xf13d}, + {"pixel-density", 0xed8c}, + {"go-to-line", 0xf1f8}, }; - addIcon( "document-new", 0xecc3 ); - addIcon( "document-open", 0xed70 ); - addIcon( "document-save", 0xf0b3 ); - addIcon( "document-save-as", 0xf0b3 ); - addIcon( "document-close", 0xeb99 ); - addIcon( "quit", 0xeb97 ); - addIcon( "undo", 0xea58 ); - addIcon( "redo", 0xea5a ); - addIcon( "cut", 0xf0c1 ); - addIcon( "copy", 0xecd5 ); - addIcon( "paste", 0xeb91 ); - addIcon( "split-horizontal", 0xf17a ); - addIcon( "split-vertical", 0xf17b ); - addIcon( "find-replace", 0xed2b ); - addIcon( "folder", 0xed54 ); - addIcon( "folder-open", 0xed70 ); - addIcon( "folder-add", 0xed5a ); - addIcon( "file", 0xecc3 ); - addIcon( "file-code", 0xecd1 ); - addIcon( "file-edit", 0xecdb ); - addIcon( "font-size", 0xed8d ); - addIcon( "zoom-in", 0xf2db ); - addIcon( "zoom-out", 0xf2dd ); - addIcon( "zoom-reset", 0xeb47 ); - addIcon( "fullscreen", 0xed9c ); - addIcon( "keybindings", 0xee75 ); - addIcon( "tree-expanded", 0xea50 ); - addIcon( "tree-contracted", 0xea54 ); - addIcon( "search", 0xf0d1 ); - addIcon( "go-up", 0xea78 ); - addIcon( "ok", 0xeb7a ); - addIcon( "cancel", 0xeb98 ); - addIcon( "color-picker", 0xf13d ); - addIcon( "pixel-density", 0xed8c ); - addIcon( "go-to-line", 0xf1f8 ); + for ( auto icon : icons ) + iconTheme->add( UIGlyphIcon::New( icon.first, iconFont, icon.second ) ); mUISceneNode->getUIIconThemeManager()->setCurrentTheme( iconTheme ); diff --git a/src/tools/codeeditor/codeeditor.hpp b/src/tools/codeeditor/codeeditor.hpp index 34f4b9004..1282a8c9d 100644 --- a/src/tools/codeeditor/codeeditor.hpp +++ b/src/tools/codeeditor/codeeditor.hpp @@ -207,6 +207,8 @@ class App : public UICodeEditorSplitter::Client { std::string getKeybind( const std::string& command ); + std::vector getUnlockedCommands(); + protected: EE::Window::Window* mWindow{nullptr}; UISceneNode* mUISceneNode{nullptr}; @@ -362,6 +364,8 @@ class App : public UICodeEditorSplitter::Client { void goToLine(); void loadCurrentDirectory(); + + void toggleSettingsMenu(); }; #endif // EE_TOOLS_CODEEDITOR_HPP