Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-adaptor.git] / adaptors / common / indicator-impl.h
1 #ifndef __DALI_INTERNAL_INDICATOR_H__
2 #define __DALI_INTERNAL_INDICATOR_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/actors/image-actor.h>
23 #include <dali/public-api/actors/mesh-actor.h>
24 #include <dali/public-api/geometry/animatable-mesh.h>
25 #include <dali/public-api/animation/animation.h>
26 #include <dali/public-api/events/pan-gesture.h>
27 #include <dali/public-api/events/pan-gesture-detector.h>
28
29 // INTERNAL INCLUDES
30 #include <indicator-buffer.h>
31 #include <server-connection.h>
32 #include <shared-file.h>
33 #include <timer.h>
34 #include <window.h>
35
36 namespace Dali
37 {
38 namespace Integration
39 {
40 class Core;
41 }
42
43 namespace Internal
44 {
45 namespace Adaptor
46 {
47 class Adaptor;
48
49 typedef unsigned int PixmapId;
50
51 /**
52  * The Indicator class connects to the indicator server, and gets and draws the indicator
53  * for the given orientation.
54  */
55 class Indicator : public ConnectionTracker, public ServerConnection::Observer
56 {
57 public:
58   enum State
59   {
60     DISCONNECTED,
61     CONNECTED
62   };
63
64   enum Type
65   {
66     INDICATOR_TYPE_UNKNOWN,
67     INDICATOR_TYPE_1,
68     INDICATOR_TYPE_2
69   };
70
71 public:
72   class Observer
73   {
74   public:
75     /**
76      * Notify the observer if the indicator type changes
77      * @param[in] type The new indicator type
78      */
79     virtual void IndicatorTypeChanged( Type type ) = 0;
80
81     /**
82      * Notify the observer when the upload has completed.
83      * @param[in] indicator The indicator that has finished uploading.
84      */
85     virtual void IndicatorClosed(Indicator* indicator) = 0;
86
87     /**
88      * Notify the observer when the indicator visible status is changed.
89      * @param[in] isShowing Whether the indicator is visible.
90      */
91     virtual void IndicatorVisibilityChanged( bool isVisible ) = 0;
92   };
93
94 protected:
95   /**
96    * Class to encapsulate lock file
97    */
98   class LockFile
99   {
100   public:
101     /**
102      * Constructor. open lock file
103      */
104     LockFile(const std::string filename);
105
106     /**
107      * Close lock file
108      */
109     ~LockFile();
110
111     /**
112      * Grab an exclusive lock on this file
113      * @return true if the lock succeeded, false if it failed
114      */
115     bool Lock();
116
117     /**
118      * Remove the lock
119      */
120     void Unlock();
121
122     /**
123      * Test if there is an error with the lock file, and clears
124      * the error flag;
125      * @return true if an error was thrown
126      */
127     bool RetrieveAndClearErrorStatus();
128
129   private:
130     std::string mFilename;
131     int         mFileDescriptor;
132     bool        mErrorThrown;
133   };
134
135   /**
136    * Class to ensure lock/unlock through object destruction
137    */
138   class ScopedLock
139   {
140   public:
141     /**
142      * Constructor - creates a lock on the lockfile
143      * @param[in] lockFile The lockfile to use
144      */
145     ScopedLock( LockFile* lockFile );
146
147     /**
148      * Destructor - removes the lock (if any) on the lockfile
149      */
150     ~ScopedLock();
151
152     /**
153      * Method to test if the locking succeeded
154      * @return TRUE if locked
155      */
156     bool IsLocked();
157
158   private:
159     LockFile* mLockFile; ///< The lock file to use
160     bool      mLocked;   ///< Whether the lock succeeded
161   };
162
163
164 public:
165   /**
166    * Constructor. Creates a new indicator and opens a connection for
167    * the required orientation.
168    * @param[in] orientation The orientation in which to draw the indicator
169    * @param[in] observer The indicator closed
170    */
171   Indicator( Adaptor* adaptor,
172              Dali::Window::WindowOrientation orientation,
173              Dali::Window::IndicatorStyle style,
174              Observer* observer );
175
176   /**
177    * Destructor
178    */
179   virtual ~Indicator();
180
181   void SetAdaptor(Adaptor* adaptor);
182
183   /**
184    * Get the actor which contains the indicator image. Ensure that the handle is
185    * released when no longer needed.
186    * Changes from the indicator service will modify the image and resize the actor appropriately.
187    * @return The indicator actor.
188    */
189   Dali::Actor GetActor();
190
191   /**
192    * Opens a new connection for the required orientation.
193    * @param[in] orientation The new orientation
194    */
195   void Open( Dali::Window::WindowOrientation orientation );
196
197   /**
198    * Close the current connection. Will respond with Observer::IndicatorClosed()
199    * when done.
200    * @note, IndicatorClosed() will be called synchronously if there's no update
201    * in progress, or asychronously if waiting for SignalUploaded )
202    */
203   void Close();
204
205   /**
206    * Set the opacity mode of the indicator background.
207    * @param[in] mode opacity mode
208    */
209   void SetOpacityMode( Dali::Window::IndicatorBgOpacity mode );
210
211   /**
212    * Set whether the indicator is visible or not.
213    * @param[in] visibleMode visible mode for indicator bar.
214    * @param[in] forceUpdate true if want to change visible mode forcely
215    */
216   void SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool forceUpdate = false );
217
218   /**
219    * Check whether the indicator is connected to the indicator service.
220    * @return whether the indicator is connected or not.
221    */
222   bool IsConnected();
223
224   /**
225    * Send message to the indicator service.
226    * @param[in] messageDomain Message Reference number
227    * @param[in] messageId Reference number of the message this message refers to
228    * @param[in] data The data to send as part of the message
229    * @param[in] size Length of the data, in bytes, to send
230    * @return whether the message is sent successfully or not
231    */
232   bool SendMessage( int messageDomain, int messageId, const void *data, int size );
233
234 private:
235   /**
236    * Initialize the indicator actors
237    */
238   void Initialize();
239
240   /**
241    * Set the opacity of the background image
242    */
243   void SetBackgroundOpacity( Dali::Window::IndicatorBgOpacity opacity );
244
245   /**
246    * Touch event callback.
247    * It should pass the valid touch event to indicator server
248    *
249    * @param[in] indicator  The indicator actor that was touched
250    * @param[in] touchEvent The touch event
251    */
252   bool OnTouched(Dali::Actor indicator, const TouchEvent& touchEvent);
253
254   /**
255    * Pan gesture callback.
256    * It finds flick down gesture to show hidden indicator image
257    *
258    * @param[in] actor  The actor for gesture
259    * @param[in] gesture The gesture event
260    */
261   void OnPan( Dali::Actor actor, const Dali::PanGesture& gesture );
262
263   /**
264    * Touch event callback on stage.
265    * If stage is touched, hide showing indicator image
266    *
267    * @param[in] touchEvent The touch event
268    */
269   void OnStageTouched(const Dali::TouchEvent& touchEvent);
270
271   /**
272    * Return the given orientation in degrees
273    *
274    * @param[in] orientation The given indicator orientation
275    * @return value of 0, 90, 180 or 270
276    */
277   int OrientationToDegrees( Dali::Window::WindowOrientation orientation );
278
279   /**
280    * Connect to the indicator service matching the orientation
281    * @param[in] orientation The current indicator orientation
282    */
283   bool Connect( Dali::Window::WindowOrientation orientation );
284
285   /**
286    * Connect to the indicator service
287    * @param[in] serviceName The indicator service name
288    */
289   bool Connect( const char *serviceName );
290
291   /**
292    * Start the reconnection timer. This will run every second until we reconnect to
293    * the indicator service.
294    */
295   void StartReconnectionTimer();
296
297   /**
298    * If connection failed, attempt to re-connect every second
299    */
300   bool OnReconnectTimer();
301
302   /**
303    * Disconnect from the indicator service
304    */
305   void Disconnect();
306
307   /**
308    * Handle Resize event
309    * @param[in] width The new width
310    * @param[in] height The new height
311    */
312   void Resize( int width, int height );
313
314   /**
315    * Set the lock file info.
316    * @param[in] epcEvent Current ecore event.
317    */
318   void SetLockFileInfo( Ecore_Ipc_Event_Server_Data *epcEvent );
319
320   /**
321    * Set the shared indicator image info
322    * @param[in] epcEvent The event containing the image data
323    */
324   void SetSharedImageInfo( Ecore_Ipc_Event_Server_Data *epcEvent );
325
326   /**
327    * Load the shared indicator image
328    * @param[in] epcEvent The event containing the image data
329    */
330   void LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent );
331
332   /**
333    * Load the pixmap indicator image
334    * @param[in] epcEvent The event containing the image data
335    */
336   void LoadPixmapImage( Ecore_Ipc_Event_Server_Data *epcEvent );
337
338   /**
339    * Inform dali that the indicator data has been updated.
340    * @param[in] bufferNumber The shared file number
341    */
342   void UpdateImageData( int bufferNumber );
343
344   /**
345    * Lock the temporary file, Copy the shared image into IndicatorBuffer
346    * and then unlock the temporary file.
347    * Caller should ensure we are not writing image to gl texture.
348    * @param[in] bufferNumber The shared file number
349    */
350   bool CopyToBuffer( int bufferNumber );
351
352   /**
353    * Update the background with the correct colors
354    */
355   void SetBackground();
356
357   /**
358    * Create a new image for the indicator, and set up signal handling for it.
359    * @param[in] bufferNumber The shared file number
360    */
361   void CreateNewImage( int bufferNumber );
362
363   /**
364    * Create a new pixmap image for the indicator, and set up signal handling for it.
365    */
366   void CreateNewPixmapImage();
367
368   /**
369    * Indicator type has changed.
370    * Inform observer
371    * @param[in] type The new indicator type
372    */
373   void OnIndicatorTypeChanged( Type type );
374
375   /**
376    * Check whether the indicator could be visible or invisible
377    * @return true if indicator should be shown
378    */
379   bool CheckVisibleState();
380
381   /**
382    * Show/Hide indicator actor with effect
383    * @param[in] duration how long need to show the indicator,
384    *                     if it equal to 0, hide the indicator
385    *                     if it less than 0, show always
386    */
387   void ShowIndicator( float duration );
388
389   /**
390    * Showing timer callback
391    */
392   bool OnShowTimer();
393
394   /**
395    * Showing animation finished callback
396    * @param[in] animation
397    */
398   void OnAnimationFinished( Dali::Animation& animation );
399
400 private: // Implementation of ServerConnection::Observer
401   /**
402    * @copydoc Dali::Internal::Adaptor::ServerConnection::Observer::DataReceived()
403    */
404   virtual void DataReceived( void* event );
405
406   /**
407    * @copydoc Dali::Internal::Adaptor::ServerConnection::Observer::DataReceived()
408    */
409   virtual void ConnectionClosed();
410
411 private:
412
413   /**
414    * Construct the gradient mesh
415    */
416   void ConstructBackgroundMesh();
417
418   /**
419    * Clear shared file info
420    */
421   void ClearSharedFileInfo();
422
423 private:
424
425   struct SharedFileInfo
426   {
427     SharedFileInfo()
428       : mLock( NULL ),
429         mSharedFile( NULL ),
430         mImageWidth( 0 ),
431         mImageHeight( 0 ),
432         mLockFileName(),
433         mSharedFileName(),
434         mSharedFileID( 0 ),
435         mSharedFileNumber( 0 )
436     {
437     }
438
439     LockFile*                        mLock;              ///< File lock for the shared file
440     SharedFile*                      mSharedFile;        ///< Shared file
441
442     int                              mImageWidth;        ///< Shared image width
443     int                              mImageHeight;       ///< Shared image height
444
445     std::string                      mLockFileName;      ///< Lock file name
446     std::string                      mSharedFileName;    ///< Shared file name
447     int                              mSharedFileID;      ///< Shared file ID
448     int                              mSharedFileNumber;  ///< Shared file number
449   };
450
451   static const int SHARED_FILE_NUMBER = 2;               ///< Shared file number
452
453   IndicatorBufferPtr               mIndicatorBuffer;     ///< class which handles indicator rendering
454   PixmapId                         mPixmap;              ///< Pixmap including indicator content
455   Dali::Image                      mImage;               ///< Image created from mIndicatorBuffer
456   Dali::ImageActor                 mIndicatorImageActor; ///< Actor created from mImage
457
458   Dali::AnimatableMesh             mBackgroundMesh;
459   Dali::MeshActor                  mBackgroundActor;     ///< Actor for background
460   Dali::Actor                      mIndicatorActor;      ///< Handle to topmost indicator actor
461   Dali::Actor                      mEventActor;          ///< Handle to event
462   Dali::PanGestureDetector         mPanDetector;         ///< Pan detector to find flick gesture for hidden indicator
463   float                            mGestureDeltaY;       ///< Checking how much panning moved
464   bool                             mGestureDetected;     ///< Whether find the flick gesture
465
466   Dali::Timer                      mReconnectTimer;      ///< Reconnection timer
467   SlotDelegate< Indicator >        mConnection;
468
469   Dali::Window::IndicatorStyle     mStyle;               ///< Style of the indicator
470   Dali::Window::IndicatorBgOpacity mOpacityMode;         ///< Opacity enum for background
471   Indicator::State                 mState;               ///< The connection state
472
473   Adaptor*                         mAdaptor;
474   ServerConnection*                mServerConnection;
475   Indicator::Observer*             mObserver;            ///< Upload observer
476
477   Dali::Window::WindowOrientation  mOrientation;
478   int                              mRotation;            ///< Orientation in degrees
479   int                              mImageWidth;
480   int                              mImageHeight;
481   Dali::Window::IndicatorVisibleMode mVisible;           ///< Whether the indicator is visible
482
483   Dali::Timer                      mShowTimer;           ///< Timer to show indicator
484   bool                             mIsShowing;           ///< Whether the indicator is showing on the screen
485   Dali::Animation                  mIndicatorAnimation;  ///< Animation to show/hide indicator image
486
487   bool                             mIsAnimationPlaying;  ///< Whether the animation is playing
488
489   int                              mCurrentSharedFile;   ///< Current shared file number
490   SharedFileInfo                   mSharedFileInfo[SHARED_FILE_NUMBER];    ///< Table to store shared file info
491 };
492
493 } // Adaptor
494 } // Internal
495 } // Dali
496
497 #endif