53102831cec2fc10e6eaab6e0cc116cf08678963
[platform/framework/web/crosswalk-tizen.git] / src / runtime / popup.cc
1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "runtime/popup.h"
6
7 #include <efl_assist.h>
8
9 #include "runtime/native_window.h"
10 #include "runtime/popup_string.h"
11 #include "common/logger.h"
12
13 namespace wrt {
14
15 namespace {
16
17 const char* kContentTitle = "title,text";
18 const char* kContentButton1 = "button1";
19 const char* kContentButton2 = "button2";
20
21 const char* kStyleDefault = "default";
22 const char* kStyleLabel = "default";
23 const char* kStyleButton = "popup";
24 const char* kStyleEditPw = "editfield/password/popup";
25
26 const char* kSignalEdit = "elm,action,hide,search_icon";
27
28 const char* kStateActivated = "activated";
29 const char* kStateClicked = "clicked";
30
31 const double kMaxPopupHeight = 0.80;
32 const double kMaxScrollerHeight = 0.80;
33
34 static void ButtonClickedCallback(void* data,
35                                   Evas_Object* obj, void* /*eventInfo*/) {
36   Popup* popup = static_cast<Popup*>(data);
37   if (!popup) {
38     LOGGER(ERROR) << "Fail to get Popup instance";
39     return;
40   }
41   popup->Result(popup->IsPositiveButton(obj));
42   popup->Hide();
43 }
44
45 // caution: not Evas_Object* but Popup*
46 static Evas_Object* AddButton(Popup* popup,
47                               const char* str_id, const char* content) {
48   Evas_Object* btn = elm_button_add(popup->popup());
49   elm_object_style_set(btn, kStyleButton);
50   elm_object_domain_translatable_part_text_set(btn, 0,
51                                                popup_string::kTextDomainWrt,
52                                                str_id);
53   elm_object_part_content_set(popup->popup(), content, btn);
54   evas_object_smart_callback_add(btn, kStateClicked,
55                                  ButtonClickedCallback, popup);
56   return btn;
57 }
58
59 static Evas_Object* AddEntry(Evas_Object* parent, Popup::EntryType type) {
60   Evas_Object* entry = elm_entry_add(parent);
61   elm_object_style_set(entry, kStyleEditPw);
62   elm_entry_single_line_set(entry, EINA_TRUE);
63   elm_entry_scrollable_set(entry, EINA_TRUE);
64   evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
65   evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
66   elm_entry_prediction_allow_set(entry, EINA_FALSE);
67   elm_object_signal_emit(entry, kSignalEdit, "");
68   elm_entry_autocapital_type_set(entry, ELM_AUTOCAPITAL_TYPE_NONE);
69
70   if (type == Popup::EntryType::Edit) {
71     evas_object_smart_callback_add(entry, kStateActivated,
72                                    [](void*, Evas_Object* obj, void*) {
73                                      elm_object_focus_set(obj, EINA_TRUE);
74                                    }, NULL);
75   } else {
76     elm_entry_password_set(entry, EINA_TRUE);
77     elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_PASSWORD);
78   }
79
80   return entry;
81 }
82
83 static Evas_Object* AddEntrySet(Evas_Object* parent,
84                                 const char* str_id, Popup::EntryType type) {
85   // a grid for entry
86   Evas_Object* entry_grid = elm_grid_add(parent);
87   evas_object_size_hint_weight_set(entry_grid, EVAS_HINT_EXPAND,
88                                    EVAS_HINT_EXPAND);
89   evas_object_size_hint_align_set(entry_grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
90   evas_object_show(entry_grid);
91
92   // label for the entry
93   Evas_Object* entry_label = elm_label_add(entry_grid);
94   elm_object_style_set(entry_label, kStyleLabel);
95   elm_object_domain_translatable_part_text_set(entry_label, 0,
96                                                popup_string::kTextDomainWrt,
97                                                str_id);
98   evas_object_color_set(entry_label, 0, 0, 0, 255);
99   evas_object_size_hint_weight_set(entry_label,
100                                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
101   evas_object_size_hint_align_set(entry_label, EVAS_HINT_FILL, EVAS_HINT_FILL);
102   elm_grid_pack(entry_grid, entry_label, 0, 0, 30, 100);
103   evas_object_show(entry_label);
104
105   // entry
106   Evas_Object* entry = AddEntry(entry_grid, type);
107   evas_object_show(entry);
108   elm_grid_pack(entry_grid, entry, 30, 0, 40, 100);
109   elm_box_pack_end(parent, entry_grid);
110
111   return entry;
112 }
113
114 static Evas_Object* AddCheckBox(Evas_Object* parent) {
115   Evas_Object* check = elm_check_add(parent);
116   elm_object_style_set(check, kStyleDefault);
117   elm_object_style_set(check, "multiline");
118   evas_object_size_hint_align_set(check, 0.0, 0.0);
119   evas_object_color_set(check, 0, 0, 0, 255);
120   elm_check_state_set(check, EINA_TRUE);
121   return check;
122 }
123
124 }  // namespace
125
126 Popup* Popup::CreatePopup(NativeWindow* window) {
127   Evas_Object* popup = elm_popup_add(window->evas_object());
128   elm_object_style_set(popup, kStyleDefault);
129
130   Evas_Object* grid = elm_grid_add(popup);
131   evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
132   evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
133   elm_object_part_content_set(popup, "default", grid);
134   evas_object_show(grid);
135
136   Evas_Object* box = elm_box_add(grid);
137   elm_box_padding_set(box, 0, 10);
138   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
139   evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
140   elm_grid_pack(grid, box, 3, 3, 94, 94);
141   evas_object_show(box);
142
143   evas_object_event_callback_add(popup, EVAS_CALLBACK_RESIZE, NULL, NULL);
144
145   return new Popup(popup, grid, box);
146 }
147
148 void Popup::SetButtonType(ButtonType type) {
149   enable_button_ = true;
150   switch (type) {
151     case ButtonType::OkButton:
152     button1_ = AddButton(this, popup_string::kPopupButtonOk,
153                          kContentButton1);
154     break;
155     case ButtonType::OkCancelButton:
156     button1_ = AddButton(this, popup_string::kPopupButtonCancel,
157                          kContentButton1);
158     button2_ = AddButton(this, popup_string::kPopupButtonOk,
159                          kContentButton2);
160     case ButtonType::LoginCancelButton:
161     button1_ = AddButton(this, popup_string::kPopupButtonCancel,
162                          kContentButton1);
163     button2_ = AddButton(this, popup_string::kPopupButtonLogin,
164                          kContentButton2);
165     break;
166     case ButtonType::AllowDenyButton:
167     button1_ = AddButton(this, popup_string::kPopupButtonDeny,
168                          kContentButton1);
169     button2_ = AddButton(this, popup_string::kPopupButtonAllow,
170                          kContentButton2);
171     break;
172   }
173 }
174
175 bool Popup::IsPositiveButton(Evas_Object* button) {
176   if (button == NULL || button1_ == NULL)
177     return false;
178   else
179     return button == button2_;
180 }
181
182 bool Popup::GetButtonResult() const {
183   return result_button_;
184 }
185
186 void Popup::SetFirstEntry(const std::string& str_id, EntryType type) {
187   enable_entry_ = true;
188   entry1_ = AddEntrySet(box_, str_id.c_str(), type);
189 }
190
191 // suppose that it is called after SetFirstEntry()
192 void Popup::SetSecondEntry(const std::string& str_id, EntryType type) {
193   if (!enable_entry_ || !entry1_) {
194     LOGGER(ERROR) << "SetFirstEntry() is not called yet";
195     return;
196   }
197   entry2_ = AddEntrySet(box_, str_id.c_str(), type);
198 }
199
200 std::string Popup::GetFirstEntryResult() const {
201   return result_entry1_;
202 }
203
204 std::string Popup::GetSecondEntryResult() const {
205   return result_entry2_;
206 }
207
208 void Popup::SetCheckBox(const std::string& str_id) {
209   enable_check_box_ = true;
210   check_box_ = AddCheckBox(box_);
211   if (!str_id.empty()) {
212     elm_object_domain_translatable_part_text_set(check_box_, 0,
213                                                  popup_string::kTextDomainWrt,
214                                                  str_id.c_str());
215   }
216   elm_box_pack_end(box_, check_box_);
217   evas_object_show(check_box_);
218 }
219
220 bool Popup::GetCheckBoxResult() const {
221   return result_check_box_;
222 }
223
224 void Popup::SetTitle(const std::string& str_id) {
225   elm_object_domain_translatable_part_text_set(popup_, kContentTitle,
226                                                popup_string::kTextDomainWrt,
227                                                str_id.c_str());
228 }
229
230 void Popup::SetBody(const std::string& str_id) {
231   Evas_Object* label = elm_label_add(box_);
232   elm_object_style_set(label, kStyleLabel);
233   elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
234   elm_object_domain_translatable_part_text_set(label, 0,
235                                                popup_string::kTextDomainWrt,
236                                                str_id.c_str());
237   evas_object_color_set(label, 0, 0, 0, 255);
238   evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
239   evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
240   elm_box_pack_end(box_, label);
241   evas_object_show(label);
242 }
243
244 void Popup::SetResultHandler(std::function<void
245     (Popup* popup, void* user_data)> handler, void* user_data) {
246   handler_ = handler;
247   user_data_ = user_data;
248 }
249
250 void Popup::Show() {
251   evas_object_show(popup_);
252 }
253
254 void Popup::Hide() {
255   evas_object_hide(popup_);
256   evas_object_del(popup_);
257   ecore_idler_add([](void* popup) {
258       Popup* obj = static_cast<Popup*>(popup);
259       delete obj;
260       return EINA_FALSE;
261     }, this);
262 }
263
264 void Popup::Result(bool is_positive) {
265   if (enable_button_) {
266     result_button_ = is_positive;
267   }
268   if (enable_entry_ && !!entry1_) {
269     result_entry1_ = elm_entry_entry_get(entry1_);
270     if (!!entry2_) {
271       result_entry2_ = elm_entry_entry_get(entry2_);
272     }
273   }
274   if (enable_check_box_) {
275     result_check_box_ = elm_check_state_get(check_box_);
276   }
277
278   handler_(this, user_data_);
279 }
280
281 Popup::Popup(Evas_Object* popup, Evas_Object* grid, Evas_Object* box)
282   : popup_(popup), grid_(grid), box_(box) {}
283
284 Popup::~Popup() {}
285
286 }  // namespace wrt