2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include "indicator-impl.h"
24 #include <sys/types.h>
30 #include <dali/public-api/images/bitmap-image.h>
31 #include <dali/public-api/actors/image-actor.h>
32 #include <dali/public-api/events/touch-event.h>
33 #include <dali/public-api/events/touch-point.h>
34 #include <dali/public-api/common/stage.h>
35 #include <dali/public-api/actors/blending.h>
36 #include <dali/public-api/shader-effects/shader-effect.h>
38 #include <dali/integration-api/debug.h>
41 #include <internal/common/adaptor-impl.h>
42 #include <internal/common/accessibility-manager-impl.h>
46 #if defined(DEBUG_ENABLED)
47 #define STATE_DEBUG_STRING(state) (state==DISCONNECTED?"DISCONNECTED":state==CONNECTED?"CONNECTED":"UNKNOWN")
52 const int NUM_GRADIENT_INTERVALS(5); // Number of gradient intervals
53 const Dali::Vector4 GRADIENT_COLORS[NUM_GRADIENT_INTERVALS+1] =
55 Vector4(0.0f, 0.0f, 0.0f, 0.6f),
56 Vector4(0.0f, 0.0f, 0.0f, 0.38f),
57 Vector4(0.0f, 0.0f, 0.0f, 0.20f),
58 Vector4(0.0f, 0.0f, 0.0f, 0.08f),
59 Vector4(0.0f, 0.0f, 0.0f, 0.0f),
60 Vector4(0.0f, 0.0f, 0.0f, 0.0f),
63 const float OPAQUE_THRESHOLD(0.99f);
64 const float TRANSPARENT_THRESHOLD(0.05f);
66 // Indicator orientation
67 const char* ELM_INDICATOR_PORTRAIT("elm_indicator_portrait");
68 const char* ELM_INDICATOR_LANDSCAPE("elm_indicator_landscape");
70 const char* MESH_VERTEX_SHADER =
71 "attribute lowp vec3 aColor;\n"
72 "varying mediump vec4 vColor;\n"
75 " gl_Position = uMvpMatrix * vec4(aPosition, 1.0);\n"
76 " vColor = vec4(aColor.r, aColor.g, aColor.b, aTexCoord.x);\n"
79 const char* MESH_FRAGMENT_SHADER =
80 "varying mediump vec4 vColor;\n"
83 " gl_FragColor = vColor*uColor;\n"
86 // Copied from elm_win.h
89 * Defines the opacity modes of indicator that can be shown
93 ELM_WIN_INDICATOR_OPACITY_UNKNOWN, /**< Unknown indicator opacity mode */
94 ELM_WIN_INDICATOR_OPAQUE, /**< Opacifies the indicator */
95 ELM_WIN_INDICATOR_TRANSLUCENT, /**< Be translucent the indicator */
96 ELM_WIN_INDICATOR_TRANSPARENT /**< Transparentizes the indicator */
97 } Elm_Win_Indicator_Opacity_Mode;
100 * Defines the type modes of indicator that can be shown
101 * If the indicator can support several type of indicator,
102 * you can use this enum value to deal with different type of indicator
106 ELM_WIN_INDICATOR_TYPE_UNKNOWN, /**< Unknown indicator type mode */
107 ELM_WIN_INDICATOR_TYPE_1, /**< Type 0 the the indicator */
108 ELM_WIN_INDICATOR_TYPE_2, /**< Type 1 the indicator */
109 } Elm_Win_Indicator_Type_Mode;
111 // Copied from ecore_evas_extn.c
140 // Copied from elm_conform.c
142 const int MSG_DOMAIN_CONTROL_INDICATOR(0x10001);
143 const int MSG_ID_INDICATOR_REPEAT_EVENT(0x10002);
144 const int MSG_ID_INDICATOR_ROTATION(0x10003);
145 const int MSG_ID_INDICATOR_OPACITY(0X1004);
146 const int MSG_ID_INDICATOR_TYPE(0X1005);
159 struct IpcDataEvMouseUp
162 Evas_Button_Flags flags;
164 unsigned int timestamp;
165 Evas_Event_Flags event_flags;
167 IpcDataEvMouseUp(unsigned long timestamp)
169 flags(EVAS_BUTTON_NONE),
171 timestamp(static_cast<unsigned int>(timestamp)),
172 event_flags(EVAS_EVENT_FLAG_NONE)
177 struct IpcDataEvMouseDown
180 Evas_Button_Flags flags;
182 unsigned int timestamp;
183 Evas_Event_Flags event_flags;
185 IpcDataEvMouseDown(unsigned long timestamp)
187 flags(EVAS_BUTTON_NONE),
189 timestamp(static_cast<unsigned int>(timestamp)),
190 event_flags(EVAS_EVENT_FLAG_NONE)
195 struct IpcDataEvMouseMove
198 Evas_Button_Flags flags;
200 unsigned int timestamp;
201 Evas_Event_Flags event_flags;
203 IpcDataEvMouseMove(const Dali::TouchPoint& touchPoint, unsigned long timestamp)
204 : x(static_cast<Evas_Coord>(touchPoint.local.x)),
205 y(static_cast<Evas_Coord>(touchPoint.local.y)),
206 flags(EVAS_BUTTON_NONE),
208 timestamp(static_cast<unsigned int>(timestamp)),
209 event_flags(EVAS_EVENT_FLAG_NONE)
214 struct IpcDataEvMouseOut
216 unsigned int timestamp;
218 Evas_Event_Flags event_flags;
220 IpcDataEvMouseOut(unsigned long timestamp)
221 : timestamp(static_cast<unsigned int>(timestamp)),
223 event_flags(EVAS_EVENT_FLAG_NONE)
228 void SetMeshDataColors(Dali::AnimatableMesh mesh, const Vector4 (&colors)[NUM_GRADIENT_INTERVALS+1])
230 for( size_t i=0; i<NUM_GRADIENT_INTERVALS+1; i++ )
233 mesh[j].SetColor(colors[i]);
234 mesh[j+1].SetColor(colors[i]);
235 mesh[j].SetTextureCoords(Dali::Vector2(colors[i].a, colors[i].a));
236 mesh[j+1].SetTextureCoords(Dali::Vector2(colors[i].a, colors[i].a));
240 void SetMeshDataColors(Dali::AnimatableMesh mesh, const Vector4& color)
242 for( size_t i=0, length=NUM_GRADIENT_INTERVALS+1 ; i<length; i++ )
245 mesh[j].SetColor(color);
246 mesh[j+1].SetColor(color);
247 mesh[j].SetTextureCoords(Dali::Vector2(color.a, color.a));
248 mesh[j+1].SetTextureCoords(Dali::Vector2(color.a, color.a));
252 } // anonymous namespace
261 #if defined(DEBUG_ENABLED)
262 Debug::Filter* gIndicatorLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_INDICATOR");
266 Indicator::LockFile::LockFile(const char* filename)
267 : mFilename(filename),
270 mFileDescriptor = open(filename, O_RDWR);
271 if( mFileDescriptor == -1 )
275 DALI_LOG_ERROR( "### Cannot open %s for indicator lock ###\n", mFilename.c_str() );
279 Indicator::LockFile::~LockFile()
281 // Closing file descriptor also unlocks file.
282 close( mFileDescriptor );
285 bool Indicator::LockFile::Lock()
287 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
290 if( mFileDescriptor > 0 )
292 if( lockf( mFileDescriptor, F_LOCK, 0 ) == 0 ) // Note, operation may block.
300 // file descriptor is no longer valid or not writable
303 DALI_LOG_ERROR( "### Cannot lock indicator: bad file descriptor for %s ###\n", mFilename.c_str() );
311 void Indicator::LockFile::Unlock()
313 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
314 if( lockf( mFileDescriptor, F_ULOCK, 0 ) != 0 )
318 // file descriptor is no longer valid or not writable
321 DALI_LOG_ERROR( "### Cannot unlock indicator: bad file descriptor for %s\n", mFilename.c_str() );
326 bool Indicator::LockFile::RetrieveAndClearErrorStatus()
328 bool error = mErrorThrown;
329 mErrorThrown = false;
333 Indicator::ScopedLock::ScopedLock(LockFile* lockFile)
334 : mLockFile(lockFile),
339 mLocked = mLockFile->Lock();
343 Indicator::ScopedLock::~ScopedLock()
351 bool Indicator::ScopedLock::IsLocked()
356 Indicator::Indicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, Observer* observer )
357 : mConnection( this ),
358 mOpacityMode( Dali::Window::OPAQUE ),
359 mState( DISCONNECTED ),
361 mServerConnection( NULL ),
364 mObserver( observer ),
365 mOrientation( orientation ),
371 mIndicatorImageActor = Dali::ImageActor::New();
372 mIndicatorImageActor.SetLeaveRequired(true);
373 mIndicatorImageActor.TouchedSignal().Connect( this, &Indicator::OnTouched );
374 mIndicatorImageActor.SetBlendFunc(Dali::BlendingFactor::ONE, Dali::BlendingFactor::ONE_MINUS_SRC_ALPHA,
375 Dali::BlendingFactor::ONE, Dali::BlendingFactor::ONE );
376 mIndicatorImageActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
379 mBackgroundActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
381 mIndicatorActor = Dali::Actor::New();
382 mIndicatorActor.SetParentOrigin( ParentOrigin::CENTER );
383 mIndicatorActor.SetAnchorPoint( AnchorPoint::CENTER );
384 mIndicatorActor.Add(mBackgroundActor);
385 mIndicatorActor.Add(mIndicatorImageActor);
387 if(mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE)
389 mBackgroundActor.SetVisible(false);
394 Dali::AccessibilityManager accessibilityManager = AccessibilityManager::Get();
395 if(accessibilityManager)
397 AccessibilityManager::GetImplementation( accessibilityManager ).SetIndicator(this);
401 Indicator::~Indicator()
403 if(mIndicatorImageActor)
405 mIndicatorImageActor.TouchedSignal().Disconnect( this, &Indicator::OnTouched );
410 void Indicator::SetAdaptor(Adaptor* adaptor)
413 mIndicatorBuffer->SetAdaptor( adaptor );
416 Dali::Actor Indicator::GetActor()
418 return mIndicatorActor;
421 void Indicator::Open( Dali::Window::WindowOrientation orientation )
423 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
425 // Calls from Window should be set up to ensure we are in a
426 // disconnected state before opening a second time.
427 DALI_ASSERT_DEBUG( mState == DISCONNECTED );
429 Connect( orientation );
431 // Change background visibility depending on orientation
432 if(mOrientation == Dali::Window::PORTRAIT || mOrientation == Dali::Window::PORTRAIT_INVERSE)
434 mBackgroundActor.SetVisible(true);
438 mBackgroundActor.SetVisible(false);
442 void Indicator::Close()
444 DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "State: %s\n", STATE_DEBUG_STRING(mState) );
446 if( mState == CONNECTED )
449 if( mObserver != NULL )
451 mObserver->IndicatorClosed( this );
455 Dali::Image emptyImage;
456 mIndicatorImageActor.SetImage(emptyImage);
459 void Indicator::SetOpacityMode( Dali::Window::IndicatorBgOpacity mode, bool notifyService )
461 if( mOpacityMode != mode || notifyService )
463 // notify opacity mode to indicator service
464 SendOpacityMode(mode);
471 void Indicator::SetVisible( bool visibility )
473 if ( visibility != mVisible )
475 mVisible = visibility;
477 // If we were previously hidden, then we should update the image data before we display the indicator
485 bool Indicator::IsConnected()
487 return ( mState == CONNECTED );
490 bool Indicator::SendMessage( int messageDomain, int messageId, const void *data, int size )
494 return mServerConnection->SendEvent( OP_MSG, messageDomain, messageId, data, size );
502 bool Indicator::OnTouched(Dali::Actor indicator, const Dali::TouchEvent& touchEvent)
504 if(mServerConnection)
506 const TouchPoint& touchPoint = touchEvent.GetPoint( 0 );
508 switch( touchPoint.state )
510 case Dali::TouchPoint::Down:
512 IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time );
513 IpcDataEvMouseDown ipcDown( touchEvent.time );
514 mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
515 mServerConnection->SendEvent( OP_EV_MOUSE_DOWN, &ipcDown, sizeof(ipcDown) );
519 case Dali::TouchPoint::Motion:
521 IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time );
522 mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
526 case Dali::TouchPoint::Up:
528 IpcDataEvMouseUp ipcUp( touchEvent.time );
529 mServerConnection->SendEvent( OP_EV_MOUSE_UP, &ipcUp, sizeof(ipcUp) );
533 case Dali::TouchPoint::Leave:
535 IpcDataEvMouseMove ipcMove( touchPoint, touchEvent.time );
536 mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
537 IpcDataEvMouseUp ipcOut( touchEvent.time );
538 mServerConnection->SendEvent( OP_EV_MOUSE_OUT, &ipcOut, sizeof(ipcOut) );
550 * Return the current orientation in degrees
551 * @return value of 0, 90, 180 or 270
553 int Indicator::OrientationToDegrees( Dali::Window::WindowOrientation orientation )
557 switch( orientation )
559 case Dali::Window::PORTRAIT:
562 case Dali::Window::PORTRAIT_INVERSE:
565 case Dali::Window::LANDSCAPE:
568 case Dali::Window::LANDSCAPE_INVERSE:
575 void Indicator::SendOpacityMode( Dali::Window::IndicatorBgOpacity mode )
577 Elm_Win_Indicator_Opacity_Mode windowIndicatorMode;
580 case Dali::Window::OPAQUE:
581 windowIndicatorMode = ELM_WIN_INDICATOR_OPAQUE;
583 case Dali::Window::TRANSPARENT:
584 windowIndicatorMode = ELM_WIN_INDICATOR_TRANSPARENT;
586 case Dali::Window::TRANSLUCENT:
587 windowIndicatorMode = ELM_WIN_INDICATOR_TRANSLUCENT;
591 if( mServerConnection )
593 mServerConnection->SendEvent( OP_MSG,
594 MSG_DOMAIN_CONTROL_INDICATOR,
595 MSG_ID_INDICATOR_OPACITY,
596 &windowIndicatorMode, sizeof( Elm_Win_Indicator_Opacity_Mode ) );
601 bool Indicator::Connect( Dali::Window::WindowOrientation orientation )
603 DALI_ASSERT_DEBUG( mState == DISCONNECTED );
605 bool connected = false;
606 mOrientation = orientation;
607 mRotation = OrientationToDegrees(mOrientation);
609 switch( orientation )
611 case Dali::Window::PORTRAIT:
612 connected = Connect( ELM_INDICATOR_PORTRAIT );
614 case Dali::Window::PORTRAIT_INVERSE:
615 connected = Connect( ELM_INDICATOR_PORTRAIT );
617 case Dali::Window::LANDSCAPE:
618 connected = Connect( ELM_INDICATOR_LANDSCAPE );
620 case Dali::Window::LANDSCAPE_INVERSE:
621 connected = Connect( ELM_INDICATOR_LANDSCAPE );
628 bool Indicator::Connect( const char *serviceName )
630 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
632 bool connected = false;
634 mServerConnection = new ServerConnection( serviceName, 0, false, this );
635 if( mServerConnection )
637 connected = mServerConnection->IsConnected();
640 delete mServerConnection;
641 mServerConnection = NULL;
648 int domain = MSG_DOMAIN_CONTROL_INDICATOR;
649 int refTo = MSG_ID_INDICATOR_ROTATION;
650 mServerConnection->SendEvent( OP_MSG, domain, refTo, &mRotation, sizeof(int) );
654 StartReconnectionTimer();
660 void Indicator::StartReconnectionTimer()
662 if( ! mReconnectTimer )
664 mReconnectTimer = Dali::Timer::New(1000);
665 mConnection.DisconnectAll();
666 mReconnectTimer.TickSignal().Connect( mConnection, &Indicator::OnReconnectTimer );
668 mReconnectTimer.Start();
671 bool Indicator::OnReconnectTimer()
675 if( mState == DISCONNECTED )
677 if( ! Connect( mOrientation ) )
686 void Indicator::Disconnect()
688 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
690 mState = DISCONNECTED;
698 delete mServerConnection;
699 mServerConnection = NULL;
702 void Indicator::NewLockFile( Ecore_Ipc_Event_Server_Data *epcEvent )
704 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
709 if ( (epcEvent->data) &&
710 (epcEvent->size > 0) &&
711 (((unsigned char *)epcEvent->data)[epcEvent->size - 1] == 0) )
713 const char* lockFile = static_cast< const char* >( epcEvent->data );
714 mLock = new Indicator::LockFile( lockFile );
715 if( mLock->RetrieveAndClearErrorStatus() )
717 DALI_LOG_ERROR( "### Indicator error: Cannot open lock file %s ###\n", lockFile );
722 void Indicator::Resize( int width, int height )
733 if( mImageWidth != width || mImageHeight != height )
736 mImageHeight = height;
738 // We don't currently handle the pixel buffer size being changed. Create a new image instead
746 void Indicator::LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent )
748 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
750 // epcEvent->ref == w
751 // epcEvent->ref_to == h
752 // epcEvent->response == alpha
753 // epcEvent->data = shm ref string + nul byte
754 if( ( epcEvent->data ) &&
755 ( ( unsigned char * ) epcEvent->data)[ epcEvent->size - 1 ] == 0 )
757 if( mSharedFile != NULL )
763 if( (epcEvent->ref > 0) && (epcEvent->ref_to > 0) )
765 mImageWidth = epcEvent->ref;
766 mImageHeight = epcEvent->ref_to;
768 char* sharedFilename = static_cast<char*>(epcEvent->data);
770 mSharedFile = SharedFile::New( sharedFilename, mImageWidth * mImageWidth * 4, true );
771 if( mSharedFile != NULL )
774 if( CheckVisibleState() )
776 // set default indicator type (enable the quick panel)
777 OnIndicatorTypeChanged( INDICATOR_TYPE_1 );
781 // set default indicator type (disable the quick panel)
782 OnIndicatorTypeChanged( INDICATOR_TYPE_2 );
789 void Indicator::UpdateImageData()
791 DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "State: %s mVisible: %s\n", STATE_DEBUG_STRING(mState), mVisible?"T":"F" );
793 if( mState == CONNECTED && mVisible )
799 bool Indicator::CopyToBuffer()
801 bool success = false;
805 Indicator::ScopedLock scopedLock(mLock);
806 if( mLock->RetrieveAndClearErrorStatus() )
810 else if( scopedLock.IsLocked() )
812 unsigned char *src = mSharedFile->GetAddress();
813 size_t size = mImageWidth * mImageHeight * 4;
814 if( mIndicatorBuffer->UpdatePixels( src, size ) )
816 mAdaptor->RequestUpdateOnce();
825 void Indicator::SetBackground()
827 if( ! mBackgroundActor )
829 ConstructBackgroundMesh();
832 switch( mOpacityMode )
834 case Dali::Window::TRANSLUCENT:
836 SetMeshDataColors( mBackgroundMesh, GRADIENT_COLORS );
840 case Dali::Window::TRANSPARENT:
842 SetMeshDataColors( mBackgroundMesh, Color::TRANSPARENT );
846 case Dali::Window::OPAQUE:
849 SetMeshDataColors( mBackgroundMesh, Color::BLACK );
855 void Indicator::CreateNewImage()
857 DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "W:%d H:%d\n", mImageWidth, mImageHeight );
858 mIndicatorBuffer = new IndicatorBuffer( mAdaptor, mImageWidth, mImageHeight, Pixel::BGRA8888 );
859 Dali::Image image = Dali::Image::New( mIndicatorBuffer->GetNativeImage() );
861 if( CopyToBuffer() ) // Only create images if we have valid image buffer
863 mIndicatorImageActor.SetImage( image );
864 mIndicatorImageActor.SetSize( mImageWidth, mImageHeight );
865 mIndicatorActor.SetSize( mImageWidth, mImageHeight );
868 if( mBackgroundActor )
870 mBackgroundActor.SetSize( mImageWidth, mImageHeight );
875 DALI_LOG_WARNING("### Cannot create indicator image - disconnecting ###\n");
877 if( mObserver != NULL )
879 mObserver->IndicatorClosed( this );
881 // Don't do connection in this callback - strange things happen!
882 StartReconnectionTimer();
886 void Indicator::OnIndicatorTypeChanged( Type indicatorType )
888 if( mObserver != NULL )
890 mObserver->IndicatorTypeChanged( indicatorType );
894 void Indicator::DataReceived( void* event )
896 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
897 Ecore_Ipc_Event_Server_Data *epcEvent = static_cast<Ecore_Ipc_Event_Server_Data *>( event );
899 switch( epcEvent->minor )
902 DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_UPDATE\n" );
906 DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_UPDATE_DONE\n" );
911 DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_LOCK_FILE\n" );
912 NewLockFile( epcEvent );
916 DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF\n" );
917 LoadSharedImage( epcEvent );
921 DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_RESIZE\n" );
923 if( (epcEvent->data) && (epcEvent->size >= (int)sizeof(IpcDataResize)) )
925 IpcDataResize *newSize = static_cast<IpcDataResize*>( epcEvent->data );
926 Resize( newSize->w, newSize->h );
932 int msgDomain = epcEvent->ref;
933 int msgId = epcEvent->ref_to;
934 if( msgDomain == MSG_DOMAIN_CONTROL_INDICATOR )
938 case MSG_ID_INDICATOR_TYPE:
940 DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_MSG_PARENT, INDICATOR_TYPE\n" );
941 Type* indicatorType = static_cast<Type*>( epcEvent->data );
942 OnIndicatorTypeChanged( *indicatorType );
952 void Indicator::ConnectionClosed()
954 DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
956 // Will get this callback if the server connection failed to start up.
957 delete mServerConnection;
958 mServerConnection = NULL;
959 mState = DISCONNECTED;
961 // Attempt to re-connect
962 Connect(mOrientation);
965 bool Indicator::CheckVisibleState()
967 if( mOrientation == Dali::Window::LANDSCAPE
968 || mOrientation == Dali::Window::LANDSCAPE_INVERSE
969 || mOpacityMode == Dali::Window::TRANSPARENT
970 || mVisible == false )
978 void Indicator::ConstructBackgroundMesh()
980 // Construct 5 interval mesh
992 Dali::AnimatableMesh::Faces faces;
993 faces.reserve(NUM_GRADIENT_INTERVALS * 6); // 2 tris per interval
994 for(int i=0; i<NUM_GRADIENT_INTERVALS; i++)
997 faces.push_back(j); faces.push_back(j+3); faces.push_back(j+1);
998 faces.push_back(j); faces.push_back(j+2); faces.push_back(j+3);
1001 mBackgroundMesh = Dali::AnimatableMesh::New((NUM_GRADIENT_INTERVALS+1)*2, faces);
1002 float interval=1.0f / (float)NUM_GRADIENT_INTERVALS;
1003 for(int i=0;i<NUM_GRADIENT_INTERVALS+1;i++)
1006 mBackgroundMesh[j ].SetPosition(Vector3(-0.5f, -0.5f+(interval*(float)i), 0.0f));
1007 mBackgroundMesh[j+1].SetPosition(Vector3( 0.5f, -0.5f+(interval*(float)i), 0.0f));
1010 mBackgroundActor = Dali::MeshActor::New(mBackgroundMesh);
1011 mBackgroundActor.SetAffectedByLighting(false);
1012 Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::New( MESH_VERTEX_SHADER, MESH_FRAGMENT_SHADER,
1013 GEOMETRY_TYPE_MESH, // Using vertex color
1014 Dali::ShaderEffect::HINT_BLENDING );
1015 mBackgroundActor.SetShaderEffect(shaderEffect);