X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=adaptors%2Fecore%2Fcommon%2Fecore-indicator-impl.cpp;h=574e0bd6eb542b1ff8f0231499caf09ff6c34644;hb=947713e1a33face353c1187925296ba3a596ddb3;hp=e44f2ff0dfcc3336035d51370fcdcc17eeaaada3;hpb=cf37db548d7b1c8c4e5d0295eb46c38c57893bc0;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/adaptors/ecore/common/ecore-indicator-impl.cpp b/adaptors/ecore/common/ecore-indicator-impl.cpp index e44f2ff..574e0bd 100644 --- a/adaptors/ecore/common/ecore-indicator-impl.cpp +++ b/adaptors/ecore/common/ecore-indicator-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,22 +19,31 @@ #include "ecore-indicator-impl.h" // EXTERNAL INCLUDES +// Ecore is littered with C style cast +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" #include #include +#ifdef WAYLAND +#include +#else +#include +#endif #include #include #include #include #include +#include +#include #include #include #include #include -#include -#include #include +#include #include @@ -95,6 +104,50 @@ const char* BACKGROUND_FRAGMENT_SHADER = MAKE_SHADER( } ); +const char* FOREGROUND_VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + varying mediump vec2 vTexCoord;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform mediump vec4 sTextureRect;\n + \n + void main()\n + {\n + gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n + vTexCoord = aPosition + vec2(0.5);\n + }\n +); + +const char* FOREGROUND_FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord );\n // the foreground does not apply actor color + }\n +); + +Dali::Geometry CreateQuadGeometry() +{ + Dali::Property::Map quadVertexFormat; + quadVertexFormat["aPosition"] = Dali::Property::VECTOR2; + Dali::PropertyBuffer vertexData = Dali::PropertyBuffer::New( quadVertexFormat ); + + const float halfQuadSize = .5f; + struct QuadVertex { Dali::Vector2 position; }; + QuadVertex quadVertexData[4] = { + { Dali::Vector2(-halfQuadSize, -halfQuadSize) }, + { Dali::Vector2(-halfQuadSize, halfQuadSize) }, + { Dali::Vector2( halfQuadSize, -halfQuadSize) }, + { Dali::Vector2( halfQuadSize, halfQuadSize) } }; + vertexData.SetData(quadVertexData, 4); + + Dali::Geometry quad = Dali::Geometry::New(); + quad.AddVertexBuffer( vertexData ); + quad.SetType( Dali::Geometry::TRIANGLE_STRIP ); + return quad; +} const float OPAQUE_THRESHOLD(0.99f); const float TRANSPARENT_THRESHOLD(0.05f); @@ -104,6 +157,8 @@ const char* INDICATOR_SERVICE_NAME("elm_indicator"); // Copied from ecore_evas_extn_engine.h +#define NBUF 2 + enum // opcodes { OP_RESIZE, @@ -131,7 +186,8 @@ enum // opcodes OP_EV_KEY_DOWN, OP_EV_HOLD, OP_MSG_PARENT, - OP_MSG + OP_MSG, + OP_PIXMAP_REF, }; // Copied from elm_conform.c @@ -203,9 +259,9 @@ struct IpcDataEvMouseMove unsigned int timestamp; Evas_Event_Flags event_flags; - IpcDataEvMouseMove(const Dali::TouchPoint& touchPoint, unsigned long timestamp) - : x(static_cast(touchPoint.local.x)), - y(static_cast(touchPoint.local.y)), + IpcDataEvMouseMove(const Dali::Vector2& touchPoint, unsigned long timestamp) + : x(static_cast(touchPoint.x)), + y(static_cast(touchPoint.y)), flags(EVAS_BUTTON_NONE), mask(0), timestamp(static_cast(timestamp)), @@ -228,6 +284,59 @@ struct IpcDataEvMouseOut } }; +#ifdef ENABLE_INDICATOR_IMAGE_SAVING + +void SaveIndicatorImage( Dali::NativeImageSourcePtr nativeImageSource ) +{ + // Save image data to disk in BMP form. + static int gFilenameCounter = 0; + static const char bmpHeader[] = { + 0x42, 0x4d, 0x0a, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x7c, 0x00, + 0x00, 0x00, + 0xe0, 0x01, 0x00, 0x00, // Width (480) + 0x1b, 0x00, 0x00, 0x00, // Height ( 27) + 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x80, 0xca, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + // This is a BMP header with width & height hard-coded in. + // The data was first determined by dumping the raw data and inspecting in GIMP, before creating this header data. + std::vector buffer; + unsigned int w = 0; + unsigned int h = 0; + Dali::Pixel::Format pixelFormat; + if( nativeImageSource->GetPixels( buffer, w, h, pixelFormat ) ) + { + int imageSize = w * h * 4; + std::stringstream fileName; + // Give each file an incremental filename. + fileName << "/opt/usr/media/Images/out-" << std::setfill( '0' ) << std::setw( 5 ) << gFilenameCounter << ".bmp"; + + std::ofstream outfile( fileName.str().c_str(), std::ofstream::binary ); + if( outfile.is_open() ) + { + DALI_LOG_WARNING( "Saving Indicator Image w:%d, h:%d, %s\n", w, h, fileName.str().c_str() ); + + outfile.write( bmpHeader, sizeof( bmpHeader ) / sizeof( bmpHeader[0] ) ); // Size of the BMP header. + outfile.write( (const char*)buffer.data(), imageSize ); + outfile.close(); + gFilenameCounter++; + } + else + { + DALI_LOG_ERROR( "COULD NOT OPEN FOR SAVING: %s\n", fileName.str().c_str() ); + } + } +} + +#endif + } // anonymous namespace @@ -241,6 +350,107 @@ namespace Adaptor Debug::Filter* gIndicatorLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_INDICATOR"); #endif +// Impl to hide EFL implementation. + +struct Indicator::Impl +{ + enum // operation mode + { + INDICATOR_HIDE, + INDICATOR_STAY_WITH_DURATION + }; + + /** + * Constructor + */ + Impl(Indicator* indicator) + : mIndicator(indicator), + mEcoreEventHandler(NULL) + { +#if defined(DALI_PROFILE_MOBILE) +#if defined(WAYLAND) + mEcoreEventHandler = ecore_event_handler_add(ECORE_WL_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this); +#else + mEcoreEventHandler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, EcoreEventClientMessage, this); +#endif +#endif // WAYLAND && DALI_PROFILE_MOBILE + } + + /** + * Destructor + */ + ~Impl() + { + if ( mEcoreEventHandler ) + { + ecore_event_handler_del(mEcoreEventHandler); + } + } + + static void SetIndicatorVisibility( void* data, int operation ) + { + Indicator::Impl* indicatorImpl((Indicator::Impl*)data); + + if ( indicatorImpl == NULL || indicatorImpl->mIndicator == NULL) + { + return; + } + if ( operation == INDICATOR_STAY_WITH_DURATION ) + { + // if indicator is not showing, INDICATOR_FLICK_DONE is given + if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO && + !indicatorImpl->mIndicator->mIsShowing ) + { + indicatorImpl->mIndicator->ShowIndicator( AUTO_INDICATOR_STAY_DURATION ); + } + } + else if( operation == INDICATOR_HIDE ) + { + if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO && + indicatorImpl->mIndicator->mIsShowing ) + { + indicatorImpl->mIndicator->ShowIndicator( HIDE_NOW ); + } + } + } +#if defined(DALI_PROFILE_MOBILE) +#if defined(WAYLAND) + /** + * Called when the Ecore indicator event is received. + */ + static Eina_Bool EcoreEventIndicator( void* data, int type, void* event ) + { + SetIndicatorVisibility( data, INDICATOR_STAY_WITH_DURATION ); + return ECORE_CALLBACK_PASS_ON; + } +#else + /** + * Called when the client messages (i.e. quick panel state) are received. + */ + static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event ) + { + Ecore_X_Event_Client_Message* clientMessageEvent((Ecore_X_Event_Client_Message*)event); + + if ( clientMessageEvent != NULL ) + { + if (clientMessageEvent->message_type == ECORE_X_ATOM_E_INDICATOR_FLICK_DONE) + { + SetIndicatorVisibility( data, INDICATOR_STAY_WITH_DURATION ); + } + else if ( clientMessageEvent->message_type == ECORE_X_ATOM_E_MOVE_QUICKPANEL_STATE ) + { + SetIndicatorVisibility( data, INDICATOR_HIDE ); + } + } + return ECORE_CALLBACK_PASS_ON; + } +#endif +#endif // WAYLAND && DALI_PROFILE_MOBILE + + // Data + Indicator* mIndicator; + Ecore_Event_Handler* mEcoreEventHandler; +}; Indicator::LockFile::LockFile(const std::string filename) : mFilename(filename), @@ -258,7 +468,10 @@ Indicator::LockFile::LockFile(const std::string filename) Indicator::LockFile::~LockFile() { // Closing file descriptor also unlocks file. - close( mFileDescriptor ); + if( mFileDescriptor > 0 ) + { + close( mFileDescriptor ); + } } bool Indicator::LockFile::Lock() @@ -268,21 +481,27 @@ bool Indicator::LockFile::Lock() bool locked = false; if( mFileDescriptor > 0 ) { - if( lockf( mFileDescriptor, F_LOCK, 0 ) == 0 ) // Note, operation may block. + struct flock filelock; + + filelock.l_type = F_RDLCK; + filelock.l_whence = SEEK_SET; + filelock.l_start = 0; + filelock.l_len = 0; + if( fcntl( mFileDescriptor, F_SETLKW, &filelock ) == -1 ) { - locked = true; + mErrorThrown = true; + DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() ); } else { - if( errno == EBADF ) - { - // file descriptor is no longer valid or not writable - mFileDescriptor = 0; - mErrorThrown = true; - DALI_LOG_ERROR( "### Cannot lock indicator: bad file descriptor for %s ###\n", mFilename.c_str() ); - } + locked = true; } } + else + { + mErrorThrown = true; + DALI_LOG_ERROR( "### Invalid fd ###\n" ); + } return locked; } @@ -290,14 +509,19 @@ bool Indicator::LockFile::Lock() void Indicator::LockFile::Unlock() { DALI_LOG_TRACE_METHOD( gIndicatorLogFilter ); - if( lockf( mFileDescriptor, F_ULOCK, 0 ) != 0 ) + + if( mFileDescriptor > 0 ) { - if( errno == EBADF ) + struct flock filelock; + + filelock.l_type = F_UNLCK; + filelock.l_whence = SEEK_SET; + filelock.l_start = 0; + filelock.l_len = 0; + if (fcntl(mFileDescriptor, F_SETLKW, &filelock) == -1) { - // file descriptor is no longer valid or not writable - mFileDescriptor = 0; mErrorThrown = true; - DALI_LOG_ERROR( "### Cannot unlock indicator: bad file descriptor for %s\n", mFilename.c_str() ); + DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() ); } } } @@ -334,6 +558,7 @@ bool Indicator::ScopedLock::IsLocked() Indicator::Indicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) : mPixmap( 0 ), + mGestureDeltaY( 0.0f ), mGestureDetected( false ), mConnection( this ), mOpacityMode( Dali::Window::OPAQUE ), @@ -347,38 +572,23 @@ Indicator::Indicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientat mVisible( Dali::Window::INVISIBLE ), mIsShowing( true ), mIsAnimationPlaying( false ), - mCurrentSharedFile( 0 ) + mCurrentSharedFile( 0 ), + mSharedBufferType( BUFFER_TYPE_SHM ), + mImpl( NULL ), + mBackgroundVisible( false ), + mTopMargin( 0 ) { - mIndicatorImageActor = Dali::ImageActor::New(); - mIndicatorImageActor.SetBlendFunc( Dali::BlendingFactor::ONE, Dali::BlendingFactor::ONE_MINUS_SRC_ALPHA, - Dali::BlendingFactor::ONE, Dali::BlendingFactor::ONE ); - - mIndicatorImageActor.SetParentOrigin( ParentOrigin::TOP_CENTER ); - mIndicatorImageActor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - mIndicatorImageActor.SetSortModifier( 1.0f ); + mIndicatorContentActor = Dali::Actor::New(); + mIndicatorContentActor.SetParentOrigin( ParentOrigin::TOP_CENTER ); + mIndicatorContentActor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); // Indicator image handles the touch event including "leave" - mIndicatorImageActor.SetLeaveRequired( true ); - mIndicatorImageActor.TouchedSignal().Connect( this, &Indicator::OnTouched ); - - mBackgroundActor = Dali::Actor::New(); - mBackgroundActor.SetParentOrigin( ParentOrigin::TOP_CENTER ); - mBackgroundActor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - mBackgroundActor.SetColor( Color::BLACK ); - - mIndicatorImageContainerActor = Dali::Actor::New(); - mIndicatorImageContainerActor.SetParentOrigin( ParentOrigin::TOP_CENTER ); - mIndicatorImageContainerActor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - mIndicatorImageContainerActor.Add( mBackgroundActor ); - mIndicatorImageContainerActor.Add( mIndicatorImageActor ); + mIndicatorContentActor.SetLeaveRequired( true ); + mIndicatorContentActor.TouchSignal().Connect( this, &Indicator::OnTouch ); + mIndicatorContentActor.SetColor( Color::BLACK ); mIndicatorActor = Dali::Actor::New(); - mIndicatorActor.Add( mIndicatorImageContainerActor ); - - if( mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE ) - { - mBackgroundActor.SetVisible( false ); - } + mIndicatorActor.Add( mIndicatorContentActor ); // Event handler to find out flick down gesture mEventActor = Dali::Actor::New(); @@ -403,13 +613,22 @@ Indicator::Indicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientat } // hide the indicator by default mIndicatorActor.SetVisible( false ); + + // create impl to handle ecore event + mImpl = new Impl(this); } Indicator::~Indicator() { + if(mImpl) + { + delete mImpl; + mImpl = NULL; + } + if(mEventActor) { - mEventActor.TouchedSignal().Disconnect( this, &Indicator::OnTouched ); + mEventActor.TouchSignal().Disconnect( this, &Indicator::OnTouch ); } Disconnect(); } @@ -438,9 +657,13 @@ void Indicator::Open( Dali::Window::WindowOrientation orientation ) Connect(); // Change background visibility depending on orientation - if(mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE ) + if( mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE ) { - mBackgroundActor.SetVisible( false ); + if( mBackgroundRenderer ) + { + mIndicatorContentActor.RemoveRenderer( mBackgroundRenderer ); + mBackgroundVisible = false; + } } else { @@ -461,52 +684,46 @@ void Indicator::Close() } } - Dali::Image emptyImage; - mIndicatorImageActor.SetImage(emptyImage); + Dali::Texture emptyTexture; + SetForegroundImage( emptyTexture ); } void Indicator::SetOpacityMode( Dali::Window::IndicatorBgOpacity mode ) { mOpacityMode = mode; - //@todo replace with a gradient renderer when that is implemented Dali::Geometry geometry = CreateBackgroundGeometry(); if( geometry ) { - mBackgroundActor.SetVisible( true ); - - if( mBackgroundActor.GetRendererCount() > 0 ) + if( mBackgroundRenderer ) { - Dali::Renderer renderer = mBackgroundActor.GetRendererAt( 0 ); - if( renderer ) + if( mBackgroundRenderer.GetGeometry() != geometry ) { - if( renderer.GetGeometry() == geometry ) - { - return; - } - else - { - renderer.SetGeometry( geometry ); - } + mBackgroundRenderer.SetGeometry( geometry ); } } else { - if( !mBackgroundMaterial ) + if( !mBackgroundShader ) { - Dali::Shader shader = Dali::Shader::New( BACKGROUND_VERTEX_SHADER, BACKGROUND_FRAGMENT_SHADER, Dali::Shader::HINT_OUTPUT_IS_TRANSPARENT ); - mBackgroundMaterial = Dali::Material::New( shader ); + mBackgroundShader = Dali::Shader::New( BACKGROUND_VERTEX_SHADER, BACKGROUND_FRAGMENT_SHADER, Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT ); } - Dali::Renderer renderer = Dali::Renderer::New( geometry, mBackgroundMaterial ); + mBackgroundRenderer = Dali::Renderer::New( geometry, mBackgroundShader ); + } - mBackgroundActor.AddRenderer( renderer ); + if( !mBackgroundVisible ) + { + mIndicatorContentActor.AddRenderer( mBackgroundRenderer ); + mBackgroundVisible = true; } } - else + else if( mBackgroundRenderer ) { - mBackgroundActor.SetVisible( false ); + mIndicatorContentActor.RemoveRenderer( mBackgroundRenderer ); + mBackgroundVisible = false; } + UpdateTopMargin(); } void Indicator::SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool forceUpdate ) @@ -518,14 +735,28 @@ void Indicator::SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool { UpdateImageData( mCurrentSharedFile ); } - if ( visibleMode != Dali::Window::INVISIBLE ) + + if ( visibleMode == Dali::Window::INVISIBLE ) + { + if (mServerConnection) + { + mServerConnection->SendEvent( OP_HIDE, NULL, 0 ); + } + } + else { mIndicatorActor.SetVisible( true ); + + if( mServerConnection ) + { + mServerConnection->SendEvent( OP_SHOW, NULL, 0 ); + } } mVisible = visibleMode; + UpdateTopMargin(); - if( mIndicatorImageActor.GetImage() ) + if( mForegroundRenderer && mForegroundRenderer.GetTextures().GetTexture( 0u ) ) { if( CheckVisibleState() && mVisible == Dali::Window::AUTO ) { @@ -543,6 +774,10 @@ void Indicator::SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool ShowIndicator( HIDE_NOW ); } } + else + { + mIsShowing = false; + } } } @@ -563,21 +798,19 @@ bool Indicator::SendMessage( int messageDomain, int messageId, const void *data, } } -bool Indicator::OnTouched(Dali::Actor indicator, const Dali::TouchEvent& touchEvent) +bool Indicator::OnTouch(Dali::Actor indicator, const Dali::TouchData& touchData) { if( mServerConnection ) { - const TouchPoint& touchPoint = touchEvent.GetPoint( 0 ); - // Send touch event to indicator server when indicator is showing if( CheckVisibleState() || mIsShowing ) { - switch( touchPoint.state ) + switch( touchData.GetState(0) ) { - case Dali::TouchPoint::Down: + case Dali::PointState::DOWN: { - IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time ); - IpcDataEvMouseDown ipcDown( touchEvent.time ); + IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() ); + IpcDataEvMouseDown ipcDown( touchData.GetTime() ); mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) ); mServerConnection->SendEvent( OP_EV_MOUSE_DOWN, &ipcDown, sizeof(ipcDown) ); @@ -589,16 +822,17 @@ bool Indicator::OnTouched(Dali::Actor indicator, const Dali::TouchEvent& touchEv } break; - case Dali::TouchPoint::Motion: + case Dali::PointState::MOTION: { - IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time ); + IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() ); mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) ); } break; - case Dali::TouchPoint::Up: + case Dali::PointState::UP: + case Dali::PointState::INTERRUPTED: { - IpcDataEvMouseUp ipcUp( touchEvent.time ); + IpcDataEvMouseUp ipcUp( touchData.GetTime() ); mServerConnection->SendEvent( OP_EV_MOUSE_UP, &ipcUp, sizeof(ipcUp) ); if( mVisible == Dali::Window::AUTO ) @@ -611,9 +845,9 @@ bool Indicator::OnTouched(Dali::Actor indicator, const Dali::TouchEvent& touchEv case Dali::TouchPoint::Leave: { - IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time ); + IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() ); mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) ); - IpcDataEvMouseUp ipcOut( touchEvent.time ); + IpcDataEvMouseUp ipcOut( touchData.GetTime() ); mServerConnection->SendEvent( OP_EV_MOUSE_OUT, &ipcOut, sizeof(ipcOut) ); } break; @@ -714,11 +948,10 @@ void Indicator::Resize( int width, int height ) mImageWidth = width; mImageHeight = height; - mIndicatorImageActor.SetSize( mImageWidth, mImageHeight ); + mIndicatorContentActor.SetSize( mImageWidth, mImageHeight ); mIndicatorActor.SetSize( mImageWidth, mImageHeight ); mEventActor.SetSize(mImageWidth, mImageHeight); - mBackgroundActor.SetSize( mImageWidth, mImageHeight ); - mIndicatorImageContainerActor.SetSize( mImageWidth, mImageHeight ); + UpdateTopMargin(); } } @@ -793,6 +1026,11 @@ void Indicator::LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent ) // epcEvent->ref_to == sys // epcEvent->response == buffer num + if ( mSharedBufferType != BUFFER_TYPE_SHM ) + { + return ; + } + int n = epcEvent->response; if( n >= 0 && n < SHARED_FILE_NUMBER ) @@ -823,21 +1061,11 @@ void Indicator::LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent ) { DALI_LOG_ERROR( "### Indicator error: Cannot open lock file %s ###\n", mSharedFileInfo[n].mLockFileName.c_str() ); } - - CreateNewImage( n ); - - if( CheckVisibleState() ) - { - // set default indicator type (enable the quick panel) - OnIndicatorTypeChanged( INDICATOR_TYPE_1 ); - } else { - // set default indicator type (disable the quick panel) - OnIndicatorTypeChanged( INDICATOR_TYPE_2 ); + CreateNewImage( n ); + UpdateVisibility(); } - - SetVisible(mVisible, true); } } } @@ -846,38 +1074,53 @@ void Indicator::LoadPixmapImage( Ecore_Ipc_Event_Server_Data *epcEvent ) { DALI_LOG_TRACE_METHOD( gIndicatorLogFilter ); - // epcEvent->ref == w - // epcEvent->ref_to == h - // epcEvent->response == alpha - // epcEvent->data = pixmap id + // epcEvent->ref == pixmap id + // epcEvent->ref_to == type + // epcEvent->response == buffer num - if( ( epcEvent->data ) && - (epcEvent->size >= (int)sizeof(PixmapId)) ) + if( (epcEvent->ref > 0) && (epcEvent->ref_to > 0) ) { + mSharedBufferType = (BufferType)(epcEvent->ref_to); + ClearSharedFileInfo(); - if( (epcEvent->ref > 0) && (epcEvent->ref_to > 0) ) - { - mImageWidth = epcEvent->ref; - mImageHeight = epcEvent->ref_to; + mPixmap = static_cast(epcEvent->ref); + DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "mPixmap [%x]", mPixmap); - mPixmap = *(static_cast(epcEvent->data)); - CreateNewPixmapImage(); + CreateNewPixmapImage(); + UpdateVisibility(); + } +} - if( CheckVisibleState() ) - { - // set default indicator type (enable the quick panel) - OnIndicatorTypeChanged( INDICATOR_TYPE_1 ); - } - else - { - // set default indicator type (disable the quick panel) - OnIndicatorTypeChanged( INDICATOR_TYPE_2 ); - } +void Indicator::UpdateTopMargin() +{ + int newMargin = (mVisible == Dali::Window::VISIBLE && mOpacityMode == Dali::Window::OPAQUE) ? mImageHeight : 0; + if (mTopMargin != newMargin) + { + mTopMargin = newMargin; + mAdaptor->IndicatorSizeChanged( mTopMargin ); + } +} - SetVisible(mVisible, true); - } +void Indicator::UpdateVisibility() +{ + if( CheckVisibleState() ) + { + // set default indicator type (enable the quick panel) + OnIndicatorTypeChanged( INDICATOR_TYPE_1 ); + } + else + { + // set default indicator type (disable the quick panel) + OnIndicatorTypeChanged( INDICATOR_TYPE_2 ); } + + if( !mIsShowing ) + { + mIndicatorContentActor.SetPosition( 0.0f, -mImageHeight, 0.0f ); + } + + SetVisible(mVisible, true); } void Indicator::UpdateImageData( int bufferNumber ) @@ -915,7 +1158,7 @@ bool Indicator::CopyToBuffer( int bufferNumber ) else if( scopedLock.IsLocked() ) { unsigned char *src = mSharedFileInfo[bufferNumber].mSharedFile->GetAddress(); - size_t size = mSharedFileInfo[bufferNumber].mImageWidth * mSharedFileInfo[bufferNumber].mImageHeight * 4; + size_t size = static_cast< size_t >( mSharedFileInfo[bufferNumber].mImageWidth ) * mSharedFileInfo[bufferNumber].mImageHeight * 4; if( mIndicatorBuffer->UpdatePixels( src, size ) ) { @@ -933,14 +1176,18 @@ void Indicator::CreateNewPixmapImage() DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "W:%d H:%d", mImageWidth, mImageHeight ); Dali::NativeImageSourcePtr nativeImageSource = Dali::NativeImageSource::New( mPixmap ); +#ifdef ENABLE_INDICATOR_IMAGE_SAVING + SaveIndicatorImage( nativeImageSource ); +#endif + if( nativeImageSource ) { - mIndicatorImageActor.SetImage( Dali::NativeImage::New(*nativeImageSource) ); - mIndicatorImageActor.SetSize( mImageWidth, mImageHeight ); + Dali::Texture texture = Dali::Texture::New( *nativeImageSource ); + SetForegroundImage( texture ); + mIndicatorContentActor.SetSize( mImageWidth, mImageHeight ); mIndicatorActor.SetSize( mImageWidth, mImageHeight ); - mEventActor.SetSize(mImageWidth, mImageHeight); - mBackgroundActor.SetSize( mImageWidth, mImageHeight ); - mIndicatorImageContainerActor.SetSize( mImageWidth, mImageHeight ); + mEventActor.SetSize( mImageWidth, mImageHeight ); + UpdateTopMargin(); } else { @@ -959,26 +1206,24 @@ void Indicator::CreateNewImage( int bufferNumber ) { DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "W:%d H:%d", mSharedFileInfo[bufferNumber].mImageWidth, mSharedFileInfo[bufferNumber].mImageHeight ); mIndicatorBuffer = new IndicatorBuffer( mAdaptor, mSharedFileInfo[bufferNumber].mImageWidth, mSharedFileInfo[bufferNumber].mImageHeight, Pixel::BGRA8888 ); - Dali::Image image = Dali::NativeImage::New( mIndicatorBuffer->GetNativeImage() ); + bool success = false; if( CopyToBuffer( bufferNumber ) ) // Only create images if we have valid image buffer { - mIndicatorImageActor.SetImage( image ); - } - else - { - DALI_LOG_WARNING("### Cannot create indicator image - disconnecting ###\n"); - Disconnect(); - if( mObserver != NULL ) + Dali::Texture texture = Dali::Texture::New( mIndicatorBuffer->GetNativeImage() ); + if( texture ) { - mObserver->IndicatorClosed( this ); + SetForegroundImage( texture ); + success = true; } - // Don't do connection in this callback - strange things happen! - StartReconnectionTimer(); + } + + if( !success ) + { + DALI_LOG_WARNING("### Cannot create indicator image ###\n"); } } -//@todo replace with a gradient renderer when that is implemented Dali::Geometry Indicator::CreateBackgroundGeometry() { switch( mOpacityMode ) @@ -1025,9 +1270,9 @@ Dali::Geometry Indicator::CreateBackgroundGeometry() // Create indices unsigned int numIndices = 2 * 3 * NUM_GRADIENT_INTERVALS; - unsigned int indices[ numIndices ]; + unsigned short indices[ numIndices ]; - unsigned int* currentIndex = indices; + unsigned short* currentIndex = indices; for( int y = 0; y < NUM_GRADIENT_INTERVALS; ++y ) { *currentIndex++ = (2 * y); @@ -1042,18 +1287,13 @@ Dali::Geometry Indicator::CreateBackgroundGeometry() Dali::Property::Map vertexFormat; vertexFormat[ "aPosition" ] = Dali::Property::VECTOR2; vertexFormat[ "aAlpha" ] = Dali::Property::FLOAT; - Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat, numVertices ); - vertexPropertyBuffer.SetData( vertices ); - - Dali::Property::Map indexFormat; - indexFormat[ "indices" ] = Dali::Property::INTEGER; - Dali::PropertyBuffer indexPropertyBuffer = Dali::PropertyBuffer::New( indexFormat, numIndices ); - indexPropertyBuffer.SetData( indices ); + Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat ); + vertexPropertyBuffer.SetData( vertices, numVertices ); // Create the geometry object mTranslucentGeometry = Dali::Geometry::New(); mTranslucentGeometry.AddVertexBuffer( vertexPropertyBuffer ); - mTranslucentGeometry.SetIndexBuffer( indexPropertyBuffer ); + mTranslucentGeometry.SetIndexBuffer( &indices[0], numIndices ); } return mTranslucentGeometry; @@ -1072,23 +1312,19 @@ Dali::Geometry Indicator::CreateBackgroundGeometry() { Vector2( -0.5f, 0.5f ), 1.0f }, { Vector2( 0.5f, 0.5f ), 1.0f } }; // Create indices - unsigned int indices[ 6 ] = { 0, 3, 1, 0, 2, 3 }; + unsigned short indices[ 6 ] = { 0, 3, 1, 0, 2, 3 }; Dali::Property::Map vertexFormat; vertexFormat[ "aPosition" ] = Dali::Property::VECTOR2; vertexFormat[ "aAlpha" ] = Dali::Property::FLOAT; - Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat, 4 ); - vertexPropertyBuffer.SetData( vertices ); + Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat ); + vertexPropertyBuffer.SetData( vertices, 4 ); - Dali::Property::Map indexFormat; - indexFormat[ "indices" ] = Dali::Property::INTEGER; - Dali::PropertyBuffer indexPropertyBuffer = Dali::PropertyBuffer::New( indexFormat, 6 ); - indexPropertyBuffer.SetData( indices ); // Create the geometry object mSolidGeometry = Dali::Geometry::New(); mSolidGeometry.AddVertexBuffer( vertexPropertyBuffer ); - mSolidGeometry.SetIndexBuffer( indexPropertyBuffer ); + mSolidGeometry.SetIndexBuffer( &indices[0], 6 ); } return mSolidGeometry; @@ -1099,6 +1335,45 @@ Dali::Geometry Indicator::CreateBackgroundGeometry() return Dali::Geometry(); } +void Indicator::SetForegroundImage( Dali::Texture texture ) +{ + if( !mForegroundRenderer && texture ) + { + // Create Shader + Dali::Shader shader = Dali::Shader::New( FOREGROUND_VERTEX_SHADER, FOREGROUND_FRAGMENT_SHADER ); + + // Create renderer from geometry and material + Dali::Geometry quad = CreateQuadGeometry(); + mForegroundRenderer = Dali::Renderer::New( quad, shader ); + // Make sure the foreground stays in front of the background + mForegroundRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, 1.f ); + + // Set blend function + mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB, Dali::BlendFactor::ONE ); + mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB, Dali::BlendFactor::ONE_MINUS_SRC_ALPHA ); + mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA, Dali::BlendFactor::ONE ); + mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA, Dali::BlendFactor::ONE ); + + // Create a texture-set and add to renderer + + Dali::TextureSet textureSet = Dali::TextureSet::New(); + textureSet.SetTexture( 0u, texture ); + mForegroundRenderer.SetTextures( textureSet ); + + mIndicatorContentActor.AddRenderer( mForegroundRenderer ); + } + else if( mForegroundRenderer ) + { + Dali::TextureSet textureSet = mForegroundRenderer.GetTextures(); + textureSet.SetTexture( 0u, texture ); + } + + if( mImageWidth == 0 && mImageHeight == 0 && texture) + { + Resize( texture.GetWidth(), texture.GetHeight() ); + } +} + void Indicator::OnIndicatorTypeChanged( Type indicatorType ) { if( mObserver != NULL ) @@ -1148,6 +1423,12 @@ void Indicator::DataReceived( void* event ) LoadSharedImage( epcEvent ); break; } + case OP_PIXMAP_REF: + { + DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_PIXMAP_REF\n" ); + LoadPixmapImage( epcEvent ); + break; + } case OP_RESIZE: { DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_RESIZE\n" ); @@ -1189,7 +1470,7 @@ void Indicator::DataReceived( void* event ) if (msgDataSize != (int)sizeof(IpcIndicatorDataAnimation)) { - DALI_LOG_ERROR("Message data is incorrect"); + DALI_LOG_ERROR("Message data is incorrect\n"); break; } @@ -1201,7 +1482,6 @@ void Indicator::DataReceived( void* event ) } break; } - } } break; @@ -1226,7 +1506,8 @@ bool Indicator::CheckVisibleState() { if( mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE - || (mVisible != Dali::Window::VISIBLE) ) + || (mVisible == Dali::Window::INVISIBLE) + || (mVisible == Dali::Window::AUTO && !mIsShowing) ) { return false; } @@ -1277,9 +1558,11 @@ void Indicator::ShowIndicator(float duration) } else { + mIndicatorAnimation.Clear(); + if( EqualsZero(duration) ) { - mIndicatorAnimation.AnimateTo( Property( mIndicatorImageContainerActor, Dali::Actor::Property::POSITION ), Vector3(0, -mImageHeight, 0), Dali::AlphaFunction::EASE_OUT ); + mIndicatorAnimation.AnimateTo( Property( mIndicatorContentActor, Dali::Actor::Property::POSITION ), Vector3(0, -mImageHeight, 0), Dali::AlphaFunction::EASE_OUT ); mIsShowing = false; @@ -1287,7 +1570,7 @@ void Indicator::ShowIndicator(float duration) } else { - mIndicatorAnimation.AnimateTo( Property( mIndicatorImageContainerActor, Dali::Actor::Property::POSITION ), Vector3(0, 0, 0), Dali::AlphaFunction::EASE_OUT ); + mIndicatorAnimation.AnimateTo( Property( mIndicatorContentActor, Dali::Actor::Property::POSITION ), Vector3(0, 0, 0), Dali::AlphaFunction::EASE_OUT ); mIsShowing = true; @@ -1311,7 +1594,7 @@ void Indicator::ShowIndicator(float duration) if( mVisible == Dali::Window::AUTO ) { // check the stage touch - Dali::Stage::GetCurrent().TouchedSignal().Connect( this, &Indicator::OnStageTouched ); + Dali::Stage::GetCurrent().TouchSignal().Connect( this, &Indicator::OnStageTouch ); } } else @@ -1324,7 +1607,7 @@ void Indicator::ShowIndicator(float duration) if( mVisible == Dali::Window::AUTO ) { // check the stage touch - Dali::Stage::GetCurrent().TouchedSignal().Disconnect( this, &Indicator::OnStageTouched ); + Dali::Stage::GetCurrent().TouchSignal().Disconnect( this, &Indicator::OnStageTouch ); } } } @@ -1341,81 +1624,31 @@ void Indicator::OnAnimationFinished(Dali::Animation& animation) { mIsAnimationPlaying = false; // once animation is finished and indicator is hidden, take it off stage - if( !mIsShowing ) + if( mObserver != NULL ) { - if( mObserver != NULL ) - { - mObserver->IndicatorVisibilityChanged( mIsShowing ); // is showing? - } + mObserver->IndicatorVisibilityChanged( mIsShowing ); // is showing? } } void Indicator::OnPan( Dali::Actor actor, const Dali::PanGesture& gesture ) { - if( mServerConnection ) - { - switch( gesture.state ) - { - case Gesture::Started: - { - mGestureDetected = false; - - // The gesture position is the current position after it has moved by the displacement. - // We want to reference the original position. - mGestureDeltaY = gesture.position.y - gesture.displacement.y; - } - - // No break, Fall through - case Gesture::Continuing: - { - if( mVisible == Dali::Window::AUTO && !mIsShowing ) - { - // Only take one touch point - if( gesture.numberOfTouches == 1 && mGestureDetected == false ) - { - mGestureDeltaY += gesture.displacement.y; - - if( mGestureDeltaY >= mImageHeight * SHOWING_DISTANCE_HEIGHT_RATE ) - { - ShowIndicator( AUTO_INDICATOR_STAY_DURATION ); - mGestureDetected = true; - } - } - } - - break; - } - - case Gesture::Finished: - case Gesture::Cancelled: - { - // if indicator is showing, hide again when touching is finished (Since touch leave is activated, checking it in gesture::finish instead of touch::up) - if( mVisible == Dali::Window::AUTO && mIsShowing ) - { - ShowIndicator( AUTO_INDICATOR_STAY_DURATION ); - } - break; - } - - - default: - break; - } - } + // Nothing to do, but we still want to consume pan } -void Indicator::OnStageTouched(const Dali::TouchEvent& touchEvent) +void Indicator::OnStageTouch(const Dali::TouchData& touchData) { - const TouchPoint& touchPoint = touchEvent.GetPoint( 0 ); - // when stage is touched while indicator is showing temporary, hide it if( mIsShowing && ( CheckVisibleState() == false || mVisible == Dali::Window::AUTO ) ) { - switch( touchPoint.state ) + switch( touchData.GetState(0) ) { - case Dali::TouchPoint::Down: + case Dali::PointState::DOWN: { - ShowIndicator( HIDE_NOW ); + // if touch point is inside the indicator, indicator is not hidden + if( mImageHeight < int( touchData.GetScreenPosition(0).y ) ) + { + ShowIndicator( HIDE_NOW ); + } break; } @@ -1426,5 +1659,9 @@ void Indicator::OnStageTouched(const Dali::TouchEvent& touchEvent) } } // Adaptor + } // Internal + } // Dali + +#pragma GCC diagnostic pop