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