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