3550b3a3b305b516144642c3d4a3075f9c26ae99
[framework/web/wrt-commons.git] / modules / popup / include / dpl / popup / popup_controller.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    popup_controller.h
18  * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version 1.0
20  * @bref    Header file for popup controller
21  */
22
23 /**
24  * To display a popup from a given class:
25  *
26  **class ABC
27  **{
28  *    void AskUser()
29  *    {
30  *    }
31  *
32  *    void DoSomeLogicWithAnswer()
33  *    {
34  *    }
35  **};
36  *
37  * ... update the class to something simmilar:
38  *
39  **class ABC : Popup::PopupControllerUser
40  **{
41  *    void AskUser() {
42  *        using namespace Popup;
43  *        CtrlPopupPtr popup =
44  *                PopupControllerSingletion::Instance().CreatePopup();
45  *        popup->SetTitle("Title");
46  *        popup->SetContent("Content");
47  *        popup->AddButton("name1", 1);
48  *        popup->AddButton("name2", 2);
49  *        ListenForAnswer(popup);
50  *        ShowPopupEvent event(popup,
51  *                             MakeAnswerCallback(this,
52  *                                                &ABC::DoSomeLogicWithAnswer));
53  *        CONTROLLER_POST_EVENT(PopupController, event);
54  *    }
55  *
56  *    void DoSomeLogicWithAnswer(Popup::LabelId answer) {
57  *        if (answer == 1)
58  *            ;//name1 pressed
59  *        else if (answer == 2)
60  *            ;//name2 pressed
61  *    }
62  **};
63  **/
64
65 #ifndef WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_
66 #define WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_
67
68 #include <dpl/singleton.h>
69 #include <dpl/event/controller.h>
70 #include <dpl/event/event_listener.h>
71 #include <dpl/generic_event.h>
72 #include <dpl/mutex.h>
73 #include <dpl/exception.h>
74 #include <dpl/shared_ptr.h>
75 #include <dpl/enable_shared_from_this.h>
76 #include <dpl/noncopyable.h>
77 #include <dpl/log/log.h>
78 #include <dpl/event/nested_loop.h>
79 #include <dpl/popup/popup_manager.h>
80
81 namespace DPL {
82 namespace Popup {
83 typedef int LabelId;
84
85 struct PopupAnswerCallback
86 {
87     typedef void (PopupAnswerCallback::*MemberPtr)();
88
89     void* callee;
90     MemberPtr member;
91     void (*callTranslator)(PopupAnswerCallback* callData,
92             const AnswerCallbackData& answer);
93
94     void Call(const AnswerCallbackData& answer)
95     {
96         callTranslator(this, answer);
97     }
98 };
99
100 class PopupController;
101 class CtrlPopup;
102
103 typedef DPL::SharedPtr<CtrlPopup> CtrlPopupPtr;
104
105 DECLARE_GENERIC_EVENT_3(PopupAnswerEvent,
106                         CtrlPopupPtr,
107                         PopupAnswerCallback,
108                         AnswerCallbackData)
109 DECLARE_GENERIC_EVENT_3(ShowPopupEvent,
110                         CtrlPopupPtr,
111                         PopupAnswerCallback,
112                         DPL::Event::LoopHandle)
113
114 class CtrlPopup : public DPL::Event::EventSupport<PopupAnswerEvent>,
115     protected DPL::EnableSharedFromThis<CtrlPopup>
116 {
117   public:
118     void SetTitle(const std::string &title);
119     void Append(PopupObject::IPopupObject *object);
120
121   private:
122     friend class PopupController;
123     friend class DPL::SharedPtr<CtrlPopup>;
124
125     explicit CtrlPopup(IPopupPtr popup);
126     ~CtrlPopup();
127     void EmitAnswer(const AnswerCallbackData& answer);
128
129     IPopupPtr m_popup;
130     PopupAnswerCallback m_callback;
131     DPL::Event::LoopHandle m_loopHandle;
132 };
133
134 class PopupController :
135     public DPL::Event::Controller<DPL::TypeListDecl<ShowPopupEvent>::Type>
136 {
137   public:
138     CtrlPopupPtr CreatePopup() const;
139
140     void setExternalCanvas(void* canvas)
141     {
142         m_canvas = canvas;
143     }
144     void* getExternalCanvas() const
145     {
146         return m_canvas;
147     }
148     void* m_canvas;
149
150   protected:
151     virtual void OnEventReceived(const ShowPopupEvent& event);
152     PopupController();
153
154   private:
155     static void StaticOnAnswerReceived(const AnswerCallbackData& answer,
156             CtrlPopupPtr* popup);
157 };
158
159 class PopupControllerUser : DPL::Event::EventListener<PopupAnswerEvent>
160 {
161     template <class Type>
162     struct PopupAnswerCallbackCreator
163     {
164         typedef void (Type::*MemberPtr)(const AnswerCallbackData& answer);
165         union Caster
166         {
167             MemberPtr specific;
168             PopupAnswerCallback::MemberPtr generic;
169         };
170
171         static PopupAnswerCallback Create(Type* callee,
172                 MemberPtr callback)
173         {
174             PopupAnswerCallback callData;
175
176             callData.callee = callee;
177
178             Caster caster;
179             caster.specific = callback;
180             callData.member = caster.generic;
181
182             callData.callTranslator =
183                 &PopupAnswerCallbackCreator::MemberCallbackTranslator;
184
185             return callData;
186         }
187
188         static void MemberCallbackTranslator(PopupAnswerCallback* callData,
189                 const AnswerCallbackData& answer)
190         {
191             Type* typedThis = static_cast<Type*>(callData->callee);
192             Caster caster;
193             caster.generic = callData->member;
194             MemberPtr typedCallback = caster.specific;
195             (typedThis->*typedCallback)(answer);
196         }
197     };
198
199   protected:
200     virtual void OnEventReceived(const PopupAnswerEvent& event);
201     void ListenForAnswer(CtrlPopupPtr popup);
202
203     template <class Type>
204     PopupAnswerCallback MakeAnswerCallback(Type* This,
205             void (Type::*callback)
206             (const AnswerCallbackData &))
207     {
208         return PopupAnswerCallbackCreator<Type>::Create(This, callback);
209     }
210 };
211
212 typedef DPL::Singleton<PopupController> PopupControllerSingleton;
213
214 } //namespace Popup
215 } //namespace DPL
216
217 #endif //WRT_SRC_POPUP_CONTROLLER_POPUP_CONTROLLER_H_