From 16e6e1f8d143b09db8cb8de0ac7013bbdd128d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 20 Jan 2020 05:15:18 -0300 Subject: [PATCH] Improvements in emscripten build. Added support in emscripten for Http:getAsync and Http::postAsync. Fixes with modal dialogs. Fixes in texture atlas editor. Fixes in UIColorPicker. Fix in UITextView text selection. Improvements in WindowSDL2. UICheckBox not uses setChecked and isChecked instead of setActive and isActive. --- include/eepp/graphics/text.hpp | 2 +- include/eepp/network/http.hpp | 20 +++-- include/eepp/ui/uicheckbox.hpp | 8 +- premake4.lua | 9 +- projects/emscripten/make.sh | 3 +- src/eepp/graphics/text.cpp | 7 +- src/eepp/maps/mapeditor/mapeditor.cpp | 46 +++++----- src/eepp/maps/mapeditor/uimapnew.cpp | 24 +++--- src/eepp/network/http.cpp | 95 +++++++++++++++++++++ src/eepp/ui/tools/textureatlasnew.cpp | 34 +++++--- src/eepp/ui/tools/textureatlasnew.hpp | 5 ++ src/eepp/ui/tools/uicolorpicker.cpp | 8 +- src/eepp/ui/uicheckbox.cpp | 24 +++--- src/eepp/ui/uiscenenode.cpp | 4 +- src/eepp/ui/uitextview.cpp | 2 +- src/eepp/ui/uiwindow.cpp | 13 ++- src/eepp/window/backend/SDL2/windowsdl2.cpp | 30 +++++-- src/test/eetest.cpp | 21 +++-- 18 files changed, 255 insertions(+), 100 deletions(-) diff --git a/include/eepp/graphics/text.hpp b/include/eepp/graphics/text.hpp index d792a4315..10fee7359 100644 --- a/include/eepp/graphics/text.hpp +++ b/include/eepp/graphics/text.hpp @@ -121,7 +121,7 @@ class EE_API Text { /** Simulates a selection request and return the initial and end cursor position when the * selection worked. Otherwise both parameters will be -1. */ - void findWordFromCharacterIndex( const Int32& characterIndex, Int32& InitCur, Int32& EndCur ); + void findWordFromCharacterIndex( Int32 characterIndex, Int32& InitCur, Int32& EndCur ); /** Cache the with of the current text */ void getWidthInfo( std::vector& LinesWidth, Float& CachedWidth, int& NumLines, diff --git a/include/eepp/network/http.hpp b/include/eepp/network/http.hpp index 9a3f7337b..772276ace 100644 --- a/include/eepp/network/http.hpp +++ b/include/eepp/network/http.hpp @@ -79,6 +79,11 @@ class EE_API Http : NonCopyable { /** @return The status string */ static const char* statusToString( const Status& status ); + /** Creates a faked response. Useful for testing. */ + static Response createFakeResponse( const FieldTable& fields, Status& status, + const std::string& body, unsigned int majorVersion = 1, + unsigned int minorVersion = 1 ); + /** @brief Default constructor ** Constructs an empty response. */ Response(); @@ -256,6 +261,9 @@ class EE_API Http : NonCopyable { /** @return The request Uri */ const std::string& getUri() const; + /** @return The request Method */ + const Method& getMethod() const; + /** @return If SSL certificate validation is enabled */ const bool& getValidateCertificate() const; @@ -444,20 +452,20 @@ class EE_API Http : NonCopyable { AsyncResponseCallback; /** @brief Sends the request and creates a new thread, when got the response informs the result - *to the callback. * This function does not lock the caller thread. - ** @see sendRequest */ + *to the callback. * This function does not lock the caller thread. + ** @see sendRequest */ void sendAsyncRequest( const AsyncResponseCallback& cb, const Http::Request& request, Time timeout = Time::Zero ); /** @brief Sends the request and creates a new thread, when got the response informs the result - *to the callback. * This function does not lock the caller thread. - ** @see downloadRequest */ + *to the callback. * This function does not lock the caller thread. + ** @see downloadRequest */ void downloadAsyncRequest( const AsyncResponseCallback& cb, const Http::Request& request, IOStream& writeTo, Time timeout = Time::Zero ); /** @brief Sends the request and creates a new thread, when got the response informs the result - *to the callback. * This function does not lock the caller thread. - ** @see downloadRequest */ + *to the callback. * This function does not lock the caller thread. + ** @see downloadRequest */ void downloadAsyncRequest( const AsyncResponseCallback& cb, const Http::Request& request, std::string writePath, Time timeout = Time::Zero ); diff --git a/include/eepp/ui/uicheckbox.hpp b/include/eepp/ui/uicheckbox.hpp index 8e8e264c5..f5abffd00 100644 --- a/include/eepp/ui/uicheckbox.hpp +++ b/include/eepp/ui/uicheckbox.hpp @@ -20,11 +20,11 @@ class EE_API UICheckBox : public UITextView { virtual void setTheme( UITheme* Theme ); - const bool& isActive() const; + const bool& isChecked() const; - void setActive( const bool& active ); + void setChecked( const bool& checked ); - UINode* getActiveButton() const; + UINode* getCheckedButton() const; UINode* getInactiveButton() const; @@ -39,7 +39,7 @@ class EE_API UICheckBox : public UITextView { protected: UINode* mActiveButton; UINode* mInactiveButton; - bool mActive; + bool mChecked; Uint32 mLastTick; Int32 mTextSeparation; diff --git a/premake4.lua b/premake4.lua index d5b1af742..d841c8dff 100644 --- a/premake4.lua +++ b/premake4.lua @@ -289,7 +289,7 @@ backend_selected = false function build_base_configuration( package_name ) includedirs { "src/thirdparty/zlib" } - if not os.is("windows") then + if not os.is("windows") and not os.is_real("emscripten") then buildoptions{ "-fPIC" } end @@ -318,7 +318,7 @@ function build_base_configuration( package_name ) end function build_base_cpp_configuration( package_name ) - if not os.is("windows") then + if not os.is("windows") and not os.is_real("emscripten") then buildoptions{ "-fPIC" } end @@ -455,8 +455,9 @@ function build_link_configuration( package_name, use_ee_icon ) add_cross_config_links() configuration "emscripten" - linkoptions{ "-O2 -s TOTAL_MEMORY=67108864 -s ASM_JS=1 -s VERBOSE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s FULL_ES3=1 -s \"BINARYEN_TRAP_MODE='clamp'\"" } - buildoptions { "-fno-strict-aliasing -O2 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=web" } + linkoptions { "-O3 -s TOTAL_MEMORY=67108864 -s VERBOSE=1" } + linkoptions { "-s USE_SDL=2 -s \"BINARYEN_TRAP_MODE='clamp'\"" } + buildoptions { "-O3 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=web" } if _OPTIONS["with-gles1"] and ( not _OPTIONS["with-gles2"] or _OPTIONS["force-gles1"] ) then linkoptions{ "-s LEGACY_GL_EMULATION=1" } diff --git a/projects/emscripten/make.sh b/projects/emscripten/make.sh index a960165f3..c626a55c4 100755 --- a/projects/emscripten/make.sh +++ b/projects/emscripten/make.sh @@ -3,10 +3,9 @@ # remember to first set the environment # source /path/to/emsdk/emsdk_env.sh cd $(dirname "$0") -premake4 --file=../../premake4.lua --with-gles1 --with-gles2 --with-static-eepp --platform=emscripten --with-backend=SDL2 gmake +premake4 --file=../../premake4.lua --with-gles2 --with-static-eepp --platform=emscripten --with-backend=SDL2 gmake cd ../../make/emscripten/ ln -sf ../../bin/assets/ ./ -sed -i 's/-rcs/rcs/g' *.make emmake make -j`nproc` $@ # Fix a bug in emscripten, see my patch: https://github.com/emscripten-core/emscripten/pull/10208 sed -i 's/function _alGetSource3f(source,/function _alGetSource3f(sourceId,/' ../../bin/*.js diff --git a/src/eepp/graphics/text.cpp b/src/eepp/graphics/text.cpp index cfe603236..582c85e79 100644 --- a/src/eepp/graphics/text.cpp +++ b/src/eepp/graphics/text.cpp @@ -382,8 +382,7 @@ static bool isStopSelChar( Uint32 c ) { ',' == c || ';' == c || ':' == c || '\n' == c || '"' == c || '\'' == c; } -void Text::findWordFromCharacterIndex( const Int32& characterIndex, Int32& InitCur, - Int32& EndCur ) { +void Text::findWordFromCharacterIndex( Int32 characterIndex, Int32& InitCur, Int32& EndCur ) { InitCur = 0; EndCur = mString.size(); @@ -398,6 +397,10 @@ void Text::findWordFromCharacterIndex( const Int32& characterIndex, Int32& InitC InitCur = 0; } + if ( characterIndex >= (Int32)mString.size() ) { + characterIndex = mString.size() - 1; + } + for ( Int32 i = characterIndex; i >= 0; i-- ) { if ( isStopSelChar( mString[i] ) ) { InitCur = i + 1; diff --git a/src/eepp/maps/mapeditor/mapeditor.cpp b/src/eepp/maps/mapeditor/mapeditor.cpp index 705eb87a4..76d5c5a06 100644 --- a/src/eepp/maps/mapeditor/mapeditor.cpp +++ b/src/eepp/maps/mapeditor/mapeditor.cpp @@ -596,7 +596,7 @@ void MapEditor::createLighContainer() { ->setPosition( mLightRadius->getPosition().x, mLightRadius->getPosition().y + mLightRadius->getSize().getHeight() + 8 ); mLightTypeChk->setText( "Isometric Light" ); - mLightTypeChk->setActive( false ); + mLightTypeChk->setChecked( false ); mLightTypeChk->addEventListener( Event::OnValueChange, cb::Make1( this, &MapEditor::onLightTypeChange ) ); } @@ -634,7 +634,7 @@ void MapEditor::createObjectsContainer() { mChkClampToTile->setText( "Clamp Position to Tile" ); mChkClampToTile->addEventListener( Event::OnValueChange, cb::Make1( this, &MapEditor::chkClickClampToTile ) ); - mChkClampToTile->setActive( true ); + mChkClampToTile->setChecked( true ); } void MapEditor::onObjectModeSel( const Event* Event ) { @@ -738,7 +738,7 @@ void MapEditor::onAddObject( Uint32 Type, Polygon2f poly ) { void MapEditor::onLightTypeChange( const Event* Event ) { if ( NULL != mUIMap->getSelectedLight() ) { - mUIMap->getSelectedLight()->setType( mLightTypeChk->isActive() ? MapLightType::Isometric + mUIMap->getSelectedLight()->setType( mLightTypeChk->isChecked() ? MapLightType::Isometric : MapLightType::Normal ); } } @@ -760,7 +760,7 @@ void MapEditor::onLightSelect( MapLight* Light ) { mUIGreenSlider->setValue( Col.g ); mUIBlueSlider->setValue( Col.b ); mLightRadius->setValue( Light->getRadius() ); - mLightTypeChk->setActive( Light->getType() == MapLightType::Isometric ? true : false ); + mLightTypeChk->setChecked( Light->getType() == MapLightType::Isometric ? true : false ); } void MapEditor::onNewLight( const Event* Event ) { @@ -771,7 +771,7 @@ void MapEditor::onNewLight( const Event* Event ) { mUIMap->addLight( eeNew( MapLight, ( mLightRadius->getValue(), Pos.x, Pos.y, mUIBaseColor->getBackgroundColor().toRGB(), - mLightTypeChk->isActive() ? MapLightType::Isometric : MapLightType::Normal ) ) ); + mLightTypeChk->isChecked() ? MapLightType::Isometric : MapLightType::Normal ) ) ); } } @@ -815,7 +815,7 @@ void MapEditor::onBlueChange( const Event* Event ) { } void MapEditor::chkClickDI( const Event* Event ) { - if ( mChkDI->isActive() ) { + if ( mChkDI->isChecked() ) { mSGCont->setEnabled( false ); mSGCont->setVisible( false ); mDICont->setEnabled( true ); @@ -830,20 +830,20 @@ void MapEditor::chkClickDI( const Event* Event ) { void MapEditor::chkClickClampToTile( const Event* Event ) { if ( NULL != mUIMap ) - mUIMap->setClampToTile( mChkClampToTile->isActive() ); + mUIMap->setClampToTile( mChkClampToTile->isChecked() ); } void MapEditor::updateGfx() { - if ( mChkMirrored->isActive() && mChkFliped->isActive() ) + if ( mChkMirrored->isChecked() && mChkFliped->isChecked() ) mGfxPreview->setRenderMode( RENDER_FLIPPED_MIRRORED ); - else if ( mChkMirrored->isActive() ) + else if ( mChkMirrored->isChecked() ) mGfxPreview->setRenderMode( RENDER_MIRROR ); - else if ( mChkFliped->isActive() ) + else if ( mChkFliped->isChecked() ) mGfxPreview->setRenderMode( RENDER_FLIPPED ); else mGfxPreview->setRenderMode( RENDER_NORMAL ); - if ( mChkRot90->isActive() ) + if ( mChkRot90->isChecked() ) mGfxPreview->setRotation( 90 ); else mGfxPreview->setRotation( 0 ); @@ -852,25 +852,25 @@ void MapEditor::updateGfx() { void MapEditor::updateFlags() { mCurGOFlags = 0; - if ( mChkMirrored->isActive() ) + if ( mChkMirrored->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_MIRRORED; - if ( mChkFliped->isActive() ) + if ( mChkFliped->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_FLIPED; - if ( mChkBlocked->isActive() ) + if ( mChkBlocked->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_BLOCKED; - if ( mChkAnim->isActive() ) + if ( mChkAnim->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_ANIMATED; - if ( mChkRot90->isActive() ) + if ( mChkRot90->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_ROTATE_90DEG; - if ( mChkAutoFix->isActive() ) + if ( mChkAutoFix->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_AUTO_FIX_TILE_POS; - if ( mChkBlendAdd->isActive() ) + if ( mChkBlendAdd->isChecked() ) mCurGOFlags |= GObjFlags::GAMEOBJECT_BLEND_ADD; } @@ -884,11 +884,11 @@ void MapEditor::onTypeChange( const Event* Event ) { else mCurGOType = String::hash( mGOTypeList->getText().toUtf8() ); - if ( NULL != mChkAnim && NULL != mGOTypeList && mChkAnim->isActive() && + if ( NULL != mChkAnim && NULL != mGOTypeList && mChkAnim->isChecked() && mGOTypeList->getText() != "Sprite" ) { if ( mGOTypeList->getText() == "TextureRegion" || mGOTypeList->getText() == "TextureRegionEx" ) { - mChkAnim->setActive( false ); + mChkAnim->setChecked( false ); } } } @@ -919,7 +919,7 @@ void MapEditor::chkClickAutoFix( const Event* Event ) { void MapEditor::chkClickAnimated( const Event* Event ) { updateFlags(); - if ( mChkAnim->isActive() && ( mGOTypeList->getText() == "TextureRegion" || + if ( mChkAnim->isChecked() && ( mGOTypeList->getText() == "TextureRegion" || mGOTypeList->getText() == "TextureRegionEx" ) ) { mGOTypeList->getListBox()->setSelected( "Sprite" ); } @@ -1448,7 +1448,7 @@ GameObject* MapEditor::createGameObject() { } else if ( GAMEOBJECT_TYPE_SPRITE == mCurGOType ) { - if ( mChkAnim->isActive() ) { + if ( mChkAnim->isChecked() ) { Sprite* tAnimSprite = Sprite::New( String::removeNumbersAtEnd( mGfxPreview->getTextureRegion()->getName() ) ); @@ -1464,7 +1464,7 @@ GameObject* MapEditor::createGameObject() { //! Creates an empty game object. The client will interpret the GameObject Type, and //! instanciate the corresponding class. - if ( mChkDI->isActive() ) + if ( mChkDI->isChecked() ) tObj = eeNew( GameObjectVirtual, ( String::hash( mDataIdInput->getText().toUtf8() ), mCurLayer, mCurGOFlags, mCurGOType ) ); else diff --git a/src/eepp/maps/mapeditor/uimapnew.cpp b/src/eepp/maps/mapeditor/uimapnew.cpp index 3f7475460..54de93d4d 100644 --- a/src/eepp/maps/mapeditor/uimapnew.cpp +++ b/src/eepp/maps/mapeditor/uimapnew.cpp @@ -144,10 +144,10 @@ UIMapNew::UIMapNew( UIMap* Map, std::function NewMapCb, bool ResizeMap ) ->setPosition( Txt->getPosition().x + DistFromTitle, Txt->getPosition().y + Txt->getSize().getHeight() + 16 ); mUILightsEnabled->setText( "Lights Enabled" ); - mUILightsEnabled->setActive( true ); + mUILightsEnabled->setChecked( true ); if ( ResizeMap ) { - mUILightsEnabled->setActive( 0 != mUIMap->Map()->getLightsEnabled() ); + mUILightsEnabled->setChecked( 0 != mUIMap->Map()->getLightsEnabled() ); } mUILightsByVertex = UICheckBox::New(); @@ -156,10 +156,10 @@ UIMapNew::UIMapNew( UIMap* Map, std::function NewMapCb, bool ResizeMap ) ->setPosition( mUIWindow->getContainer()->getSize().getWidth() / 2, mUILightsEnabled->getPosition().y ); mUILightsByVertex->setText( "Lights By Vertex" ); - mUILightsByVertex->setActive( true ); + mUILightsByVertex->setChecked( true ); if ( ResizeMap ) { - mUILightsByVertex->setActive( 0 != mUIMap->Map()->getLightsByVertex() ); + mUILightsByVertex->setChecked( 0 != mUIMap->Map()->getLightsByVertex() ); } mUIClampBorders = UICheckBox::New(); @@ -169,10 +169,10 @@ UIMapNew::UIMapNew( UIMap* Map, std::function NewMapCb, bool ResizeMap ) mUILightsEnabled->getPosition().y + mUILightsEnabled->getSize().getHeight() + 16 ); mUIClampBorders->setText( "Clamp Borders" ); - mUIClampBorders->setActive( true ); + mUIClampBorders->setChecked( true ); if ( ResizeMap ) { - mUIClampBorders->setActive( 0 != mUIMap->Map()->getClampBorders() ); + mUIClampBorders->setChecked( 0 != mUIMap->Map()->getClampBorders() ); } mUIClipArea = UICheckBox::New(); @@ -181,10 +181,10 @@ UIMapNew::UIMapNew( UIMap* Map, std::function NewMapCb, bool ResizeMap ) ->setPosition( mUIWindow->getContainer()->getSize().getWidth() / 2, mUIClampBorders->getPosition().y ); mUIClipArea->setText( "Clip View Area" ); - mUIClipArea->setActive( true ); + mUIClipArea->setChecked( true ); if ( ResizeMap ) { - mUIClipArea->setActive( 0 != mUIMap->Map()->getClipedArea() ); + mUIClipArea->setChecked( 0 != mUIMap->Map()->getClipedArea() ); } Txt = @@ -333,16 +333,16 @@ void UIMapNew::onOKClick( const Event* ) { Uint32 Flags = MAP_EDITOR_DEFAULT_FLAGS; - if ( mUILightsEnabled->isActive() ) + if ( mUILightsEnabled->isChecked() ) Flags |= MAP_FLAG_LIGHTS_ENABLED; - if ( mUILightsByVertex->isActive() ) + if ( mUILightsByVertex->isChecked() ) Flags |= MAP_FLAG_LIGHTS_BYVERTEX; - if ( mUIClampBorders->isActive() ) + if ( mUIClampBorders->isChecked() ) Flags |= MAP_FLAG_CLAMP_BORDERS; - if ( mUIClipArea->isActive() ) + if ( mUIClipArea->isChecked() ) Flags |= MAP_FLAG_CLIP_AREA; if ( w > 0 && h > 0 && tw > 0 && th > 0 && ml > 0 ) { diff --git a/src/eepp/network/http.cpp b/src/eepp/network/http.cpp index 528b4c899..c69e00dc8 100644 --- a/src/eepp/network/http.cpp +++ b/src/eepp/network/http.cpp @@ -15,6 +15,10 @@ #include #include +#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN +#include +#endif + using namespace EE::Network::SSL; using namespace EE::Network::Private; @@ -116,6 +120,10 @@ const std::string& Http::Request::getUri() const { return mUri; } +const Http::Request::Method& Http::Request::getMethod() const { + return mMethod; +} + const bool& Http::Request::getValidateCertificate() const { return mValidateCertificate; } @@ -309,6 +317,20 @@ const char* Http::Response::statusToString( const Http::Response::Status& status } } +Http::Response Http::Response::createFakeResponse( const Http::Response::FieldTable& fields, + Http::Response::Status& status, + const std::string& body, + unsigned int majorVersion, + unsigned int minorVersion ) { + Response response; + response.mStatus = status; + response.mBody = body; + response.mFields = fields; + response.mMajorVersion = majorVersion; + response.mMinorVersion = minorVersion; + return response; +} + Http::Response::Response() : mStatus( ConnectionFailed ), mMajorVersion( 0 ), mMinorVersion( 0 ) {} Http::Response::FieldTable Http::Response::getHeaders() { @@ -1120,8 +1142,68 @@ bool Http::isProxied() const { return !mProxy.empty(); } +struct WGetAsyncRequest { + Http* http; + Http::Request request; + Http::AsyncResponseCallback cb; +}; + +#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN +void emscripten_async_wget2_got_data( unsigned, void* vwget, void* buffer, unsigned bufferSize ) { + WGetAsyncRequest* wget = reinterpret_cast( vwget ); + std::string responseBody; + Http::Response::Status status = Http::Response::Status::Ok; + responseBody.insert( 0, (const char*)buffer, bufferSize ); + Http::Response response = + Http::Response::createFakeResponse( Http::Response::FieldTable(), status, responseBody ); + wget->cb( *wget->http, wget->request, response ); + delete wget; +} + +void emscripten_async_wget2_got_file( unsigned int, void* vwget, const char* ) { + WGetAsyncRequest* wget = reinterpret_cast( vwget ); + Http::Response::Status status = Http::Response::Status::Ok; + Http::Response response = + Http::Response::createFakeResponse( Http::Response::FieldTable(), status, "" ); + wget->cb( *wget->http, wget->request, response ); + delete wget; +} + +void emscripten_async_wget2_got_error_data( unsigned, void* vwget, int errorCode, + const char* errorDescription ) { + WGetAsyncRequest* wget = reinterpret_cast( vwget ); + std::string responseBody; + Http::Response::Status status = Http::Response::Status::InternalServerError; + Http::Response response = + Http::Response::createFakeResponse( Http::Response::FieldTable(), status, responseBody ); + wget->cb( *wget->http, wget->request, response ); + delete wget; +} + +void emscripten_async_wget2_got_error_file( unsigned int, void* vwget, int errorCode ) { + WGetAsyncRequest* wget = reinterpret_cast( vwget ); + std::string responseBody; + Http::Response::Status status = Http::Response::Status::InternalServerError; + Http::Response response = + Http::Response::createFakeResponse( Http::Response::FieldTable(), status, responseBody ); + wget->cb( *wget->http, wget->request, response ); + delete wget; +} +#endif + void Http::sendAsyncRequest( const Http::AsyncResponseCallback& cb, const Http::Request& request, Time timeout ) { +#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN + WGetAsyncRequest* wget = new WGetAsyncRequest(); + wget->http = this; + wget->cb = cb; + wget->request = Http::Request( request ); + emscripten_async_wget2_data( ( getURI().toString() + request.getUri() ).c_str(), + Request::methodToString( request.getMethod() ).c_str(), + URI( request.getUri() ).getQuery().c_str(), wget, 1, + emscripten_async_wget2_got_data, + emscripten_async_wget2_got_error_data, NULL ); +#else AsyncRequest* thread = eeNew( AsyncRequest, ( this, cb, request, timeout ) ); thread->launch(); @@ -1132,6 +1214,7 @@ void Http::sendAsyncRequest( const Http::AsyncResponseCallback& cb, const Http:: removeOldThreads(); mThreads.push_back( thread ); +#endif } void Http::downloadAsyncRequest( const Http::AsyncResponseCallback& cb, @@ -1151,6 +1234,17 @@ void Http::downloadAsyncRequest( const Http::AsyncResponseCallback& cb, void Http::downloadAsyncRequest( const Http::AsyncResponseCallback& cb, const Http::Request& request, std::string writePath, Time timeout ) { +#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN + WGetAsyncRequest* wget = new WGetAsyncRequest(); + wget->http = this; + wget->cb = cb; + wget->request = Http::Request( request ); + emscripten_async_wget2( ( getURI().toString() + request.getUri() ).c_str(), writePath.c_str(), + Request::methodToString( request.getMethod() ).c_str(), + URI( request.getUri() ).getQuery().c_str(), wget, + emscripten_async_wget2_got_file, emscripten_async_wget2_got_error_file, + NULL ); +#else AsyncRequest* thread = eeNew( AsyncRequest, ( this, cb, request, writePath, timeout ) ); thread->launch(); @@ -1161,6 +1255,7 @@ void Http::downloadAsyncRequest( const Http::AsyncResponseCallback& cb, removeOldThreads(); mThreads.push_back( thread ); +#endif } const IpAddress& Http::getHost() const { diff --git a/src/eepp/ui/tools/textureatlasnew.cpp b/src/eepp/ui/tools/textureatlasnew.cpp index 0298eddd3..f7d4c2361 100644 --- a/src/eepp/ui/tools/textureatlasnew.cpp +++ b/src/eepp/ui/tools/textureatlasnew.cpp @@ -11,8 +11,8 @@ namespace EE { namespace UI { namespace Tools { TextureAtlasNew::TextureAtlasNew( TGCreateCb NewTGCb ) : mUIWindow( NULL ), mNewTGCb( NewTGCb ) { mUIWindow = UIWindow::New(); - mUIWindow->setSizeWithDecoration( 378, 303 ) - ->setMinWindowSize( 378, 303 ) + mUIWindow->setSizeWithDecoration( 378, 374 ) + ->setMinWindowSize( 378, 374 ) ->setWinFlags( UI_WIN_CLOSE_BUTTON | UI_WIN_USE_DEFAULT_BUTTONS_ACTIONS | UI_WIN_SHARE_ALPHA_WITH_CHILDS | UI_WIN_MODAL ); @@ -41,7 +41,7 @@ TextureAtlasNew::TextureAtlasNew( TGCreateCb NewTGCb ) : mUIWindow( NULL ), mNew - + @@ -66,9 +66,15 @@ TextureAtlasNew::TextureAtlasNew( TGCreateCb NewTGCb ) : mUIWindow( NULL ), mNew - - - + + + + + + + )xml"; @@ -85,6 +91,10 @@ TextureAtlasNew::TextureAtlasNew( TGCreateCb NewTGCb ) : mUIWindow( NULL ), mNew mUIWindow->bind( "pathInput", mTGPath ); mUIWindow->bind( "openPath", mSetPathButton ); mUIWindow->bind( "textureFilter", mTextureFilter ); + mUIWindow->bind( "forcePow2", mForcePow2 ); + mUIWindow->bind( "scalableSVG", mScalableSVG ); + mUIWindow->bind( "saveExtensions", mSaveExtensions ); + mUIWindow->bind( "allowChilds", mAllowChilds ); std::vector Sizes; @@ -158,9 +168,9 @@ void TextureAtlasNew::textureAtlasSave( const Event* Event ) { : Texture::TextureFilter::Linear; if ( Res1 && Res2 ) { - TexturePacker* texturePacker = - TexturePacker::New( w, h, PixelDensity::fromString( mPixelDensity->getText() ), - false, false, b, textureFilter ); + TexturePacker* texturePacker = TexturePacker::New( + w, h, PixelDensity::fromString( mPixelDensity->getText() ), mForcePow2->isChecked(), + mScalableSVG->isChecked(), b, textureFilter, mAllowChilds->isChecked(), false ); texturePacker->addTexturesPath( mTGPath->getText() ); @@ -178,8 +188,10 @@ void TextureAtlasNew::textureAtlasSave( const Event* Event ) { FPath += "." + ext; } - texturePacker->save( FPath, static_cast( - mSaveFileType->getListBox()->getItemSelectedIndex() ) ); + texturePacker->save( + FPath, + static_cast( mSaveFileType->getListBox()->getItemSelectedIndex() ), + mSaveExtensions->isChecked() ); if ( mNewTGCb ) mNewTGCb( texturePacker ); diff --git a/src/eepp/ui/tools/textureatlasnew.hpp b/src/eepp/ui/tools/textureatlasnew.hpp index c6dc7f4f4..ee7c43154 100644 --- a/src/eepp/ui/tools/textureatlasnew.hpp +++ b/src/eepp/ui/tools/textureatlasnew.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,10 @@ class EE_API TextureAtlasNew { UIDropDownList* mSaveFileType; UIDropDownList* mPixelDensity; UIDropDownList* mTextureFilter; + UICheckBox * mForcePow2; + UICheckBox * mScalableSVG; + UICheckBox * mSaveExtensions; + UICheckBox * mAllowChilds; void windowClose( const Event* Event ); diff --git a/src/eepp/ui/tools/uicolorpicker.cpp b/src/eepp/ui/tools/uicolorpicker.cpp index 382000ad1..3bb7f9675 100644 --- a/src/eepp/ui/tools/uicolorpicker.cpp +++ b/src/eepp/ui/tools/uicolorpicker.cpp @@ -515,11 +515,15 @@ void UIColorPicker::registerEvents() { UI_ANCHOR_BOTTOM ); coverWidget->addEventListener( Event::MouseMove, [&]( const Event* event ) { Vector2i position = reinterpret_cast( event )->getPosition(); - setColor( GLi->readPixel( position.x, position.y ) ); + setColor( GLi->readPixel( + position.x, + event->getNode()->getSceneNode()->getWindow()->getHeight() - position.y ) ); } ); coverWidget->addEventListener( Event::MouseClick, [&]( const Event* event ) { Vector2i position = reinterpret_cast( event )->getPosition(); - setColor( GLi->readPixel( position.x, position.y ) ); + setColor( GLi->readPixel( + position.x, + event->getNode()->getSceneNode()->getWindow()->getHeight() - position.y ) ); event->getNode()->close(); } ); } ); diff --git a/src/eepp/ui/uicheckbox.cpp b/src/eepp/ui/uicheckbox.cpp index 0b00063a9..9ae187562 100644 --- a/src/eepp/ui/uicheckbox.cpp +++ b/src/eepp/ui/uicheckbox.cpp @@ -9,7 +9,7 @@ UICheckBox* UICheckBox::New() { return eeNew( UICheckBox, () ); } -UICheckBox::UICheckBox() : UITextView( "checkbox" ), mActive( false ), mTextSeparation( 4 ) { +UICheckBox::UICheckBox() : UITextView( "checkbox" ), mChecked( false ), mTextSeparation( 4 ) { mActiveButton = UINode::New(); mActiveButton->setVisible( false ); mActiveButton->setEnabled( true ); @@ -132,27 +132,27 @@ Uint32 UICheckBox::onMessage( const NodeMessage* Msg ) { } void UICheckBox::switchState() { - setActive( !mActive ); + setChecked( !mChecked ); } -void UICheckBox::setActive( const bool& active ) { - if ( !active ) { +void UICheckBox::setChecked( const bool& checked ) { + if ( !checked ) { mActiveButton->setVisible( false ); mInactiveButton->setVisible( true ); - mActive = false; + mChecked = false; } else { mActiveButton->setVisible( true ); mInactiveButton->setVisible( false ); - mActive = true; + mChecked = true; } onValueChange(); } -const bool& UICheckBox::isActive() const { - return mActive; +const bool& UICheckBox::isChecked() const { + return mChecked; } void UICheckBox::onPaddingChange() { @@ -188,7 +188,7 @@ void UICheckBox::alignFix() { mAlignOffset = PixelDensity::pxToDp( mRealAlignOffset ); } -UINode* UICheckBox::getActiveButton() const { +UINode* UICheckBox::getCheckedButton() const { return mActiveButton; } @@ -212,7 +212,7 @@ std::string UICheckBox::getPropertyString( const PropertyDefinition* propertyDef switch ( propertyDef->getPropertyId() ) { case PropertyId::Selected: - return isActive() ? "true" : "false"; + return isChecked() ? "true" : "false"; break; default: return UITextView::getPropertyString( propertyDef ); @@ -225,7 +225,7 @@ bool UICheckBox::applyProperty( const StyleSheetProperty& attribute ) { switch ( attribute.getPropertyDefinition()->getPropertyId() ) { case PropertyId::Selected: - setActive( attribute.asBool() ); + setChecked( attribute.asBool() ); break; default: return UITextView::applyProperty( attribute ); @@ -241,7 +241,7 @@ Uint32 UICheckBox::onKeyDown( const KeyEvent& Event ) { if ( Sys::getTicks() - mLastTick > 250 ) { mLastTick = Sys::getTicks(); - setActive( !mActive ); + setChecked( !mChecked ); } } diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 1a3aaf91a..4aa22a50e 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -404,12 +404,11 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles ) { mFontFaces.push_back( font ); } else if ( String::startsWith( path, "http://" ) || String::startsWith( path, "https://" ) ) { - #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN std::string familyName = familyProp.getValue(); Http::getAsync( [&, familyName]( const Http&, Http::Request&, Http::Response& response ) { FontTrueType* font = - FontTrueType::New( String::trim( familyName , '"' ) ); + FontTrueType::New( String::trim( familyName, '"' ) ); if ( !response.getBody().empty() ) { font->loadFromMemory( &response.getBody()[0], @@ -419,7 +418,6 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles ) { } }, URI( path ), Seconds( 5 ) ); - #endif } else if ( VFS::instance()->fileExists( path ) ) { FontTrueType* font = FontTrueType::New( String::trim( familyProp.getValue(), '"' ) ); diff --git a/src/eepp/ui/uitextview.cpp b/src/eepp/ui/uitextview.cpp index a2722a4b5..be8e97c0f 100644 --- a/src/eepp/ui/uitextview.cpp +++ b/src/eepp/ui/uitextview.cpp @@ -387,7 +387,7 @@ Uint32 UITextView::onMouseDoubleClick( const Vector2i& Pos, const Uint32& Flags if ( isTextSelectionEnabled() && ( Flags & EE_BUTTON_LMASK ) ) { Vector2f controlPos( Vector2f( Pos.x, Pos.y ) ); worldToNode( controlPos ); - controlPos = PixelDensity::dpToPx( controlPos ); + controlPos = PixelDensity::dpToPx( controlPos ) - mRealAlignOffset; Int32 curPos = mTextCache->findCharacterFromPos( Vector2i( controlPos.x, controlPos.y ) ); diff --git a/src/eepp/ui/uiwindow.cpp b/src/eepp/ui/uiwindow.cpp index 605c01d66..3d15f2a91 100644 --- a/src/eepp/ui/uiwindow.cpp +++ b/src/eepp/ui/uiwindow.cpp @@ -84,6 +84,12 @@ UIWindow::UIWindow( UIWindow::WindowBaseContainerType type, const StyleConfig& w UIWindow::~UIWindow() { if ( NULL != getUISceneNode() && !SceneManager::instance()->isShootingDown() ) { + if ( NULL != mModalCtrl ) { + mModalCtrl->setEnabled( false ); + mModalCtrl->setVisible( false ); + mModalCtrl->close(); + } + getUISceneNode()->windowRemove( this ); getUISceneNode()->setFocusLastWindow( this ); @@ -275,7 +281,7 @@ void UIWindow::updateWinFlags() { updateDrawInvalidator( true ); - if ( isModal() ) { + if ( isModal() && NULL == mModalCtrl ) { createModalControl(); } @@ -446,13 +452,14 @@ void UIWindow::closeWindow() { if ( NULL != mButtonMinimize ) mButtonMinimize->setEnabled( false ); - if ( Time::Zero != getUISceneNode()->getUIThemeManager()->getControlsFadeOutTime() ) + if ( Time::Zero != getUISceneNode()->getUIThemeManager()->getControlsFadeOutTime() ) { runAction( Actions::Sequence::New( Actions::FadeOut::New( getUISceneNode()->getUIThemeManager()->getControlsFadeOutTime() ), Actions::Close::New() ) ); - else + } else { close(); + } } void UIWindow::close() { diff --git a/src/eepp/window/backend/SDL2/windowsdl2.cpp b/src/eepp/window/backend/SDL2/windowsdl2.cpp index 8c37f6530..999cab8ba 100644 --- a/src/eepp/window/backend/SDL2/windowsdl2.cpp +++ b/src/eepp/window/backend/SDL2/windowsdl2.cpp @@ -18,7 +18,7 @@ #if EE_PLATFORM == EE_PLATFORM_WIN || EE_PLATFORM == EE_PLATFORM_MACOSX || \ defined( EE_X11_PLATFORM ) || EE_PLATFORM == EE_PLATFORM_IOS || \ - EE_PLATFORM == EE_PLATFORM_ANDROID + EE_PLATFORM == EE_PLATFORM_ANDROID || EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN #define SDL2_THREADED_GLCONTEXT #endif @@ -255,10 +255,10 @@ bool WindowSDL::create( WindowSettings Settings, ContextSettings Context ) { setGLConfig(); - Uint32 mTmpFlags = mWindow.Flags; + Uint32 tmpFlags = mWindow.Flags; if ( mWindow.WindowConfig.Style & WindowStyle::Fullscreen ) { - mTmpFlags |= SDL_WINDOW_FULLSCREEN; + tmpFlags |= SDL_WINDOW_FULLSCREEN; } if ( mWindow.ContextConfig.Multisamples > 0 ) { @@ -274,7 +274,7 @@ bool WindowSDL::create( WindowSettings Settings, ContextSettings Context ) { mSDLWindow = SDL_CreateWindow( mWindow.WindowConfig.Caption.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, mWindow.WindowConfig.Width, - mWindow.WindowConfig.Height, mTmpFlags ); + mWindow.WindowConfig.Height, tmpFlags ); if ( NULL == mSDLWindow ) { eePRINTL( "Unable to create window: %s", SDL_GetError() ); @@ -284,15 +284,25 @@ bool WindowSDL::create( WindowSettings Settings, ContextSettings Context ) { return false; } -/// In some platforms it will not create the desired window size, so we query the real window size -/// created +// In some platforms it will not create the desired window size, so we query the real window size +// created #if SDL_VERSION_ATLEAST( 2, 0, 1 ) int w, h; SDL_GL_GetDrawableSize( mSDLWindow, &w, &h ); - mWindow.WindowConfig.Width = w; - mWindow.WindowConfig.Height = h; - mWindow.WindowSize = Sizei( mWindow.WindowConfig.Width, mWindow.WindowConfig.Height ); + if ( w > 0 && h > 0 ) { + mWindow.WindowConfig.Width = w; + mWindow.WindowConfig.Height = h; + mWindow.WindowSize = Sizei( mWindow.WindowConfig.Width, mWindow.WindowConfig.Height ); + } else { + eePRINTL( "Window failed to create!" ); + + if ( NULL != SDL_GetError() ) { + eePRINTL( "Error: %s", SDL_GetError() ); + } + + return false; + } #endif #if EE_PLATFORM == EE_PLATFORM_ANDROID || EE_PLATFORM == EE_PLATFORM_IOS @@ -360,7 +370,9 @@ bool WindowSDL::create( WindowSettings Settings, ContextSettings Context ) { return false; } +#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN SDL_GL_SetSwapInterval( ( mWindow.ContextConfig.VSync ? 1 : 0 ) ); // VSync +#endif SDL_GL_MakeCurrent( mSDLWindow, mGLContext ); diff --git a/src/test/eetest.cpp b/src/test/eetest.cpp index 154d3c45f..b12949132 100644 --- a/src/test/eetest.cpp +++ b/src/test/eetest.cpp @@ -1257,7 +1257,7 @@ void EETest::onQuitClick( const Event* event ) { void EETest::showMenu() { if ( NULL != Menu && Menu->show() ) { - Vector2f Pos = mWindow->getInput()->getMousePosf(); + Vector2f Pos = KM->getMousePosf(); UIMenu::fixMenuPos( Pos, Menu ); Menu->setPixelsPosition( Pos ); } @@ -1895,9 +1895,7 @@ void EETest::render() { mInfoText.draw( 6.f, 6.f ); - SceneManager::instance()->update(); SceneManager::instance()->draw(); - Con.draw(); } @@ -1911,6 +1909,17 @@ void EETest::input() { if ( KM->isKeyUp( KEY_F1 ) ) Graphics::ShaderProgramManager::instance()->reload(); + UISceneNode * uiSceneNode = SceneManager::instance()->getUISceneNode(); + + if ( KM->isKeyUp( KEY_F6 ) ) + uiSceneNode->setHighlightOver( !uiSceneNode->getHighlightOver() ); + + if ( KM->isKeyUp( KEY_F7 ) ) + uiSceneNode->setDrawBoxes( !uiSceneNode->getDrawBoxes() ); + + if ( KM->isKeyUp( KEY_F8 ) ) + uiSceneNode->setDrawDebugData( !uiSceneNode->getDrawDebugData() ); + if ( !mWindow->isVisible() ) { mWasMinimized = true; @@ -2122,12 +2131,14 @@ void EETest::input() { } void EETest::update() { - mWindow->clear(); - et = mWindow->getElapsed(); + SceneManager::instance()->update(); + input(); + mWindow->clear(); + render(); #if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN