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