From 353988f292d8517e5ff21f5d0aa3caad098d36d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 23 Feb 2023 00:02:01 -0300 Subject: [PATCH] eepp: Fixed an issue in UINodeDrawable that was breaking the color tint of the drawables in some cases. Fixed an issue when using clipping mask that prevented the batched geometry to be rendered. Added border-smooth and background-smooth properties (I'm not sure if I'm gonna use them yet). ecode: Closes SpartanJ/ecode#59. Fixed a minor issue when dropping SVG files into the editor, they weren't being opened in a new tab. Added Solidity LSP support using solc. --- bin/assets/plugins/lspclient.json | 7 + include/eepp/graphics/primitivedrawable.hpp | 7 + include/eepp/graphics/renderer/renderer.hpp | 9 +- include/eepp/ui/css/propertydefinition.hpp | 2 + include/eepp/ui/uibackgrounddrawable.hpp | 5 + include/eepp/ui/uiborderdrawable.hpp | 6 + src/eepp/graphics/primitivedrawable.cpp | 27 +++- src/eepp/graphics/renderer/clippingmask.cpp | 4 + src/eepp/graphics/renderer/renderer.cpp | 25 +++- src/eepp/ui/css/drawableimageparser.cpp | 6 +- src/eepp/ui/css/stylesheetspecification.cpp | 3 + src/eepp/ui/uibackgrounddrawable.cpp | 17 +++ src/eepp/ui/uiborderdrawable.cpp | 17 +++ src/eepp/ui/uinodedrawable.cpp | 2 +- src/eepp/ui/uiwidget.cpp | 135 +++++++++++--------- src/eepp/ui/uiwidgetcreator.cpp | 5 + src/tools/ecode/appconfig.cpp | 82 ++++++------ src/tools/ecode/appconfig.hpp | 14 +- src/tools/ecode/ecode.cpp | 93 ++++++++------ src/tools/ecode/ecode.hpp | 3 + 20 files changed, 315 insertions(+), 154 deletions(-) diff --git a/bin/assets/plugins/lspclient.json b/bin/assets/plugins/lspclient.json index 4a93edb09..179f9fad4 100644 --- a/bin/assets/plugins/lspclient.json +++ b/bin/assets/plugins/lspclient.json @@ -183,6 +183,13 @@ "url": "https://github.com/eclipse/eclipse.jdt.ls", "command": "jdtls", "file_patterns": ["%.java$"] + }, + { + "language": "solidity", + "name": "solc", + "url": "https://soliditylang.org", + "command": "solc --lsp", + "file_patterns": ["%.sol$"] } ] } diff --git a/include/eepp/graphics/primitivedrawable.hpp b/include/eepp/graphics/primitivedrawable.hpp index fc2d2feeb..33b33d788 100644 --- a/include/eepp/graphics/primitivedrawable.hpp +++ b/include/eepp/graphics/primitivedrawable.hpp @@ -32,6 +32,12 @@ class EE_API PrimitiveDrawable : public Drawable { /** @return The line with to draw primitives */ const Float& getLineWidth() const; + /** @return True if polygon and line smoothing is enabled */ + bool isSmooth() const; + + /** Enables/Disables polygon and line smoothing */ + void setSmooth( bool smooth ); + protected: PrimitiveDrawable( Type drawableType ); @@ -40,6 +46,7 @@ class EE_API PrimitiveDrawable : public Drawable { Float mLineWidth; bool mNeedsUpdate; bool mRecreateVertexBuffer; + bool mSmooth{ false }; VertexBuffer* mVertexBuffer; virtual void onAlphaChange(); diff --git a/include/eepp/graphics/renderer/renderer.hpp b/include/eepp/graphics/renderer/renderer.hpp index e15988885..74e95343e 100644 --- a/include/eepp/graphics/renderer/renderer.hpp +++ b/include/eepp/graphics/renderer/renderer.hpp @@ -117,6 +117,13 @@ class EE_API Renderer { bool isLineSmooth(); + void polygonSmooth( const bool& enable ); + + /** Reapply the polygon smooth state */ + void polygonSmooth(); + + bool isPolygonSmooth(); + /** Set the polygon fill mode ( wireframe or filled ) */ void polygonMode( const PrimitiveFillMode& Mode ); @@ -271,7 +278,7 @@ class EE_API Renderer { protected: static Renderer* sSingleton; - enum RendererStateFlags { RSF_LINE_SMOOTH = 0, RSF_POLYGON_MODE }; + enum RendererStateFlags { RSF_LINE_SMOOTH = 0, RSF_POLYGON_MODE, RSF_POLYGON_SMOOTH }; Uint32 mExtensions; Uint32 mStateFlags; diff --git a/include/eepp/ui/css/propertydefinition.hpp b/include/eepp/ui/css/propertydefinition.hpp index 4909f7959..8e3a32216 100644 --- a/include/eepp/ui/css/propertydefinition.hpp +++ b/include/eepp/ui/css/propertydefinition.hpp @@ -196,6 +196,8 @@ enum class PropertyId : Uint32 { BorderTopRightRadius = String::hash( "border-top-right-radius" ), BorderBottomLeftRadius = String::hash( "border-bottom-left-radius" ), BorderBottomRightRadius = String::hash( "border-bottom-right-radius" ), + BorderSmooth = String::hash( "border-smooth" ), + BackgroundSmooth = String::hash( "background-smooth" ), TabBarHideOnSingleTab = String::hash( "tabbar-hide-on-single-tab" ), TabBarAllowRearrange = String::hash( "tabbar-allow-rearrange" ), TabBarAllowDragAndDrop = String::hash( "tabbar-allow-drag-and-drop-tabs" ), diff --git a/include/eepp/ui/uibackgrounddrawable.hpp b/include/eepp/ui/uibackgrounddrawable.hpp index 684608a4e..b1957e1d1 100644 --- a/include/eepp/ui/uibackgrounddrawable.hpp +++ b/include/eepp/ui/uibackgrounddrawable.hpp @@ -56,6 +56,10 @@ class EE_API UIBackgroundDrawable : public Drawable { void setBottomRightRadius( const std::string& radius ); + bool isSmooth() const; + + void setSmooth( bool smooth ); + protected: const UINode* mOwner; BorderRadiuseStr mRadiusesStr; @@ -65,6 +69,7 @@ class EE_API UIBackgroundDrawable : public Drawable { bool mNeedsUpdate; bool mNeedsRadiusUpdate; bool mColorNeedsUpdate; + bool mSmooth{ false }; virtual void onAlphaChange(); diff --git a/include/eepp/ui/uiborderdrawable.hpp b/include/eepp/ui/uiborderdrawable.hpp index 042f16b1d..f6dd03d05 100644 --- a/include/eepp/ui/uiborderdrawable.hpp +++ b/include/eepp/ui/uiborderdrawable.hpp @@ -2,6 +2,7 @@ #define EE_UI_UIBORDERDRAWABLE_HPP #include +#include #include namespace EE { namespace UI { @@ -80,6 +81,10 @@ class EE_API UIBorderDrawable : public Drawable { Rectf getBorderBoxDiff() const; + bool isSmooth() const; + + void setSmooth( bool smooth ); + protected: const UINode* mOwner; VertexBuffer* mVertexBuffer; @@ -90,6 +95,7 @@ class EE_API UIBorderDrawable : public Drawable { bool mNeedsUpdate; bool mColorNeedsUpdate; bool mHasBorder; + bool mSmooth{ false }; virtual void onAlphaChange(); diff --git a/src/eepp/graphics/primitivedrawable.cpp b/src/eepp/graphics/primitivedrawable.cpp index 9d950cdf5..f324e18e3 100644 --- a/src/eepp/graphics/primitivedrawable.cpp +++ b/src/eepp/graphics/primitivedrawable.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace EE { namespace Graphics { @@ -17,7 +18,7 @@ PrimitiveDrawable::~PrimitiveDrawable() { eeSAFE_DELETE( mVertexBuffer ); } -void PrimitiveDrawable::draw( const Vector2f& position, const Sizef& size ) { +void PrimitiveDrawable::draw( const Vector2f& position, const Sizef& ) { if ( mPosition != position ) { mPosition = position; mNeedsUpdate = true; @@ -29,6 +30,14 @@ void PrimitiveDrawable::draw( const Vector2f& position, const Sizef& size ) { if ( NULL != mVertexBuffer ) { BatchRenderer* BR = GlobalBatchRenderer::instance(); + bool isPolySmooth = GLi->isPolygonSmooth(); + bool isLineSmooth = GLi->isLineSmooth(); + + if ( mSmooth ) { + GLi->polygonSmooth( true ); + GLi->lineSmooth( true ); + } + BR->draw(); Float lw = BR->getLineWidth(); @@ -39,6 +48,14 @@ void PrimitiveDrawable::draw( const Vector2f& position, const Sizef& size ) { mVertexBuffer->unbind(); BR->setLineWidth( lw ); + + if ( mSmooth ) { + if ( !isPolySmooth ) + GLi->polygonSmooth( isPolySmooth ); + + if ( !isLineSmooth ) + GLi->lineSmooth( isLineSmooth ); + } } } @@ -68,6 +85,14 @@ const Float& PrimitiveDrawable::getLineWidth() const { return mLineWidth; } +bool PrimitiveDrawable::isSmooth() const { + return mSmooth; +} + +void PrimitiveDrawable::setSmooth( bool smooth ) { + mSmooth = smooth; +} + void PrimitiveDrawable::onAlphaChange() { mNeedsUpdate = true; } diff --git a/src/eepp/graphics/renderer/clippingmask.cpp b/src/eepp/graphics/renderer/clippingmask.cpp index 3767ef3a2..45a4f2cf8 100644 --- a/src/eepp/graphics/renderer/clippingmask.cpp +++ b/src/eepp/graphics/renderer/clippingmask.cpp @@ -118,6 +118,8 @@ void ClippingMask::setMaskMode( Mode theMode ) { } void ClippingMask::stencilMaskEnable() { + GlobalBatchRenderer::instance()->draw(); + GLi->enable( GL_STENCIL_TEST ); GLi->stencilMask( 0xFF ); GLi->stencilFunc( GL_NEVER, 1, 0xFF ); @@ -132,6 +134,8 @@ void ClippingMask::stencilMaskEnable() { void ClippingMask::stencilMaskDisable( bool clearMasks ) { GLi->disable( GL_STENCIL_TEST ); + GlobalBatchRenderer::instance()->draw(); + if ( clearMasks ) this->clearMasks(); } diff --git a/src/eepp/graphics/renderer/renderer.cpp b/src/eepp/graphics/renderer/renderer.cpp index 4a27a63e3..189867c74 100644 --- a/src/eepp/graphics/renderer/renderer.cpp +++ b/src/eepp/graphics/renderer/renderer.cpp @@ -520,6 +520,27 @@ bool Renderer::isLineSmooth() { return BitOp::readBitKey( &mStateFlags, RSF_LINE_SMOOTH ); } +void Renderer::polygonSmooth( const bool& Enable ) { +#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN && defined( GL_POLYGON_SMOOTH ) && \ + !defined( EE_GLES1 ) && !defined( EE_GLES2 ) && !defined( EE_GLES_BOTH ) + if ( Enable ) { + enable( GL_POLYGON_SMOOTH ); + } else { + disable( GL_POLYGON_SMOOTH ); + } + + BitOp::writeBitKey( &mStateFlags, RSF_POLYGON_SMOOTH, Enable ? 1 : 0 ); +#endif +} + +void Renderer::polygonSmooth() { + polygonSmooth( isPolygonSmooth() ); +} + +bool Renderer::isPolygonSmooth() { + return BitOp::readBitKey( &mStateFlags, RSF_POLYGON_SMOOTH ); +} + void Renderer::lineSmooth() { lineSmooth( isLineSmooth() ); } @@ -527,9 +548,9 @@ void Renderer::lineSmooth() { void Renderer::lineSmooth( const bool& Enable ) { #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN if ( Enable ) { - GLi->enable( GL_LINE_SMOOTH ); + enable( GL_LINE_SMOOTH ); } else { - GLi->disable( GL_LINE_SMOOTH ); + disable( GL_LINE_SMOOTH ); } BitOp::writeBitKey( &mStateFlags, RSF_LINE_SMOOTH, Enable ? 1 : 0 ); diff --git a/src/eepp/ui/css/drawableimageparser.cpp b/src/eepp/ui/css/drawableimageparser.cpp index 373f22a15..c799c2a16 100644 --- a/src/eepp/ui/css/drawableimageparser.cpp +++ b/src/eepp/ui/css/drawableimageparser.cpp @@ -122,9 +122,11 @@ void DrawableImageParser::registerBaseParsers() { if ( params.size() >= 3 ) { std::string fillMode( String::toLower( params[2] ) ); - if ( fillMode == "line" || fillMode == "solid" || fillMode == "fill" ) { + if ( fillMode == "line" || fillMode == "solid" || fillMode == "fill" ) drawable->setFillMode( fillMode == "line" ? DRAW_LINE : DRAW_FILL ); - } + + if ( params.size() >= 4 && params[3] == "smooth" ) + drawable->setSmooth( true ); } drawable->setOffset( drawable->getSize() / 2.f ); diff --git a/src/eepp/ui/css/stylesheetspecification.cpp b/src/eepp/ui/css/stylesheetspecification.cpp index 2e40901e2..8b3b193e8 100644 --- a/src/eepp/ui/css/stylesheetspecification.cpp +++ b/src/eepp/ui/css/stylesheetspecification.cpp @@ -369,6 +369,9 @@ void StyleSheetSpecification::registerDefaultProperties() { registerProperty( "border-bottom-left-radius", "0" ).setType( PropertyType::RadiusLength ); registerProperty( "border-bottom-right-radius", "0" ).setType( PropertyType::RadiusLength ); + registerProperty( "border-smooth", "false" ).setType( PropertyType::Bool ); + registerProperty( "background-smooth", "false" ).setType( PropertyType::Bool ); + registerProperty( "tabbar-hide-on-single-tab", "false" ); registerProperty( "tabbar-allow-rearrange", "false" ); registerProperty( "tabbar-allow-drag-and-drop-tabs", "false" ); diff --git a/src/eepp/ui/uibackgrounddrawable.cpp b/src/eepp/ui/uibackgrounddrawable.cpp index 0ae1ec988..2c7c52df8 100644 --- a/src/eepp/ui/uibackgrounddrawable.cpp +++ b/src/eepp/ui/uibackgrounddrawable.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -45,9 +46,17 @@ void UIBackgroundDrawable::draw( const Vector2f& position, const Sizef& size ) { } if ( hasRadius() && mVertexBuffer ) { + bool isPolySmooth = GLi->isPolygonSmooth(); + + if ( mSmooth ) + GLi->polygonSmooth( true ); + mVertexBuffer->bind(); mVertexBuffer->draw(); mVertexBuffer->unbind(); + + if ( mSmooth && !isPolySmooth ) + GLi->polygonSmooth( isPolySmooth ); } else { Primitives primitives; primitives.setColor( getColor() ); @@ -119,6 +128,14 @@ void UIBackgroundDrawable::setBottomRightRadius( const std::string& radius ) { } } +bool UIBackgroundDrawable::isSmooth() const { + return mSmooth; +} + +void UIBackgroundDrawable::setSmooth( bool smooth ) { + mSmooth = smooth; +} + Int32 UIBackgroundDrawable::getRadius() const { return mRadiuses.topLeft.x; } diff --git a/src/eepp/ui/uiborderdrawable.cpp b/src/eepp/ui/uiborderdrawable.cpp index 5f1899d08..37acb9452 100644 --- a/src/eepp/ui/uiborderdrawable.cpp +++ b/src/eepp/ui/uiborderdrawable.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -47,9 +48,17 @@ void UIBorderDrawable::draw( const Vector2f& position, const Sizef& size ) { } if ( mHasBorder ) { + bool isPolySmooth = GLi->isPolygonSmooth(); + + if ( mSmooth ) + GLi->polygonSmooth( true ); + mVertexBuffer->bind(); mVertexBuffer->draw(); mVertexBuffer->unbind(); + + if ( mSmooth && !isPolySmooth ) + GLi->polygonSmooth( isPolySmooth ); } } @@ -263,6 +272,14 @@ Rectf UIBorderDrawable::getBorderBoxDiff() const { return bd; } +bool UIBorderDrawable::isSmooth() const { + return mSmooth; +} + +void UIBorderDrawable::setSmooth( bool smooth ) { + mSmooth = smooth; +} + void UIBorderDrawable::update() { updateBorders(); diff --git a/src/eepp/ui/uinodedrawable.cpp b/src/eepp/ui/uinodedrawable.cpp index e95c6fedb..632fb77f1 100644 --- a/src/eepp/ui/uinodedrawable.cpp +++ b/src/eepp/ui/uinodedrawable.cpp @@ -310,7 +310,7 @@ void UINodeDrawable::LayerDrawable::draw( const Vector2f& position, const Sizef& if ( mNeedsUpdate ) update(); - RGB prevColor = getColorFilter(); + RGB prevColor = mDrawable->getColorFilter(); if ( mColorWasSet ) mDrawable->setColorFilter( getColor() ); mDrawable->setAlpha( getAlpha() ); diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index 436ee0991..2608f42ee 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -1138,68 +1138,68 @@ std::vector UIWidget::querySelectorAll( const std::string& selector ) } std::vector UIWidget::getPropertiesImplemented() const { - return { - PropertyId::X, - PropertyId::Y, - PropertyId::Width, - PropertyId::Height, - PropertyId::MarginLeft, - PropertyId::MarginTop, - PropertyId::MarginRight, - PropertyId::MarginBottom, - PropertyId::PaddingLeft, - PropertyId::PaddingTop, - PropertyId::PaddingRight, - PropertyId::PaddingBottom, - PropertyId::BackgroundColor, - PropertyId::BackgroundTint, - PropertyId::ForegroundColor, - PropertyId::ForegroundTint, - PropertyId::ForegroundRadius, - PropertyId::BorderType, - PropertyId::SkinColor, - PropertyId::Rotation, - PropertyId::Scale, - PropertyId::Opacity, - PropertyId::Cursor, - PropertyId::Visible, - PropertyId::Enabled, - PropertyId::Theme, - PropertyId::Skin, - PropertyId::Flags, - PropertyId::BackgroundSize, - PropertyId::ForegroundSize, - PropertyId::LayoutWeight, - PropertyId::LayoutGravity, - PropertyId::LayoutWidth, - PropertyId::LayoutHeight, - PropertyId::Clip, - PropertyId::BackgroundPositionX, - PropertyId::BackgroundPositionY, - PropertyId::ForegroundPositionX, - PropertyId::ForegroundPositionY, - PropertyId::RotationOriginPointX, - PropertyId::RotationOriginPointY, - PropertyId::ScaleOriginPointX, - PropertyId::ScaleOriginPointY, - PropertyId::BlendMode, - PropertyId::MinWidth, - PropertyId::MaxWidth, - PropertyId::MinHeight, - PropertyId::MaxHeight, - PropertyId::BorderLeftColor, - PropertyId::BorderTopColor, - PropertyId::BorderRightColor, - PropertyId::BorderBottomColor, - PropertyId::BorderLeftWidth, - PropertyId::BorderTopWidth, - PropertyId::BorderRightWidth, - PropertyId::BorderBottomWidth, - PropertyId::BorderTopLeftRadius, - PropertyId::BorderTopRightRadius, - PropertyId::BorderBottomLeftRadius, - PropertyId::BorderBottomRightRadius, - }; + return { PropertyId::X, + PropertyId::Y, + PropertyId::Width, + PropertyId::Height, + PropertyId::MarginLeft, + PropertyId::MarginTop, + PropertyId::MarginRight, + PropertyId::MarginBottom, + PropertyId::PaddingLeft, + PropertyId::PaddingTop, + PropertyId::PaddingRight, + PropertyId::PaddingBottom, + PropertyId::BackgroundColor, + PropertyId::BackgroundTint, + PropertyId::ForegroundColor, + PropertyId::ForegroundTint, + PropertyId::ForegroundRadius, + PropertyId::BorderType, + PropertyId::SkinColor, + PropertyId::Rotation, + PropertyId::Scale, + PropertyId::Opacity, + PropertyId::Cursor, + PropertyId::Visible, + PropertyId::Enabled, + PropertyId::Theme, + PropertyId::Skin, + PropertyId::Flags, + PropertyId::BackgroundSize, + PropertyId::ForegroundSize, + PropertyId::LayoutWeight, + PropertyId::LayoutGravity, + PropertyId::LayoutWidth, + PropertyId::LayoutHeight, + PropertyId::Clip, + PropertyId::BackgroundPositionX, + PropertyId::BackgroundPositionY, + PropertyId::ForegroundPositionX, + PropertyId::ForegroundPositionY, + PropertyId::RotationOriginPointX, + PropertyId::RotationOriginPointY, + PropertyId::ScaleOriginPointX, + PropertyId::ScaleOriginPointY, + PropertyId::BlendMode, + PropertyId::MinWidth, + PropertyId::MaxWidth, + PropertyId::MinHeight, + PropertyId::MaxHeight, + PropertyId::BorderLeftColor, + PropertyId::BorderTopColor, + PropertyId::BorderRightColor, + PropertyId::BorderBottomColor, + PropertyId::BorderLeftWidth, + PropertyId::BorderTopWidth, + PropertyId::BorderRightWidth, + PropertyId::BorderBottomWidth, + PropertyId::BorderTopLeftRadius, + PropertyId::BorderTopRightRadius, + PropertyId::BorderBottomLeftRadius, + PropertyId::BorderBottomRightRadius, + PropertyId::BorderSmooth, + PropertyId::BackgroundSmooth }; } std::string UIWidget::getPropertyString( const std::string& property ) const { @@ -1340,6 +1340,12 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef, return String::format( "%.2fpx %.2fpx", setBorderEnabled( true )->getBorders().radius.bottomRight.x, getBorder()->getBorders().radius.bottomRight.y ); + case PropertyId::BorderSmooth: + return mBorder ? ( mBorder->isSmooth() ? "true" : "false" ) : "false"; + case PropertyId::BackgroundSmooth: + return mBackground + ? ( mBackground->getBackgroundDrawable().isSmooth() ? "true" : "false" ) + : "false"; default: break; } @@ -1736,6 +1742,11 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::BorderBottomRightRadius: setBottomRightRadius( attribute.asString() ); break; + case PropertyId::BorderSmooth: + setBorderEnabled( true )->setSmooth( attribute.asBool() ); + case PropertyId::BackgroundSmooth: + setBackgroundFillEnabled( true )->getBackgroundDrawable().setSmooth( + attribute.asBool() ); default: attributeSet = false; break; diff --git a/src/eepp/ui/uiwidgetcreator.cpp b/src/eepp/ui/uiwidgetcreator.cpp index 5b1b7ea1f..0cc14f0e9 100644 --- a/src/eepp/ui/uiwidgetcreator.cpp +++ b/src/eepp/ui/uiwidgetcreator.cpp @@ -91,6 +91,10 @@ void UIWidgetCreator::createBaseWidgetList() { registeredWidget["listview"] = UIListView::New; registeredWidget["stackwidget"] = UIStackWidget::New; registeredWidget["console"] = UIConsole::New; + registeredWidget["menu"] = UIMenu::New; + registeredWidget["menucheckbox"] = UIMenuCheckBox::New; + registeredWidget["menuradiobutton"] = UIMenuRadioButton::New; + registeredWidget["menuseparator"] = UIMenuSeparator::New; registeredWidget["hbox"] = UILinearLayout::NewHorizontal; registeredWidget["vbox"] = UILinearLayout::NewVertical; @@ -106,6 +110,7 @@ void UIWidgetCreator::createBaseWidgetList() { registeredWidget["rlay"] = UIRelativeLayout::New; registeredWidget["tooltip"] = UITooltip::New; + sBaseListCreated = true; } } diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index 2a657ece4..8a438c48f 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -6,7 +6,6 @@ #include #include #include -#include using namespace EE::Network; using namespace eterm::UI; @@ -368,16 +367,43 @@ void AppConfig::saveProject( std::string projectFolder, UICodeEditorSplitter* ed ini.writeFile(); } -static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr pool, - json j, UITabWidget* curTabWidget, ecode::App* app ) { +static void countTotalEditors( json j, size_t& curTotal ) { + if ( j["type"] == "tabwidget" ) { + for ( const auto& file : j["files"] ) + if ( !file.contains( "type" ) || file["type"] == "editor" ) + curTotal++; + } else if ( j["type"] == "splitter" ) { + countTotalEditors( j["first"], curTotal ); + countTotalEditors( j["last"], curTotal ); + } +} + +static int countTotalEditors( json j ) { + size_t total = 0; + countTotalEditors( j, total ); + return total; +} + +void AppConfig::editorLoadedCounter( ecode::App* app ) { + editorsToLoad--; + if ( editorsToLoad <= 0 ) { + app->getUISceneNode()->runOnMainThread( [app] { app->loadFileDelayed(); } ); + } +} + +void AppConfig::loadDocuments( UICodeEditorSplitter* editorSplitter, + std::shared_ptr pool, json j, UITabWidget* curTabWidget, + ecode::App* app ) { if ( j["type"] == "tabwidget" ) { Int64 currentPage = j["current_page"]; size_t totalToLoad = j["files"].size(); for ( const auto& file : j["files"] ) { if ( !file.contains( "type" ) || file["type"] == "editor" ) { std::string path( file["path"] ); - if ( !FileSystem::fileExists( path ) ) + if ( !FileSystem::fileExists( path ) ) { + editorLoadedCounter( app ); return; + } TextRanges selection( TextRanges::fromString( file["selection"] ) ); UITab* tab = nullptr; if ( ( tab = editorSplitter->isDocumentOpen( path, false, true ) ) != nullptr ) { @@ -394,11 +420,13 @@ static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr if ( curTabWidget->getTabCount() == totalToLoad ) curTabWidget->setTabSelected( eeclamp( currentPage, 0, curTabWidget->getTabCount() - 1 ) ); + + editorLoadedCounter( app ); } else { editorSplitter->loadAsyncFileFromPathInNewTab( path, pool, - [curTabWidget, selection, totalToLoad, currentPage]( UICodeEditor* editor, - const std::string& ) { + [this, curTabWidget, selection, totalToLoad, currentPage, + app]( UICodeEditor* editor, const std::string& ) { if ( !editor->getDocument().getSelection().isValid() || editor->getDocument().getSelection() == TextRange( { 0, 0 }, { 0, 0 } ) ) { @@ -408,6 +436,8 @@ static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr if ( curTabWidget->getTabCount() == totalToLoad ) curTabWidget->setTabSelected( eeclamp( currentPage, 0, curTabWidget->getTabCount() - 1 ) ); + + editorLoadedCounter( app ); }, curTabWidget ); } @@ -460,12 +490,6 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed docConfig.doc.indentSpaces = ini.getValueB( "document", "indent_spaces", false ); docConfig.doc.lineEndings = TextDocument::stringToLineEnding( ini.getValue( "document", "line_endings", "LF" ) ); - // Migrate old data - if ( ini.keyValueExists( "document", "windows_line_endings" ) && - !ini.keyValueExists( "document", "line_endings" ) && - ini.getValueB( "document", "windows_line_endings" ) == true ) { - docConfig.doc.lineEndings = TextDocument::LineEnding::CRLF; - } docConfig.doc.tabWidth = eemax( 2, ini.getValueI( "document", "tab_width", 4 ) ); docConfig.doc.lineBreakingColumn = @@ -481,40 +505,10 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed } if ( j.is_discarded() ) return; + + editorsToLoad = countTotalEditors( j ); loadDocuments( editorSplitter, pool, j, editorSplitter->tabWidgetFromWidget( editorSplitter->getCurWidget() ), app ); - } else { - // Old format - bool found; - size_t i = 0; - std::vector paths; - do { - std::string val( ini.getValue( "files", String::format( "file_name_%zu", i ) ) ); - found = !val.empty(); - if ( found ) { - auto pp = ProjectPath::fromString( val ); - if ( FileSystem::fileExists( pp.path ) ) - paths.emplace_back( pp ); - } - i++; - } while ( found ); - - Int64 currentPage = ini.getValueI( "files", "current_page" ); - size_t totalToLoad = paths.size(); - - for ( auto& pp : paths ) { - editorSplitter->loadAsyncFileFromPathInNewTab( - pp.path, pool, - [pp, editorSplitter, totalToLoad, currentPage]( UICodeEditor* editor, - const std::string& ) { - editor->getDocument().setSelection( pp.selection ); - editor->scrollToCursor(); - - if ( !editorSplitter->getTabWidgets().empty() && - editorSplitter->getTabWidgets()[0]->getTabCount() == totalToLoad ) - editorSplitter->switchToTab( currentPage ); - } ); - } } } diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index 181a45016..d3dc63f2a 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -8,6 +8,9 @@ #include #include +#include +using json = nlohmann::json; + using namespace EE; using namespace EE::Math; using namespace EE::UI; @@ -112,7 +115,8 @@ struct WorkspaceConfig { bool checkForUpdatesAtStartup{ false }; }; -struct AppConfig { +class AppConfig { + public: WindowStateConfig windowState; ContextSettings context; CodeEditorConfig editor; @@ -144,6 +148,14 @@ struct AppConfig { void loadProject( std::string projectFolder, UICodeEditorSplitter* editorSplitter, const std::string& configPath, ProjectDocumentConfig& docConfig, std::shared_ptr pool, ecode::App* app ); + + protected: + Int64 editorsToLoad{ 0 }; + + void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr pool, + json j, UITabWidget* curTabWidget, ecode::App* app ); + + void editorLoadedCounter( ecode::App* app ); }; } // namespace ecode diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 2bcf186b8..c3b1baf30 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -564,8 +564,8 @@ void App::onFileDropped( String file ) { if ( node && node->isType( UI_TYPE_CODEEDITOR ) ) { codeEditor = node->asType(); if ( ( codeEditor->getDocument().isLoading() || !codeEditor->getDocument().isEmpty() ) && - !Image::isImageExtension( file ) && - FileSystem::fileExtension( file.toUtf8() ) != "svg" ) { + ( !Image::isImageExtension( file ) || + FileSystem::fileExtension( file.toUtf8() ) == "svg" ) ) { auto d = mSplitter->createCodeEditorInTabWidget( mSplitter->tabWidgetFromEditor( codeEditor ) ); codeEditor = d.second; @@ -573,7 +573,8 @@ void App::onFileDropped( String file ) { } } else if ( widget && widget->isType( UI_TYPE_TERMINAL ) ) { if ( !Image::isImageExtension( file ) && - FileSystem::fileExtension( file.toUtf8() ) != "svg" ) { + ( !Image::isImageExtension( file ) || + FileSystem::fileExtension( file.toUtf8() ) == "svg" ) ) { auto d = mSplitter->createCodeEditorInTabWidget( mSplitter->tabWidgetFromWidget( widget ) ); codeEditor = d.second; @@ -1434,6 +1435,46 @@ void App::cleanUpRecentFiles() { mRecentFiles = recentFiles; } +void App::loadFileDelayed() { + if ( mFileToOpen.empty() ) + return; + + auto fileAndPos = getPathAndPosition( mFileToOpen ); + auto tab = mSplitter->isDocumentOpen( fileAndPos.first, false, true ); + + if ( tab ) { + tab->getTabWidget()->setTabSelected( tab ); + if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) { + UICodeEditor* editor = tab->getOwnedWidget()->asType(); + if ( editor->getDocument().isLoading() ) { + Uint32 cb = + editor->on( Event::OnDocumentLoaded, [fileAndPos]( const Event* event ) { + if ( event->getNode()->isType( UI_TYPE_CODEEDITOR ) ) { + UICodeEditor* editor = event->getNode()->asType(); + editor->runOnMainThread( + [editor, fileAndPos] { editor->goToLine( fileAndPos.second ); } ); + } + event->getNode()->removeEventListener( event->getCallbackId() ); + } ); + // Don't listen forever if no event is received + editor->runOnMainThread( [editor, cb]() { editor->removeEventListener( cb ); }, + Seconds( 4 ) ); + } else { + editor->runOnMainThread( + [editor, fileAndPos] { editor->goToLine( fileAndPos.second ); } ); + } + } + } else { + loadFileFromPath( fileAndPos.first, true, nullptr, + [fileAndPos]( UICodeEditor* editor, const std::string& ) { + editor->runOnMainThread( + [editor, fileAndPos] { editor->goToLine( fileAndPos.second ); } ); + } ); + } + + mFileToOpen.clear(); +} + void App::onRealDocumentLoaded( UICodeEditor* editor, const std::string& path ) { updateEditorTitle( editor ); if ( mSplitter->curEditorExistsAndFocused() && editor == mSplitter->getCurEditor() ) @@ -3197,42 +3238,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe initProjectTreeView( file ); } - if ( !fileToOpen.empty() ) { - auto fileAndPos = getPathAndPosition( fileToOpen ); - auto tab = mSplitter->isDocumentOpen( fileAndPos.first, false, true ); - - if ( tab ) { - tab->getTabWidget()->setTabSelected( tab ); - if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) { - UICodeEditor* editor = tab->getOwnedWidget()->asType(); - if ( editor->getDocument().isLoading() ) { - Uint32 cb = editor->on( - Event::OnDocumentLoaded, [fileAndPos]( const Event* event ) { - if ( event->getNode()->isType( UI_TYPE_CODEEDITOR ) ) { - UICodeEditor* editor = event->getNode()->asType(); - editor->runOnMainThread( [editor, fileAndPos] { - editor->goToLine( fileAndPos.second ); - } ); - } - event->getNode()->removeEventListener( event->getCallbackId() ); - } ); - // Don't listen forever if no event is received - editor->runOnMainThread( - [editor, cb]() { editor->removeEventListener( cb ); }, Seconds( 4 ) ); - } else { - editor->runOnMainThread( - [editor, fileAndPos] { editor->goToLine( fileAndPos.second ); } ); - } - } - } else { - loadFileFromPath( fileAndPos.first, true, nullptr, - [fileAndPos]( UICodeEditor* editor, const std::string& ) { - editor->runOnMainThread( [editor, fileAndPos] { - editor->goToLine( fileAndPos.second ); - } ); - } ); - } - } + mFileToOpen = fileToOpen; Log::info( "Init ProjectTreeView took: %.2f ms", globalClock.getElapsedTime().asMilliseconds() ); @@ -3348,7 +3354,14 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { { "export-lang" }, "" ); try { - parser.ParseCLI( Sys::parseArguments( argc, argv ) ); + auto args = Sys::parseArguments( argc, argv ); + + if ( !args.empty() ) { + std::string strargs( String::join( args ) ); + Log::info( "ecode starting with these command line arguments: %s", strargs.c_str() ); + } + + parser.ParseCLI( args ); } catch ( const args::Help& ) { Sys::windowAttachConsole(); std::cout << parser; diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index d5381d805..5becf6060 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -312,6 +312,8 @@ class App : public UICodeEditorSplitter::Client { void checkLanguagesHealth(); + void loadFileDelayed(); + protected: EE::Window::Window* mWindow{ nullptr }; UISceneNode* mUISceneNode{ nullptr }; @@ -375,6 +377,7 @@ class App : public UICodeEditorSplitter::Client { std::unique_ptr mTerminalManager; std::unique_ptr mPluginManager; std::unique_ptr mSettings; + std::string mFileToOpen; void saveAllProcess();