From 19e2aba3bae4b7e8fb42dfd7a102ce5aa596c3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 12 Sep 2022 01:38:11 -0300 Subject: [PATCH] ecode: Added Terminal menu. --- docs/articles/cssspecification.md | 4 ++ .../eepp/ui/tools/uicodeeditorsplitter.hpp | 6 +++ include/eepp/ui/uidatabind.hpp | 6 +++ src/eepp/ui/css/stylesheetspecification.cpp | 6 ++- src/eepp/ui/tools/uicodeeditorsplitter.cpp | 32 ++++++++++++ src/tools/ecode/ecode.cpp | 49 ++++++++++++++++++- src/tools/ecode/ecode.hpp | 7 ++- src/tools/ecode/terminalmanager.cpp | 6 ++- 8 files changed, 110 insertions(+), 6 deletions(-) diff --git a/docs/articles/cssspecification.md b/docs/articles/cssspecification.md index 96f2e107d..e5e87f680 100644 --- a/docs/articles/cssspecification.md +++ b/docs/articles/cssspecification.md @@ -1283,6 +1283,7 @@ Sets the element rotation in degrees. * Applicable to: Any element * Data Type: [number](#number-data-type) * Default value: `0` +* Aliases: `rotate` --- @@ -1293,6 +1294,7 @@ Sets the x-axis rotation origin point relative to the element expressed as a len * Applicable to: Any element * Data Type: [length-percentage](#length-percentage-data-type) * Default value: `center` +* Aliases: `rotate-origin-point-x` Syntax: @@ -1311,6 +1313,7 @@ Sets the y-axis rotation origin point relative to the element expressed as a len * Applicable to: Any element * Data Type: [length-percentage](#length-percentage-data-type) * Default value: `center` +* Aliases: `rotate-origin-point-y` Syntax: @@ -2154,6 +2157,7 @@ Read [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) documen The origin point of the rotation expressed as a [position](#position-data-type). Default value: `center center`. +Aliases: `rotate-origin-point` Syntax: diff --git a/include/eepp/ui/tools/uicodeeditorsplitter.hpp b/include/eepp/ui/tools/uicodeeditorsplitter.hpp index 040836ed5..25cd48500 100644 --- a/include/eepp/ui/tools/uicodeeditorsplitter.hpp +++ b/include/eepp/ui/tools/uicodeeditorsplitter.hpp @@ -118,6 +118,12 @@ class EE_API UICodeEditorSplitter { void applyColorScheme( const SyntaxColorScheme& colorScheme ); + void forEachWidgetType( const UINodeType& nodeType, + std::function run ) const; + + void forEachWidgetTypeStoppable( const UINodeType& nodeType, + std::function run ) const; + void forEachWidgetStoppable( std::function run ) const; void forEachWidget( std::function run ) const; diff --git a/include/eepp/ui/uidatabind.hpp b/include/eepp/ui/uidatabind.hpp index 63a4112cc..9ca532172 100644 --- a/include/eepp/ui/uidatabind.hpp +++ b/include/eepp/ui/uidatabind.hpp @@ -87,6 +87,8 @@ template class UIDataBind { *data = t; setValueChange(); inSetValue = false; + if ( onValueChangeCb ) + onValueChangeCb( t ); } const T& get() const { return *data; } @@ -127,6 +129,8 @@ template class UIDataBind { const PropertyDefinition* getPropertyDefinition() const { return property; } + std::function onValueChangeCb; + protected: T* data{ nullptr }; std::set widgets; @@ -172,6 +176,8 @@ template class UIDataBind { widget->applyProperty( prop ); } inSetValue = false; + if ( onValueChangeCb ) + onValueChangeCb( val ); } } diff --git a/src/eepp/ui/css/stylesheetspecification.cpp b/src/eepp/ui/css/stylesheetspecification.cpp index f0302f4b2..b317a3d34 100644 --- a/src/eepp/ui/css/stylesheetspecification.cpp +++ b/src/eepp/ui/css/stylesheetspecification.cpp @@ -158,12 +158,14 @@ void StyleSheetSpecification::registerDefaultProperties() { registerProperty( "layout-to-top-of", "" ).addAlias( "layout_to_top_of" ); registerProperty( "layout-to-bottom-of", "" ).addAlias( "layout_to_bottom_of" ); registerProperty( "clip", "" ).setType( PropertyType::String ); - registerProperty( "rotation", "" ).setType( PropertyType::NumberFloat ); + registerProperty( "rotation", "" ).addAlias( "rotate" ).setType( PropertyType::NumberFloat ); registerProperty( "scale", "" ).setType( PropertyType::Vector2 ); registerProperty( "rotation-origin-point-x", "50%" ) + .addAlias( "rotate-origin-point-x" ) .setRelativeTarget( PropertyRelativeTarget::LocalBlockWidth ) .setType( PropertyType::NumberLength ); registerProperty( "rotation-origin-point-y", "50%" ) + .addAlias( "rotate-origin-point-y" ) .setRelativeTarget( PropertyRelativeTarget::LocalBlockHeight ) .setType( PropertyType::NumberLength ); registerProperty( "scale-origin-point-x", "50%" ) @@ -414,6 +416,8 @@ void StyleSheetSpecification::registerDefaultProperties() { "radius" ); registerShorthand( "rotation-origin-point", { "rotation-origin-point-x", "rotation-origin-point-y" }, "vector2" ); + registerShorthand( "rotate-origin-point", + { "rotation-origin-point-x", "rotation-origin-point-y" }, "vector2" ); registerShorthand( "scale-origin-point", { "scale-origin-point-x", "scale-origin-point-y" }, "vector2" ); registerShorthand( "min-size", { "min-width", "min-height" }, "vector2" ); diff --git a/src/eepp/ui/tools/uicodeeditorsplitter.cpp b/src/eepp/ui/tools/uicodeeditorsplitter.cpp index a0430ad21..f2c4824f1 100644 --- a/src/eepp/ui/tools/uicodeeditorsplitter.cpp +++ b/src/eepp/ui/tools/uicodeeditorsplitter.cpp @@ -600,6 +600,38 @@ void UICodeEditorSplitter::applyColorScheme( const SyntaxColorScheme& colorSchem mClient->onColorSchemeChanged( mCurrentColorScheme ); } +void UICodeEditorSplitter::forEachWidgetType( const UINodeType& nodeType, + std::function run ) const { + Node* node; + UIWidget* widget; + for ( auto tabWidget : mTabWidgets ) { + for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) { + node = tabWidget->getTab( i )->getOwnedWidget(); + if ( node && node->isWidget() ) { + widget = node->asType(); + if ( widget->isType( nodeType ) ) + run( widget ); + } + } + } +} + +void UICodeEditorSplitter::forEachWidgetTypeStoppable( + const UINodeType& nodeType, std::function run ) const { + Node* node; + UIWidget* widget; + for ( auto tabWidget : mTabWidgets ) { + for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) { + node = tabWidget->getTab( i )->getOwnedWidget(); + if ( node && node->isWidget() ) { + widget = node->asType(); + if ( widget->isType( nodeType ) && run( widget ) ) + return; + } + } + } +} + void UICodeEditorSplitter::forEachEditor( std::function run ) const { for ( auto tabWidget : mTabWidgets ) for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) { diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 3b1be3ce7..ffb8c4e3b 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1215,6 +1215,33 @@ makeAutoClosePairs( const std::string& strPairs ) { return pairs; } +UIMenu* App::createTerminalMenu() { + mTerminalMenu = UIPopUpMenu::New(); + + UIMenuCheckBox* exclusiveChk = + mTerminalMenu->addCheckBox( i18n( "exclusive_mode", "Exclusive Mode" ), false, + getKeybind( UITerminal::getExclusiveModeToggleCommandName() ) ); + exclusiveChk + ->setTooltipText( + i18n( "exclusive_mode_tooltip", + "Global Keybindings are disabled when exclusive mode is enabled.\nThis is to " + "avoid keyboard shortcut overlapping between the terminal an the application." ) ) + ->setId( "exclusive-mode" ); + + mTerminalMenu->addEventListener( Event::OnItemClicked, [&]( const Event* event ) { + const std::string& id( event->getNode()->getId() ); + if ( "exclusive-mode" == id ) { + if ( mSplitter->getCurWidget() && + mSplitter->getCurWidget()->isType( UI_TYPE_TERMINAL ) ) { + mSplitter->getCurWidget()->asType()->setExclusiveMode( + event->getNode()->asType()->isActive() ); + } + } + } ); + + return mTerminalMenu; +} + UIMenu* App::createDocumentMenu() { auto shouldCloseCb = []( UIMenuItem* ) -> bool { return false; }; @@ -1749,6 +1776,17 @@ void App::updateProjectSettingsMenu() { ->setActive( mProjectDocConfig.useGlobalSettings ); } +void App::updateTerminalMenu() { + bool enabled = + mSplitter->getCurWidget() && mSplitter->getCurWidget()->isType( UI_TYPE_TERMINAL ); + mSettingsMenu->getItemId( "term-menu" )->setEnabled( enabled ); + if ( !enabled ) + return; + mTerminalMenu->getItemId( "exclusive-mode" ) + ->asType() + ->setActive( mSplitter->getCurWidget()->asType()->getExclusiveMode() ); +} + void App::updateDocumentMenu() { if ( !mSplitter->getCurWidget() || !mSplitter->getCurWidget()->isType( UI_TYPE_CODEEDITOR ) ) { mSettingsMenu->getItemId( "doc-menu" )->setEnabled( false ); @@ -1986,9 +2024,12 @@ void App::onWidgetFocusChange( UIWidget* widget ) { mDocInfo->setVisible( widget && widget->isType( UI_TYPE_CODEEDITOR ) ); updateDocumentMenu(); + updateTerminalMenu(); if ( widget && !widget->isType( UI_TYPE_CODEEDITOR ) ) { if ( widget->isType( UI_TYPE_TERMINAL ) ) setAppTitle( widget->asType()->getTitle() ); + else + setAppTitle( "" ); } } @@ -2698,8 +2739,12 @@ void App::createSettingsMenu() { mTerminalManager->updateMenuColorScheme( termColorSchemeMenu ); } ); #endif - mSettingsMenu->addSubMenu( i18n( "document", "Document" ), nullptr, createDocumentMenu() ) + mSettingsMenu + ->addSubMenu( i18n( "document", "Document" ), findIcon( "file" ), createDocumentMenu() ) ->setId( "doc-menu" ); + mSettingsMenu + ->addSubMenu( i18n( "terminal", "Terminal" ), findIcon( "terminal" ), createTerminalMenu() ) + ->setId( "term-menu" ); mSettingsMenu->addSubMenu( i18n( "edit", "Edit" ), nullptr, createEditMenu() ); mSettingsMenu->addSubMenu( i18n( "view", "View" ), nullptr, createViewMenu() ); mSettingsMenu->addSubMenu( i18n( "tools", "Tools" ), nullptr, createToolsMenu() ); @@ -2992,7 +3037,7 @@ void App::createProjectTreeMenu() { } else if ( "open_folder" == id ) { Engine::instance()->openURI( mCurrentProject ); } else if ( "execute_dir_in_terminal" == id ) { - mTerminalManager->createNewTerminal( "", nullptr, mCurrentProject ); + mTerminalManager->createNewTerminal(); } else if ( "show_hidden_files" == id ) { toggleHiddenFiles(); } else if ( "collapse-all" == id ) { diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 7e5dad426..d91148bd6 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -140,6 +140,10 @@ class App : public UICodeEditorSplitter::Client { void updatedReopenClosedFileState(); + void updateDocumentMenu(); + + void updateTerminalMenu(); + protected: EE::Window::Window* mWindow{ nullptr }; UISceneNode* mUISceneNode{ nullptr }; @@ -162,6 +166,7 @@ class App : public UICodeEditorSplitter::Client { std::vector mRecentFolders; AppConfig mConfig; UIPopUpMenu* mDocMenu{ nullptr }; + UIPopUpMenu* mTerminalMenu{ nullptr }; UIPopUpMenu* mViewMenu{ nullptr }; UIPopUpMenu* mWindowMenu{ nullptr }; UIPopUpMenu* mRendererMenu{ nullptr }; @@ -276,7 +281,7 @@ class App : public UICodeEditorSplitter::Client { UIMenu* createDocumentMenu(); - void updateDocumentMenu(); + UIMenu* createTerminalMenu(); void loadKeybindings(); diff --git a/src/tools/ecode/terminalmanager.cpp b/src/tools/ecode/terminalmanager.cpp index e4b6dbecd..1e650332b 100644 --- a/src/tools/ecode/terminalmanager.cpp +++ b/src/tools/ecode/terminalmanager.cpp @@ -298,8 +298,10 @@ UITerminal* TerminalManager::createNewTerminal( const std::string& title, UITabW mApp->getSplitter()->splitterFromWidget( mApp->getSplitter()->getCurWidget() ) ) splitter->swap(); } ); - term->setCommand( UITerminal::getExclusiveModeToggleCommandName(), - [term] { term->setExclusiveMode( !term->getExclusiveMode() ); } ); + term->setCommand( UITerminal::getExclusiveModeToggleCommandName(), [term, this] { + term->setExclusiveMode( !term->getExclusiveMode() ); + mApp->updateTerminalMenu(); + } ); term->setCommand( "create-new-terminal", [&] { createNewTerminal(); } ); term->setCommand( "terminal-rename", [&, term] { UIMessageBox* msgBox = UIMessageBox::New(