From f209ed5cb3e27c382e5f17ef854c7db4381ee802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 31 Dec 2020 23:29:39 -0300 Subject: [PATCH] TextureFactory::remove now allows Texture* as parameter. ecode: Allow preview image inside the editor. --- include/eepp/graphics/texturefactory.hpp | 8 +- include/eepp/scene/node.hpp | 6 +- include/eepp/system/color.hpp | 6 +- src/eepp/graphics/texturefactory.cpp | 13 ++- src/eepp/system/color.cpp | 17 +++- src/eepp/ui/uiimage.cpp | 18 ++-- src/tools/codeeditor/codeeditor.cpp | 101 ++++++++++++++++++----- src/tools/codeeditor/codeeditor.hpp | 6 ++ 8 files changed, 139 insertions(+), 36 deletions(-) diff --git a/include/eepp/graphics/texturefactory.hpp b/include/eepp/graphics/texturefactory.hpp index 0067f4ab9..a4b69306f 100644 --- a/include/eepp/graphics/texturefactory.hpp +++ b/include/eepp/graphics/texturefactory.hpp @@ -128,12 +128,18 @@ class EE_API TextureFactory : protected Mutex { const bool& CompressTexture = false, const bool& KeepLocalCopy = false, const Image::FormatConfiguration& imageformatConfiguration = Image::FormatConfiguration() ); - /** Remove and Unload the Texture Id + /** Removes and Unload the Texture Id * @param TexId * @return True if was removed */ bool remove( Uint32 TexId ); + /** Removes and Unload the Texture + * @param texture The texture pointer + * @return True if was removed + */ + bool remove( Texture* texture ); + /** Reload all loaded textures to recover the OpenGL context */ void reloadAllTextures(); diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp index cbc426778..1ca86ca92 100644 --- a/include/eepp/scene/node.hpp +++ b/include/eepp/scene/node.hpp @@ -190,6 +190,10 @@ class EE_API Node : public Transformable { Uint32 addEventListener( const Uint32& eventType, const EventCallback& callback ); + Uint32 on( const Uint32& eventType, const EventCallback& callback ) { + return addEventListener( eventType, callback ); + } + void removeEventsOfType( const Uint32& eventType ); void removeEventListener( const Uint32& callbackId ); @@ -406,7 +410,7 @@ class EE_API Node : public Transformable { const Vector2f& getScreenPos() const; - protected: + protected: typedef std::map> EventsMap; friend class EventDispatcher; diff --git a/include/eepp/system/color.hpp b/include/eepp/system/color.hpp index 4147fed33..e11b0528b 100644 --- a/include/eepp/system/color.hpp +++ b/include/eepp/system/color.hpp @@ -138,7 +138,9 @@ class EE_API Color : public tColor { public: Color(); - Color( std::string colorString ); + Color( const Color& color ); + + Color( const std::string& colorString ); Color( Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255 ); @@ -152,6 +154,8 @@ class EE_API Color : public tColor { Color( const Uint32& Col ); + Color& operator=( const Color& col ); + Colorf toHsv() const; static Color fromHsv( const Colorf& hsv ); diff --git a/src/eepp/graphics/texturefactory.cpp b/src/eepp/graphics/texturefactory.cpp index b31033299..aeb77fe6e 100644 --- a/src/eepp/graphics/texturefactory.cpp +++ b/src/eepp/graphics/texturefactory.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -158,8 +159,8 @@ void TextureFactory::bind( const Texture* texture, Texture::CoordinateType coord } if ( coordinateType == Texture::CoordinateType::Pixels ) { - GLfloat matrix[16] = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f}; + GLfloat matrix[16] = { 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f }; matrix[0] = 1.f / const_cast( texture )->getPixelsSize().x; matrix[5] = 1.f / const_cast( texture )->getPixelsSize().y; @@ -219,6 +220,14 @@ bool TextureFactory::remove( Uint32 TexId ) { return false; } +bool TextureFactory::remove( Texture* texture ) { + if ( std::find( mTextures.begin(), mTextures.end(), texture ) != mTextures.end() ) { + removeReference( texture ); + return true; + } + return false; +} + void TextureFactory::removeReference( Texture* Tex ) { mMemSize -= Tex->getMemSize(); diff --git a/src/eepp/system/color.cpp b/src/eepp/system/color.cpp index d5929ed85..64c36ea9a 100644 --- a/src/eepp/system/color.cpp +++ b/src/eepp/system/color.cpp @@ -89,7 +89,14 @@ Color Color::blend( Color src, Color dst ) { Color::Color() : tColor() {} -Color::Color( std::string colorString ) { +Color::Color( const Color& c ) { + r = c.r; + g = c.g; + b = c.b; + a = c.a; +} + +Color::Color( const std::string& colorString ) { Color c( fromString( colorString ) ); r = c.r; g = c.g; @@ -109,6 +116,14 @@ Color::Color( const tColor& Col ) : tColor( Col.r, Col.g, Col.b, C Color::Color( const Uint32& Col ) : tColor( Col ) {} +Color& Color::operator=( const Color& col ) { + r = col.r; + g = col.g; + b = col.b; + a = col.a; + return *this; +} + Colorf Color::toHsv() const { Colorf hsv; Colorf rgba( this->r / 255.f, this->g / 255.f, this->b / 255.f, this->a / 255.f ); diff --git a/src/eepp/ui/uiimage.cpp b/src/eepp/ui/uiimage.cpp index ca9364084..f8e3df746 100644 --- a/src/eepp/ui/uiimage.cpp +++ b/src/eepp/ui/uiimage.cpp @@ -27,8 +27,6 @@ UIImage::UIImage( const std::string& tag ) : mDrawableOwner( false ) { mFlags |= UI_AUTO_SIZE; - onAutoSize(); - applyDefaultTheme(); } @@ -77,15 +75,15 @@ void UIImage::onAutoSize() { setInternalSize( mDrawable->getSize() ); } - if ( mWidthPolicy == SizePolicy::WrapContent ) { - setInternalWidth( (int)mDrawable->getSize().getWidth() + mPadding.Left + - mPadding.Right ); - } + Sizef size( getSize() ); - if ( mHeightPolicy == SizePolicy::WrapContent ) { - setInternalHeight( (int)mDrawable->getSize().getHeight() + mPadding.Top + - mPadding.Bottom ); - } + if ( mWidthPolicy == SizePolicy::WrapContent ) + size.x = ( (int)mDrawable->getSize().getWidth() + mPadding.Left + mPadding.Right ); + + if ( mHeightPolicy == SizePolicy::WrapContent ) + size.y = ( (int)mDrawable->getSize().getHeight() + mPadding.Top + mPadding.Bottom ); + + setSize( size ); } } diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index 8e21799ba..1c8dbb611 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -134,8 +134,7 @@ void App::openFileDialog() { dialog->setTitle( "Open File" ); dialog->setCloseShortcut( KEY_ESCAPE ); dialog->addEventListener( Event::OpenFile, [&]( const Event* event ) { - mEditorSplitter->loadFileFromPathInNewTab( - event->getNode()->asType()->getFullPath() ); + loadFileFromPath( event->getNode()->asType()->getFullPath() ); } ); dialog->addEventListener( Event::OnWindowClose, [&]( const Event* ) { if ( mEditorSplitter && mEditorSplitter->getCurEditor() && @@ -511,7 +510,7 @@ void App::initLocateBar() { if ( !tab ) { FileInfo fileInfo( path ); if ( fileInfo.exists() && fileInfo.isRegularFile() ) - mEditorSplitter->loadFileFromPathInNewTab( path ); + loadFileFromPath( path ); } else { tab->getTabWidget()->setTabSelected( tab ); } @@ -851,7 +850,7 @@ void App::initGlobalSearchBar() { if ( !tab ) { FileInfo fileInfo( path ); if ( fileInfo.exists() && fileInfo.isRegularFile() ) - mEditorSplitter->loadFileFromPathInNewTab( path ); + loadFileFromPath( path ); } else { tab->getTabWidget()->setTabSelected( tab ); } @@ -945,14 +944,14 @@ void App::onFileDropped( String file ) { node = codeEditor; if ( node && node->isType( UI_TYPE_CODEEDITOR ) ) { codeEditor = node->asType(); - if ( !codeEditor->getDocument().isEmpty() ) { + if ( !codeEditor->getDocument().isEmpty() && !Image::isImageExtension( file ) ) { auto d = mEditorSplitter->createCodeEditorInTabWidget( mEditorSplitter->tabWidgetFromEditor( codeEditor ) ); codeEditor = d.second; d.first->getTabWidget()->setTabSelected( d.first ); } } - mEditorSplitter->loadFileFromPath( file, codeEditor ); + loadFileFromPath( file, false, codeEditor ); } void App::onTextDropped( String text ) { @@ -992,7 +991,7 @@ void App::updateRecentFiles() { menu->removeEventsOfType( Event::OnItemClicked ); if ( mRecentFiles.empty() ) return; - for ( auto file : mRecentFiles ) + for ( const auto& file : mRecentFiles ) menu->add( file ); menu->addSeparator(); menu->add( "Clear Menu" ); @@ -1003,7 +1002,7 @@ void App::updateRecentFiles() { if ( txt != "Clear Menu" ) { std::string path( txt.toUtf8() ); if ( FileSystem::fileExists( path ) && !FileSystem::isDirectory( path ) ) { - mEditorSplitter->loadFileFromPathInNewTab( path ); + loadFileFromPath( path ); } } else { mRecentFiles.clear(); @@ -1023,7 +1022,7 @@ void App::updateRecentFolders() { menu->removeEventsOfType( Event::OnItemClicked ); if ( mRecentFolders.empty() ) return; - for ( auto file : mRecentFolders ) + for ( const auto& file : mRecentFolders ) menu->add( file ); menu->addSeparator(); menu->add( "Clear Menu" ); @@ -1579,17 +1578,17 @@ void App::loadKeybindings() { if ( FileSystem::fileExists( mKeybindingsPath ) ) { mKeybindings = ini.getKeyMap( "keybindings" ); } else { - for ( auto it : defKeybindings ) + for ( const auto& it : defKeybindings ) ini.setValue( "keybindings", bindings.getShortcutString( it.first ), it.second ); ini.writeFile(); mKeybindings = ini.getKeyMap( "keybindings" ); } - for ( auto key : mKeybindings ) + for ( const auto& key : mKeybindings ) mKeybindingsInvert[key.second] = key.first; if ( defKeybindings.size() != mKeybindings.size() ) { bool added = false; - for ( auto key : defKeybindings ) { + for ( const auto& key : defKeybindings ) { auto foundCmd = mKeybindingsInvert.find( key.second ); auto shortcutStr = bindings.getShortcutString( key.first ); if ( foundCmd == mKeybindingsInvert.end() && @@ -1804,6 +1803,43 @@ void App::createDocAlert( UICodeEditor* editor ) { } ); } +void App::loadFileFromPath( const std::string& path, bool inNewTab, UICodeEditor* codeEditor ) { + if ( Image::isImageExtension( path ) && Image::isImage( path ) ) { + UIImage* imageView = mImageLayout->findByType( UI_TYPE_IMAGE ); + UILoader* loaderView = mImageLayout->findByType( UI_TYPE_LOADER ); + if ( imageView ) { + mImageLayout->setEnabled( true )->setVisible( true ); + loaderView->setVisible( true ); +#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN + mThreadPool->run( + [&, imageView, loaderView, path]() { +#endif + Texture* image = TextureFactory::instance()->getTexture( + TextureFactory::instance()->loadFromFile( path ) ); + if ( mImageLayout->isVisible() ) { + imageView->runOnMainThread( [imageView, loaderView, image]() { + imageView->setDrawable( image, true ); + loaderView->setVisible( false ); + } ); + } else { + TextureFactory::instance()->remove( image ); + imageView->setDrawable( nullptr ); + loaderView->setVisible( false ); + } +#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN + }, + []() {} ); +#endif + } + } else { + if ( inNewTab ) { + mEditorSplitter->loadFileFromPathInNewTab( path ); + } else { + mEditorSplitter->loadFileFromPath( path, codeEditor ); + } + } +} + void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { const CodeEditorConfig& config = mConfig.editor; editor->setFontSize( config.fontSize.asDp( 0, Sizef(), mUISceneNode->getDPI() ) ); @@ -1876,8 +1912,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { updateDocumentMenu(); } } ); - doc.setCommand( "keybindings", - [&] { mEditorSplitter->loadFileFromPathInNewTab( mKeybindingsPath ); } ); + doc.setCommand( "keybindings", [&] { loadFileFromPath( mKeybindingsPath ); } ); doc.setCommand( "debug-draw-boxes-toggle", [&] { mUISceneNode->setDrawBoxes( !mUISceneNode->getDrawBoxes() ); } ); doc.setCommand( "debug-draw-highlight-toggle", [&] { @@ -2156,11 +2191,11 @@ void App::updateEditorState() { void App::removeFolderWatches() { if ( mFileWatcher ) { - for ( auto dir : mFolderWatches ) + for ( const auto& dir : mFolderWatches ) mFileWatcher->removeWatch( dir ); mFolderWatches.clear(); - for ( auto fileFolder : mFilesFolderWatches ) + for ( const auto& fileFolder : mFilesFolderWatches ) mFileWatcher->removeWatch( fileFolder.second ); mFilesFolderWatches.clear(); } @@ -2180,7 +2215,7 @@ void App::loadDirTree( const std::string& path ) { if ( mFileWatcher ) { removeFolderWatches(); auto newDirs = dirTree.getDirectories(); - for ( auto dir : newDirs ) + for ( const auto& dir : newDirs ) mFolderWatches.insert( mFileWatcher->addWatch( dir, mFileSystemListener ) ); } }, @@ -2211,7 +2246,7 @@ void App::initProjectTreeView( const std::string& path ) { if ( !tab ) { FileInfo fileInfo( path ); if ( fileInfo.exists() && fileInfo.isRegularFile() ) - mEditorSplitter->loadFileFromPathInNewTab( path ); + loadFileFromPath( path ); } else { tab->getTabWidget()->setTabSelected( tab ); } @@ -2245,7 +2280,7 @@ void App::initProjectTreeView( const std::string& path ) { if ( mFileSystemListener ) mFileSystemListener->setFileSystemModel( mFileSystemModel ); - mEditorSplitter->loadFileFromPath( rpath ); + loadFileFromPath( rpath, false ); } } else { loadFolder( "." ); @@ -2254,6 +2289,13 @@ void App::initProjectTreeView( const std::string& path ) { mProjectTreeView->setAutoExpandOnSingleColumn( true ); } +void App::initImageView() { + mImageLayout->on( Event::MouseClick, [&]( const Event* ) { + mImageLayout->findByType( UI_TYPE_IMAGE )->setDrawable( nullptr ); + mImageLayout->setEnabled( false )->setVisible( false ); + } ); +} + void App::loadFolder( const std::string& path ) { if ( !mCurrentProject.empty() ) closeEditors(); @@ -2320,6 +2362,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) { if ( winSettings.Icon.empty() ) winSettings.Icon = mConfig.window.winIcon; ContextSettings contextSettings = engine->createContextSettings( &mConfig.ini, "window" ); + contextSettings.SharedGLContext = true; mWindow = engine->createWindow( winSettings, contextSettings ); if ( mWindow->isOpen() ) { @@ -2454,6 +2497,16 @@ void App::init( const std::string& file, const Float& pidelDensity ) { margin-top: 24dp; cursor: arrow; } + #image_container { + background-color: #00000066; + } + #image_close { + color: #eff0f188; + font-family: icon; + font-size: 22dp; + margin-top: 32dp; + margin-right: 22dp; + } @@ -2467,6 +2520,11 @@ void App::init( const std::string& file, const Float& pidelDensity ) { + + + + + @@ -2566,7 +2624,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) { { "table-view", 0xf1de }, { "list-view", 0xecf1 }, }; - for ( auto icon : icons ) + for ( const auto& icon : icons ) iconTheme->add( UIGlyphIcon::New( icon.first, iconFont, icon.second ) ); mUISceneNode->getUIIconThemeManager()->setCurrentTheme( iconTheme ); @@ -2577,6 +2635,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) { mUISceneNode->loadLayoutFromString( baseUI ); mUISceneNode->bind( "main_layout", mMainLayout ); mUISceneNode->bind( "code_container", mBaseLayout ); + mUISceneNode->bind( "image_container", mImageLayout ); mUISceneNode->bind( "search_bar", mSearchBarLayout ); mUISceneNode->bind( "global_search_bar", mGlobalSearchBarLayout ); mUISceneNode->bind( "locate_bar", mLocateBarLayout ); @@ -2614,6 +2673,8 @@ void App::init( const std::string& file, const Float& pidelDensity ) { initLocateBar(); + initImageView(); + createSettingsMenu(); mEditorSplitter->createEditorWithTabWidget( mBaseLayout ); diff --git a/src/tools/codeeditor/codeeditor.hpp b/src/tools/codeeditor/codeeditor.hpp index ca5f49b3e..8a18fe0dc 100644 --- a/src/tools/codeeditor/codeeditor.hpp +++ b/src/tools/codeeditor/codeeditor.hpp @@ -156,6 +156,7 @@ class App : public UICodeEditorSplitter::Client { String mLastSearch; UILayout* mMainLayout{ nullptr }; UILayout* mBaseLayout{ nullptr }; + UILayout* mImageLayout{ nullptr }; UISearchBar* mSearchBarLayout{ nullptr }; UILocateBar* mLocateBarLayout{ nullptr }; UILocateBar* mGlobalSearchBarLayout{ nullptr }; @@ -214,6 +215,8 @@ class App : public UICodeEditorSplitter::Client { void initProjectTreeView( const std::string& path ); + void initImageView(); + void loadDirTree( const std::string& path ); void showSidePanel( bool show ); @@ -339,6 +342,9 @@ class App : public UICodeEditorSplitter::Client { void removeFolderWatches(); void createDocAlert( UICodeEditor* editor ); + + void loadFileFromPath( const std::string& path, bool inNewTab = true, + UICodeEditor* codeEditor = nullptr ); }; #endif // EE_TOOLS_CODEEDITOR_HPP