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();