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