merge with master
[platform/framework/web/wrt-plugins-common.git] / src / wrt-popup / wrt / popup-bin / renderer / evas_object.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @file        evas_object.h
18  * @author      Lukasz Wrzosek (l.wrzosel@samsung.com)
19  * @version     1.0
20  * @brief       This file is the header for Evas_Object wrapper from Efl.
21  */
22
23 #ifndef WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H
24 #define WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H
25
26 #include <Evas.h>
27 #include <dpl/noncopyable.h>
28 #include <dpl/framework_efl.h>
29 #include <dpl/assert.h>
30 #include <dpl/foreach.h>
31 #include <dpl/apply.h>
32 #include <set>
33 #include <string>
34 #include <tuple>
35 #include <utility>
36 #include <memory>
37
38 namespace Wrt {
39 namespace Popup {
40 namespace Renderer {
41 class EvasObject
42 {
43     class EvasObjectShared;
44     typedef std::shared_ptr<EvasObjectShared> EvasObjectSharedPtr;
45
46   public:
47     class IConnection
48     {
49       public:
50         Evas_Object* GetEvasObject();
51         void Disconnect();
52
53       private:
54         IConnection(EvasObjectShared* object);
55         virtual ~IConnection()
56         {}
57         virtual void Call(void* /*event_info*/) = 0;
58
59         static void SmartCallbackWrapper(void* data,
60                                          Evas_Object* /*object*/,
61                                          void* event_info);
62         static void EvasCallbackWrapper(void* data,
63                                         Evas* /*evas*/,
64                                         Evas_Object* /*object*/,
65                                         void* event_info);
66
67         virtual void ConnectPrv() = 0;
68         virtual void DisconnectPrv() = 0;
69
70         friend class EvasObjectShared;
71
72         EvasObjectShared* m_object;
73     };
74
75   private:
76     class EvasObjectShared : DPL::Noncopyable
77     {
78       public:
79         friend class IConnection;
80         Evas_Object* GetObject();
81
82         typedef std::set<IConnection*> IConnectionsSet;
83
84         class SmartConnectionBase : public IConnection
85         {
86           public:
87             SmartConnectionBase(const std::string& name,
88                                 EvasObjectShared* object);
89
90             virtual void ConnectPrv();
91             virtual void DisconnectPrv();
92             std::string m_callbackName;
93         };
94
95         template<typename ... Args>
96         class SmartConnection : public SmartConnectionBase
97         {
98           public:
99             typedef void (*CbType)(IConnection* connection,
100                                    void* event_info,
101                                    Args ... args);
102
103             SmartConnection(const std::string& name,
104                             CbType callback,
105                             EvasObjectShared* object,
106                             Args ... args) :
107                 SmartConnectionBase(name, object),
108                 m_callback(callback),
109                 m_args(args ...)
110             {}
111
112             virtual ~SmartConnection()
113             {}
114
115             virtual void Call(void* event_info)
116             {
117                 DPL::Apply<void,
118                            DPL::ExtraArgsInsertPolicy::Prepend>(m_callback,
119                                                                 m_args,
120                                                                 this,
121                                                                 event_info);
122             }
123
124           private:
125             CbType m_callback;
126             std::tuple<Args ...> m_args;
127         };
128
129         template <class ThisType, class ArgType1>
130         class SmartMemberConnection1 : public SmartConnectionBase
131         {
132           public:
133             typedef void (ThisType::*CbType)(IConnection* connection,
134                                              void* event_info, ArgType1 *arg1);
135
136             SmartMemberConnection1(const std::string& name,
137                                    CbType callback,
138                                    ThisType* callee,
139                                    ArgType1* arg1,
140                                    EvasObjectShared* object) :
141                 SmartConnectionBase(name, object),
142                 m_callback(callback),
143                 m_callee(callee),
144                 m_arg1(arg1)
145             {}
146
147             virtual ~SmartMemberConnection1()
148             {}
149
150             virtual void Call(void* event_info)
151             {
152                 (m_callee->*m_callback)(this, event_info, m_arg1);
153             }
154
155           private:
156             CbType m_callback;
157             ThisType* m_callee;
158             ArgType1* m_arg1;
159         };
160
161         template <class ThisType, class ArgType1, class ArgType2>
162         class SmartMemberConnection2 : public SmartConnectionBase
163         {
164           public:
165             typedef void (ThisType::*CbType)(IConnection* connection,
166                                              void* event_info, ArgType1 *arg1,
167                                              ArgType2* arg2);
168
169             SmartMemberConnection2(const std::string& name,
170                                    CbType callback,
171                                    ThisType* callee,
172                                    ArgType1* arg1,
173                                    ArgType2* arg2,
174                                    EvasObjectShared* object) :
175                 SmartConnectionBase(name, object),
176                 m_callback(callback),
177                 m_callee(callee),
178                 m_arg1(arg1),
179                 m_arg2(arg2)
180             {}
181
182             virtual ~SmartMemberConnection2()
183             {}
184
185             virtual void Call(void* event_info)
186             {
187                 (m_callee->*m_callback)(this, event_info, m_arg1, m_arg2);
188             }
189
190           private:
191             CbType m_callback;
192             ThisType* m_callee;
193             ArgType1* m_arg1;
194             ArgType2* m_arg2;
195         };
196
197         class EvasConnectionBase : public IConnection
198         {
199           public:
200             EvasConnectionBase(Evas_Callback_Type type,
201                                EvasObjectShared* object);
202
203             virtual void ConnectPrv();
204             virtual void DisconnectPrv();
205
206             Evas_Callback_Type m_callbackType;
207         };
208
209         template <class ArgType1>
210         class EvasConnection1 : public EvasConnectionBase
211         {
212           public:
213             typedef void (*CbType)(IConnection* connection, void* event_info,
214                                    ArgType1 *arg1);
215
216             EvasConnection1(Evas_Callback_Type type,
217                             CbType callback,
218                             ArgType1* arg1,
219                             EvasObjectShared* object) :
220                 EvasConnectionBase(type, object),
221                 m_callback(callback),
222                 m_arg1(arg1)
223             {}
224
225             virtual ~EvasConnection1()
226             {}
227
228             virtual void Call(void* event_info)
229             {
230                 m_callback(this, event_info, m_arg1);
231             }
232
233           private:
234             CbType m_callback;
235             ArgType1* m_arg1;
236         };
237
238         template <class ArgType1, class ArgType2>
239         class EvasConnection2 : public EvasConnectionBase
240         {
241           public:
242             typedef void (*CbType)(IConnection* connection, void* event_info,
243                                    ArgType1 *arg1, ArgType2 *arg2);
244
245             EvasConnection2(Evas_Callback_Type type,
246                             CbType callback,
247                             ArgType1* arg1,
248                             ArgType2* arg2,
249                             EvasObjectShared* object) :
250                 EvasConnectionBase(type, object),
251                 m_callback(callback),
252                 m_arg1(arg1),
253                 m_arg2(arg2)
254             {}
255
256             virtual ~EvasConnection2()
257             {}
258
259             virtual void Call(void* event_info)
260             {
261                 m_callback(this, event_info, m_arg1, m_arg2);
262             }
263
264           private:
265             CbType m_callback;
266             ArgType1* m_arg1;
267             ArgType2* m_arg2;
268         };
269
270         template <class ThisType, class ArgType1>
271         class EvasMemberConnection1 : public EvasConnectionBase
272         {
273           public:
274             typedef void (ThisType::*CbType)(IConnection* connection,
275                                              void* event_info, ArgType1 *arg1);
276
277             EvasMemberConnection1(Evas_Callback_Type type,
278                                   CbType callback,
279                                   ThisType* callee,
280                                   ArgType1* arg1,
281                                   EvasObjectShared* object) :
282                 EvasConnectionBase(type, object),
283                 m_callback(callback),
284                 m_callee(callee),
285                 m_arg1(arg1)
286             {}
287
288             virtual ~EvasMemberConnection1()
289             {}
290
291             virtual void Call(void* event_info)
292             {
293                 (m_callee->*m_callback)(this, event_info, m_arg1);
294             }
295
296           private:
297             CbType m_callback;
298             ThisType* m_callee;
299             ArgType1* m_arg1;
300         };
301
302         template <class ThisType, class ArgType1, class ArgType2>
303         class EvasMemberConnection2 : public EvasConnectionBase
304         {
305           public:
306             typedef void (ThisType::*CbType)(IConnection* connection,
307                                              void* event_info, ArgType1* arg1,
308                                              ArgType2* arg2);
309
310             EvasMemberConnection2(Evas_Callback_Type type,
311                                   CbType callback,
312                                   ThisType* callee,
313                                   ArgType1* arg1,
314                                   ArgType2* arg2,
315                                   EvasObjectShared* object) :
316                 EvasConnectionBase(type, object),
317                 m_callback(callback),
318                 m_callee(callee),
319                 m_arg1(arg1),
320                 m_arg2(arg2)
321             {}
322
323             virtual ~EvasMemberConnection2()
324             {}
325
326             virtual void Call(void* event_info)
327             {
328                 (m_callee->*m_callback)(this, event_info, m_arg1, m_arg2);
329             }
330
331           private:
332             CbType m_callback;
333             ThisType* m_callee;
334             ArgType1* m_arg1;
335             ArgType2* m_arg2;
336         };
337
338         EvasObjectShared();
339         explicit EvasObjectShared(Evas_Object* object);
340         void SetObject(Evas_Object* object);
341         ~EvasObjectShared();
342
343         template<typename ... Args>
344         IConnection* ConnectSmartCallback(
345             const char* callbackName,
346             typename SmartConnection<Args ...>::
347                 CbType callback,
348             Args ... args)
349         {
350             Assert(m_object);
351             Assert(callbackName);
352             Assert(callback);
353             IConnection* connection = new SmartConnection<Args ...>(
354                     callbackName,
355                     callback,
356                     this,
357                     args ...);
358             m_connections.insert(connection);
359             connection->ConnectPrv();
360             return connection;
361         }
362
363         template <class ThisType, class ArgType1, class ArgType2>
364         IConnection* ConnectMemberSmartCallback(
365             const char* callbackName,
366             typename SmartMemberConnection2<ThisType, ArgType1,
367                                             ArgType2>::CbType callback,
368             ThisType* callee,
369             ArgType1* arg1,
370             ArgType2* arg2)
371         {
372             Assert(m_object);
373             Assert(callee);
374             Assert(callbackName);
375             Assert(callback);
376             IConnection* connection =
377                 new SmartMemberConnection2<ThisType, ArgType1, ArgType2>(
378                     callbackName,
379                     callback,
380                     callee,
381                     arg1,
382                     arg2,
383                     this);
384             m_connections.insert(connection);
385             connection->ConnectPrv();
386             return connection;
387         }
388
389         template <class ThisType, class ArgType1>
390         IConnection* ConnectMemberSmartCallback(
391             const char* callbackName,
392             typename SmartMemberConnection1<ThisType,
393                                             ArgType1>::CbType callback,
394             ThisType* callee,
395             ArgType1* arg1)
396         {
397             Assert(m_object);
398             Assert(callee);
399             Assert(callbackName);
400             Assert(callback);
401             IConnection* connection =
402                 new SmartMemberConnection1<ThisType, ArgType1>(callbackName,
403                                                                callback,
404                                                                callee,
405                                                                arg1,
406                                                                this);
407             m_connections.insert(connection);
408             connection->ConnectPrv();
409             return connection;
410         }
411
412         template <class ArgType1, class ArgType2>
413         IConnection* ConnectEvasCallback(Evas_Callback_Type callbackType,
414                                          typename EvasConnection2<ArgType1,
415                                                                   ArgType2>::
416                                              CbType callback,
417                                          ArgType1* arg1,
418                                          ArgType2* arg2)
419         {
420             Assert(m_object);
421             Assert(callbackType);
422             Assert(callback);
423             IConnection* connection = new EvasConnection2<ArgType1, ArgType2>(
424                     callbackType,
425                     callback,
426                     arg1,
427                     arg2,
428                     this);
429             m_connections.insert(connection);
430             connection->ConnectPrv();
431             return connection;
432         }
433
434         template <class ArgType1>
435         IConnection* ConnectEvasCallback(
436             Evas_Callback_Type callbackType,
437             typename EvasConnection1<ArgType1>::
438                 CbType callback,
439             ArgType1* arg1)
440         {
441             Assert(m_object);
442             Assert(callbackType);
443             Assert(callback);
444             IConnection* connection = new EvasConnection1<ArgType1>(
445                     callbackType,
446                     callback,
447                     arg1,
448                     this);
449             m_connections.insert(connection);
450             connection->ConnectPrv();
451             return connection;
452         }
453
454         template <class ThisType, class ArgType1, class ArgType2>
455         IConnection* ConnectMemberEvasCallback(
456             Evas_Callback_Type callbackType,
457             typename EvasMemberConnection2<ThisType, ArgType1,
458                                            ArgType2>::CbType callback,
459             ThisType* callee,
460             ArgType1* arg1,
461             ArgType2* arg2)
462         {
463             Assert(m_object);
464             Assert(callee);
465             Assert(callbackType);
466             Assert(callback);
467             IConnection* connection =
468                 new EvasMemberConnection2<ThisType, ArgType1, ArgType2>(
469                     callbackType,
470                     callback,
471                     callee,
472                     arg1,
473                     arg2,
474                     this);
475             m_connections.insert(connection);
476             connection->ConnectPrv();
477             return connection;
478         }
479
480         template <class ThisType, class ArgType1>
481         IConnection* ConnectMemberEvasCallback(
482             Evas_Callback_Type callbackType,
483             typename EvasMemberConnection1<ThisType,
484                                            ArgType1>::CbType callback,
485             ThisType* callee,
486             ArgType1* arg1)
487         {
488             Assert(m_object);
489             Assert(callee);
490             Assert(callbackType);
491             Assert(callback);
492             IConnection* connection =
493                 new EvasMemberConnection1<ThisType, ArgType1>(callbackType,
494                                                               callback,
495                                                               callee,
496                                                               arg1,
497                                                               this);
498             m_connections.insert(connection);
499             connection->ConnectPrv();
500             return connection;
501         }
502
503         bool DisconnectCallback(IConnection* connection);
504         void DisconnectAll();
505
506         static void StaticOnDelEvent(void* data,
507                                      Evas* /*e*/,
508                                      Evas_Object* /*o*/,
509                                      void* /*ev*/);
510
511         IConnectionsSet m_connections;
512         Evas_Object* m_object;
513     };
514
515   public:
516     EvasObject();
517     explicit EvasObject(Evas_Object* object);
518     EvasObject(const EvasObject& other);
519     ~EvasObject();
520
521     EvasObject& operator=(const EvasObject& other);
522     EvasObject* operator=(Evas_Object* object);
523
524     operator Evas_Object *();
525
526     bool IsValid() const
527     {
528         Assert(m_object);
529         return m_object->GetObject() != NULL;
530     }
531
532     bool DisconnectCallback(IConnection* connection);
533     void DisconnectAll();
534
535     template <class ... Args>
536     IConnection* ConnectSmartCallback(
537         const char* callbackName,
538         typename EvasObjectShared::SmartConnection<Args ...>::CbType
539         callback,
540         Args ... args)
541     {
542         Assert(m_object);
543         return m_object->ConnectSmartCallback(callbackName, callback, args ...);
544     }
545
546     template <class ThisType, class ArgType1, class ArgType2>
547     IConnection* ConnectMemberSmartCallback(
548         const char* callbackName,
549         typename EvasObjectShared::SmartMemberConnection2<ThisType,
550                                                           ArgType1,
551                                                           ArgType2>::CbType
552         callback,
553         ThisType* callee,
554         ArgType1* arg1,
555         ArgType2* arg2)
556     {
557         Assert(m_object);
558         Assert(callee);
559         Assert(callback);
560         return m_object->ConnectMemberSmartCallback(callbackName,
561                                                     callback,
562                                                     callee,
563                                                     arg1,
564                                                     arg2);
565     }
566
567     template <class ThisType, class ArgType1>
568     IConnection* ConnectMemberSmartCallback(
569         const char* callbackName,
570         typename EvasObjectShared::SmartMemberConnection1<ThisType,
571                                                           ArgType1>::CbType
572         callback,
573         ThisType* callee,
574         ArgType1* arg1)
575     {
576         Assert(m_object);
577         Assert(callee);
578         Assert(callback);
579         return m_object->ConnectMemberSmartCallback(callbackName,
580                                                     callback,
581                                                     callee,
582                                                     arg1);
583     }
584
585     template <class ArgType1, class ArgType2>
586     IConnection* ConnectEvasCallback(
587         Evas_Callback_Type callbackType,
588         typename EvasObjectShared::EvasConnection1<ArgType1>::CbType
589         callback,
590         ArgType1* arg1,
591         ArgType2* arg2)
592     {
593         Assert(m_object);
594         return m_object->ConnectEvasCallback(callbackType, callback, arg1, arg2);
595     }
596
597     template <class ArgType1>
598     IConnection* ConnectEvasCallback(
599         Evas_Callback_Type callbackType,
600         typename EvasObjectShared::EvasConnection1<ArgType1>::CbType
601         callback,
602         ArgType1* arg1)
603     {
604         Assert(m_object);
605         return m_object->ConnectEvasCallback(callbackType, callback, arg1);
606     }
607
608     template <class ThisType, class ArgType1>
609     IConnection* ConnectMemberEvasCallback(
610         Evas_Callback_Type callbackType,
611         typename EvasObjectShared::EvasMemberConnection1<ThisType,
612                                                          ArgType1>::CbType
613         callback,
614         ThisType* callee,
615         ArgType1* arg1)
616     {
617         Assert(m_object);
618         Assert(callee);
619         Assert(callback);
620         return m_object->ConnectMemberEvasCallback(callbackType,
621                                                    callback,
622                                                    callee,
623                                                    arg1);
624     }
625
626     template <class ThisType, class ArgType1, class ArgType2>
627     IConnection* ConnectMemberEvasCallback(
628         Evas_Callback_Type callbackType,
629         typename EvasObjectShared::EvasMemberConnection2<ThisType, ArgType1,
630                                                          ArgType2>::CbType
631         callback,
632         ThisType* callee,
633         ArgType1* arg1,
634         ArgType2* arg2)
635     {
636         Assert(m_object);
637         Assert(callee);
638         Assert(callback);
639         return m_object->ConnectMemberEvasCallback(callbackType,
640                                                    callback,
641                                                    callee,
642                                                    arg1,
643                                                    arg2);
644     }
645
646   private:
647     EvasObjectSharedPtr m_object;
648 };
649 }
650 } //namespace
651 } //namespace
652
653 #endif //WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H
654