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