/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
// EXTERNAL INCLUDES
#include <Ecore.h>
#include <Evas.h>
+#ifdef WAYLAND
+#include <Ecore_Wayland.h>
+#else
+#include <Ecore_X.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <iomanip>
+#include <fstream>
#include <dali/public-api/images/native-image.h>
#include <dali/public-api/events/touch-event.h>
#include <dali/public-api/events/touch-point.h>
#include <dali/public-api/common/stage.h>
-#include <dali/public-api/actors/blending.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
#include <dali/public-api/images/buffer-image.h>
+#include <dali/public-api/images/pixel.h>
#include <dali/integration-api/debug.h>
}
);
+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);
// Copied from ecore_evas_extn_engine.h
+#define NBUF 2
+
enum // opcodes
{
OP_RESIZE,
OP_EV_KEY_DOWN,
OP_EV_HOLD,
OP_MSG_PARENT,
- OP_MSG
+ OP_MSG,
+ OP_PIXMAP_REF,
};
// Copied from elm_conform.c
}
};
+#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<unsigned char> 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
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),
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;
}
void Indicator::LockFile::Unlock()
{
DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
- if( lockf( mFileDescriptor, F_ULOCK, 0 ) != 0 )
+
+ 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)
{
- if( errno == EBADF )
- {
- // 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() );
- }
+ mErrorThrown = true;
+ DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() );
}
}
Indicator::Indicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer )
: mPixmap( 0 ),
+ mGestureDeltaY( 0.0f ),
mGestureDetected( false ),
mConnection( this ),
mOpacityMode( Dali::Window::OPAQUE ),
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.TouchedSignal().Connect( this, &Indicator::OnTouched );
+ 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();
}
// 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 );
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
{
}
}
- 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 )
{
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 )
{
ShowIndicator( HIDE_NOW );
}
}
+ else
+ {
+ mIsShowing = false;
+ }
}
}
{
switch( touchPoint.state )
{
- case Dali::TouchPoint::Down:
+ case Dali::PointState::DOWN:
{
IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time );
IpcDataEvMouseDown ipcDown( touchEvent.time );
}
break;
- case Dali::TouchPoint::Motion:
+ case Dali::PointState::MOTION:
{
IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time );
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 );
mServerConnection->SendEvent( OP_EV_MOUSE_UP, &ipcUp, sizeof(ipcUp) );
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();
}
}
// 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 )
}
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 );
- }
-
- SetVisible(mVisible, true);
+ UpdateVisibility();
}
}
}
{
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<PixmapId>(epcEvent->ref);
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "mPixmap [%x]", mPixmap);
- mPixmap = *(static_cast<PixmapId*>(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 )
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 ) )
{
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
{
{
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 );
+ Dali::Texture texture = Dali::Texture::New( mIndicatorBuffer->GetNativeImage() );
+ if( texture )
+ {
+ SetForegroundImage( texture );
+ success = true;
+ }
}
- else
+
+ if( !success )
{
DALI_LOG_WARNING("### Cannot create indicator image - disconnecting ###\n");
Disconnect();
}
}
-//@todo replace with a gradient renderer when that is implemented
Dali::Geometry Indicator::CreateBackgroundGeometry()
{
switch( mOpacityMode )
// 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);
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;
{ 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;
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 )
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" );
if (msgDataSize != (int)sizeof(IpcIndicatorDataAnimation))
{
- DALI_LOG_ERROR("Message data is incorrect");
+ DALI_LOG_ERROR("Message data is incorrect\n");
break;
}
}
break;
}
-
}
}
break;
{
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;
}
}
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;
}
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;
{
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)
{
switch( touchPoint.state )
{
- 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(touchPoint.screen.y) )
+ {
+ ShowIndicator( HIDE_NOW );
+ }
break;
}