Fix issues shown by cppcheck for wrt-plugins-common
[platform/framework/web/wrt-plugins-common.git] / src / wrt-popup / wrt / popup-bin / renderer / popup_renderer.cpp
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_renderer.cpp
18  * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version     1.0
20  * @brief       This is efl specific implementation for PopupRenderer
21  */
22
23 #include "popup_renderer.h"
24 #include <stddef.h>
25 #include <dpl/scoped_array.h>
26 #include <dpl/assert.h>
27 #include <dpl/log/log.h>
28 #include <dpl/foreach.h>
29 #include <dpl/framework_efl.h>
30 #include <dpl/lexical_cast.h>
31 #include <queue>
32 #include "popup_manager.h"
33 #include "popup_manager.h"
34 #include "evas_object.h"
35
36 namespace Wrt {
37 namespace {
38 using namespace Popup;
39 const char* EDJ_NAME = "/usr/share/edje/ace/generic_popup.edj";
40 const char* POPUP_LAYOUT1 = "popup_layout1";
41 const char* POPUP_LAYOUT2 = "popup_layout2";
42 const char* POPUP_PART_TITLE = "title,text";
43 const char* POPUP_PART_BUTTON1 = "button1";
44 const char* POPUP_PART_BUTTON2 = "button2";
45 const char* POPUP_PART_BUTTON3 = "button3";
46 const char* BUTTON_CLICKED_CALLBACK_NAME = "clicked";
47 const char* CHANGED_CALLBACK_NAME = "changed";
48 const unsigned int MAX_NUMBER_OF_VERTICAL = 2;
49
50 Evas_Object* create_layout_main(Evas_Object* parent, int totalV)
51 {
52     Evas_Object *layout = elm_layout_add(parent);
53
54     if (totalV == 1) {
55         elm_layout_file_set(layout, EDJ_NAME, POPUP_LAYOUT1);
56     } else if (totalV == 2) {
57         elm_layout_file_set(layout, EDJ_NAME, POPUP_LAYOUT2);
58     } else {
59         Assert("popup needs define new group in the edc");
60     }
61
62     evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
63                                      EVAS_HINT_EXPAND);
64     return layout;
65 }
66 } //namespace
67
68 namespace Popup {
69 namespace Renderer {
70 class PopupRenderer::Impl
71 {
72   public:
73     Impl() :
74         m_popupsToRender(),
75         m_current(),
76         m_initialized(false),
77         m_checkState(false),
78         m_themeIndexV(0),
79         m_externalCanvas(NULL)
80     {}
81
82     ~Impl()
83     {
84         if (m_initialized) {
85             LogError("Destroyed without Deinitialize");
86         }
87     }
88
89     void Initialize()
90     {
91         Assert(!m_initialized);
92         m_initialized = true;
93     }
94
95     void Deinitialize()
96     {
97         Assert(m_initialized);
98         m_current.reset();
99         while (!m_popupsToRender.empty()) {
100             m_popupsToRender.pop();
101         }
102         m_initialized = false;
103     }
104
105     void ButtonCallback(EvasObject::IConnection* /*connection*/,
106                         void* /*event_info*/,
107                         void* data)
108     {
109         LogInfo("ButtonCallback");
110         Assert(m_initialized);
111         AnswerCallbackData answerData;
112
113         answerData.buttonAnswer = reinterpret_cast<int>(data);
114         answerData.chackState = m_checkState;
115         answerData.password = m_password;
116         m_current->ForwardAnswer(answerData);
117         m_current.reset();
118
119         FOREACH(it, m_createdObjects)
120         {
121             if (it->IsValid()) {
122                 evas_object_del(*it);
123             }
124         }
125         m_createdObjects.clear();
126         m_checkState = false;
127         DoRender();
128     }
129
130     void CheckCallback(EvasObject::IConnection* connection,
131                        void* /*event_info*/,
132                        void* /* unused */)
133     {
134         m_checkState =
135             elm_check_state_get(connection->GetEvasObject());
136     }
137
138     void Render (PopupPtr popup)
139     {
140         Assert(m_initialized);
141         m_popupsToRender.push(popup);
142         DoRender();
143     }
144
145     void DoRender(const PopupObject::Label& object,
146                   EvasObject& parent,
147                   EvasObject& layout,
148                   int themeIndex)
149     {
150         EvasObject label(elm_label_add(parent));
151
152         elm_object_style_set(label, "popup_description/default");
153         elm_label_line_wrap_set(label, ELM_WRAP_WORD);
154         elm_object_text_set(label, object.getLabel().c_str());
155         evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0);
156         evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
157         evas_object_show(label);
158
159         elm_object_part_content_set(
160             layout,
161             DPL::lexical_cast<std::string>(themeIndex).c_str(),
162             label);
163         m_createdObjects.push_back(label);
164     }
165
166     void DoRender(const PopupObject::Check& object,
167                   EvasObject& parent,
168                   EvasObject& layout,
169                   int themeIndex)
170     {
171         EvasObject check(elm_check_add(parent));
172
173         evas_object_size_hint_align_set(check, EVAS_HINT_FILL, EVAS_HINT_FILL);
174         evas_object_size_hint_weight_set(check, EVAS_HINT_EXPAND, 0.0);
175         elm_object_text_set(check,
176                             object.getCheckLabel().c_str());
177         elm_object_part_content_set(
178             layout,
179             DPL::lexical_cast<std::string>(themeIndex).c_str(),
180             check);
181
182         check.ConnectMemberSmartCallback(CHANGED_CALLBACK_NAME,
183                                          &Impl::CheckCallback,
184                                          this,
185                                          static_cast<void*>(NULL));
186         evas_object_show(check);
187         m_createdObjects.push_back(check);
188     }
189
190     void DoRender(const PopupObject::Button& object,
191                   EvasObject &parent)
192     {
193         EvasObject btn(elm_button_add(parent));
194
195         elm_object_text_set(btn, object.getLabel().c_str());
196         elm_object_part_content_set(parent, POPUP_PART_BUTTON1, btn);
197         btn.ConnectMemberSmartCallback(BUTTON_CLICKED_CALLBACK_NAME,
198                                        &Impl::ButtonCallback,
199                                        this,
200                                        reinterpret_cast<void*>(object.
201                                                                    getLabelId()));
202         m_createdObjects.push_back(btn);
203     }
204
205     void DoRender(const PopupObject::Button& object1,
206                   const PopupObject::Button& object2,
207                   EvasObject &parent)
208     {
209         DoRender(object1, parent);
210
211         EvasObject btn2(elm_button_add(parent));
212
213         elm_object_text_set(btn2, object2.getLabel().c_str());
214         elm_object_part_content_set(parent, POPUP_PART_BUTTON2, btn2);
215         btn2.ConnectMemberSmartCallback(BUTTON_CLICKED_CALLBACK_NAME,
216                                         &Impl::ButtonCallback,
217                                         this,
218                                         reinterpret_cast<void*>(object2.
219                                                                     getLabelId()));
220         m_createdObjects.push_back(btn2);
221     }
222
223     void DoRender(const PopupObject::Button& object1,
224                   const PopupObject::Button& object2,
225                   const PopupObject::Button& object3,
226                   EvasObject &parent)
227     {
228         DoRender(object1, object2, parent);
229
230         EvasObject btn3(elm_button_add(parent));
231
232         elm_object_text_set(btn3, object3.getLabel().c_str());
233         elm_object_part_content_set(parent, POPUP_PART_BUTTON3, btn3);
234         btn3.ConnectMemberSmartCallback(BUTTON_CLICKED_CALLBACK_NAME,
235                                         &Impl::ButtonCallback,
236                                         this,
237                                         reinterpret_cast<void*>(object3.
238                                                                     getLabelId()));
239         m_createdObjects.push_back(btn3);
240     }
241
242     EvasObject getBaseObject()
243     {
244         if (getExternalCanvas() == NULL) {
245             LogInfo("Create old style popup");
246             EvasObject win(elm_win_add(NULL, "Popup", ELM_WIN_DIALOG_BASIC));
247             elm_win_borderless_set(win, EINA_TRUE);
248             elm_win_alpha_set(win, EINA_TRUE);
249             elm_win_raise(win);
250             {
251                 int w, h, x, y;
252                 ecore_x_window_geometry_get(ecore_x_window_root_first_get(),
253                                             &x,
254                                             &y,
255                                             &w,
256                                             &h);
257                 evas_object_resize(win, w, h);
258                 evas_object_move(win, x, y);
259             }
260             m_createdObjects.push_back(win);
261             evas_object_show(win);
262             return win;
263         } else {
264             LogInfo("Create new style popup");
265             EvasObject win(getExternalCanvas());
266             evas_object_show(win);
267             return win;
268         }
269     }
270
271     void DoRender()
272     {
273         if (!m_current && !m_popupsToRender.empty()) {
274             m_current = m_popupsToRender.front();
275             m_popupsToRender.pop();
276
277             m_themeIndexV = 0;
278
279             // preprocessing
280             std::vector<int> countPopupObjects = { 0 /* PopupObject::BUTTON */,
281                                                    0 /* PopupObject::LABEL */,
282                                                    0 /* PopupObject::CHECK */ };
283             FOREACH(it, m_current->GetPopupObjects()) {
284                 Assert((*it)->getType() < countPopupObjects.size() &&
285                        "Wrong PopupObject assigned");
286                 countPopupObjects[(*it)->getType()]++;
287             }
288             int needsIndexV = countPopupObjects[PopupObject::LABEL] +
289                 countPopupObjects[PopupObject::CHECK];
290
291             EvasObject win = getBaseObject();
292             EvasObject main(elm_popup_add(win));
293
294             evas_object_size_hint_weight_set(main,
295                                              EVAS_HINT_EXPAND,
296                                              EVAS_HINT_EXPAND);
297             elm_object_part_text_set(main,
298                                      POPUP_PART_TITLE,
299                                      m_current->GetTitle().c_str());
300
301             m_createdObjects.push_back(main);
302             std::vector<PopupObject::Button> buttonObjectList;
303             EvasObject layout(create_layout_main(main, needsIndexV));
304             m_createdObjects.push_back(layout);
305
306             FOREACH(it, m_current->GetPopupObjects()) {
307                 switch ((*it)->getType()) {
308                 case PopupObject::BUTTON:
309                     buttonObjectList.push_back(*(*it)->asButton());
310                     break;
311                 case PopupObject::LABEL:
312                     DoRender(*(*it)->asLabel(),
313                              main,
314                              layout,
315                              m_themeIndexV++);
316                     break;
317                 case PopupObject::CHECK:
318                     DoRender(*(*it)->asCheck(),
319                              main,
320                              layout,
321                              m_themeIndexV++);
322                     break;
323                 default:
324                     Assert("incorrect type");
325                 }
326                 Assert(m_themeIndexV <= MAX_NUMBER_OF_VERTICAL);
327             }
328             elm_object_content_set(main,
329                                    layout);
330
331             // show buution
332             switch (buttonObjectList.size()) {
333             case 0:
334                 LogInfo("no button");
335                 break;
336             case 1:
337                 DoRender(buttonObjectList.at(0),
338                          main);
339                 break;
340             case 2:
341                 DoRender(buttonObjectList.at(0),
342                          buttonObjectList.at(1),
343                          main);
344                 break;
345             case 3:
346                 DoRender(buttonObjectList.at(0),
347                          buttonObjectList.at(1),
348                          buttonObjectList.at(2),
349                          main);
350                 break;
351             default:
352                 Assert("incorrect button number");
353                 break;
354             }
355
356             evas_object_show(main);
357         }
358     }
359
360     void setExternalCanvas(void* externalCanvas)
361     {
362         m_externalCanvas = static_cast<Evas_Object*>(externalCanvas);
363     }
364
365     Evas_Object* getExternalCanvas() const
366     {
367         return m_externalCanvas;
368     }
369
370     std::queue<PopupPtr> m_popupsToRender;
371     std::list<EvasObject> m_createdObjects;
372     PopupPtr m_current;
373     bool m_initialized;
374     bool m_checkState;
375     DPL::Optional<std::string> m_password;
376     unsigned int m_themeIndexV;
377
378   private:
379     Evas_Object* m_externalCanvas;
380 };
381
382 PopupRenderer::PopupRenderer()
383 {
384     m_impl = new PopupRenderer::Impl();
385 }
386
387 PopupRenderer::~PopupRenderer()
388 {
389     delete m_impl;
390 }
391
392 void PopupRenderer::Initialize()
393 {
394     Assert(m_impl);
395     m_impl->Initialize();
396 }
397
398 void PopupRenderer::Deinitialize()
399 {
400     Assert(m_impl);
401     m_impl->Deinitialize();
402 }
403
404 IPopupPtr PopupRenderer::CreatePopup()
405 {
406     return std::static_pointer_cast<IPopup>(IPopupPtr
407                                                 (new Popup(shared_from_this())));
408 }
409
410 void PopupRenderer::Render(PopupPtr popup)
411 {
412     m_impl->Render(popup);
413 }
414
415 void PopupRenderer::setExternalCanvas(void* externalCanvas)
416 {
417     m_impl->setExternalCanvas(externalCanvas);
418 }
419 }
420 } // namespace Popup
421 } // namespace Wrt