2 * Tizen Krate launcher application
4 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 static uidata_s ud = {0, };
25 static int __num_of_apps = 0;
26 static bool __is_edit_mode = false;
27 static Ecore_Timer *__app_icon_long_press_timer = NULL;
29 static void __block_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
34 static void __app_view_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
36 eina_list_free(ud.app_icon_list);
39 static void __set_kaskit_layout()
41 ud.panel = _create_layout(ud.layout, ud.edj_path, "popup_layout");
43 elm_object_part_content_set(ud.layout, "popup_window", ud.panel);
45 ud.scroller = elm_scroller_add(ud.panel);
46 elm_scroller_bounce_set(ud.scroller, EINA_FALSE, EINA_TRUE);
47 elm_scroller_policy_set(ud.scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
48 elm_object_part_content_set(ud.panel, "popup_content", ud.scroller);
50 ud.app_view = elm_table_add(ud.scroller);
51 elm_table_homogeneous_set(ud.app_view, EINA_TRUE);
52 elm_object_content_set(ud.scroller, ud.app_view);
54 evas_object_event_callback_add(ud.app_view, EVAS_CALLBACK_DEL, __app_view_del_cb, NULL);
59 static char *__get_res_path(const char *file)
61 char *res_path = NULL;
62 char edj_path[PATH_MAX] = "\0";
64 res_path = app_get_resource_path();
65 if (res_path == NULL) {
66 dlog_print(DLOG_ERROR, LOG_TAG, "failed get resource path");
69 snprintf(edj_path, PATH_MAX, "%s%s", res_path, file);
73 return strdup(edj_path);
76 static Eina_Bool key_event_cb(void *data, int type, void *event)
78 Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *)event;
80 if (!strcmp(ev->keyname, "XF86Back")) {
85 __is_edit_mode = false;
87 EINA_LIST_FOREACH(ud.app_icon_list, i, icon) {
88 elm_object_signal_emit(icon, "uninstall_button_hide", "source");
89 elm_object_signal_emit(icon, "icon_sub_badge_show", "source");
99 void _create_kaskit_window()
101 ud.edj_path = __get_res_path(PACKAGE ".edj");
102 ud.win = _create_win(PACKAGE);
103 ud.conform = _create_conformant(ud.win);
104 ud.layout = _create_layout(ud.conform, ud.edj_path, "main_window");
105 elm_object_content_set(ud.conform, ud.layout);
107 __set_kaskit_layout();
109 evas_object_show(ud.win);
114 void _set_kaskit_window_exit_cb()
116 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_event_cb, NULL);
118 elm_object_signal_callback_add(ud.layout, "bg_clicked", "layout", __block_clicked_cb, NULL);
121 static Eina_Bool __app_icon_long_press_cb(void *data)
126 EINA_LIST_FOREACH(ud.app_icon_list, i, icon) {
127 if (evas_object_data_get(icon, "removable")) {
128 elm_object_signal_emit(icon, "uninstall_button_show", "source");
130 elm_object_signal_emit(icon, "icon_sub_badge_hide", "source");
133 __is_edit_mode = true;
135 return ECORE_CALLBACK_CANCEL;
138 void _set_kaskit_window_title(const char *title)
140 elm_object_part_text_set(ud.panel, "popup_title", title);
143 static int __icon_down_x, __icon_down_y;
144 static void __app_icon_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
146 Evas_Event_Mouse_Up *ev = event_info;
148 __icon_down_x = ev->output.x;
149 __icon_down_y = ev->output.y;
151 __app_icon_long_press_timer = ecore_timer_add(LONG_PRESS_TIME, __app_icon_long_press_cb, NULL);
154 static void __app_icon_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
156 Evas_Event_Mouse_Up *ev = event_info;
158 int distance_x = (ev->output.x - __icon_down_x);
159 int distance_y = (ev->output.y - __icon_down_y);
160 int distance = distance_x * distance_x + distance_y * distance_y;
162 if (distance > ALLOWED_ICON_DRAG_DISTANCE) {
163 if (__app_icon_long_press_timer != NULL) {
164 ecore_timer_del(__app_icon_long_press_timer);
165 __app_icon_long_press_timer = NULL;
170 static void __app_icon_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
172 Evas_Event_Mouse_Up *ev = event_info;
174 int distance_x = (ev->output.x - __icon_down_x);
175 int distance_y = (ev->output.y - __icon_down_y);
176 int distance = distance_x * distance_x + distance_y * distance_y;
178 if (distance <= ALLOWED_ICON_DRAG_DISTANCE && !__is_edit_mode) {
179 _icon_clicked_cb(evas_object_data_get(obj, "id"));
182 if (__app_icon_long_press_timer != NULL) {
183 ecore_timer_del(__app_icon_long_press_timer);
184 __app_icon_long_press_timer = NULL;
188 static void __app_icon_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
190 free(evas_object_data_get(obj, "id"));
191 free(evas_object_data_get(obj, "package"));
194 static void __app_icon_uninstall_btn_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
196 _icon_uninstalled_cb(evas_object_data_get(obj, "package"));
199 void _create_app_icon(const char *pkg_id, const char *app_id, const char *label, const char *icon, bool removable)
201 char string[1024] = {0, }, *default_icon;
202 Evas_Object *icon_layout;
203 Evas_Object *icon_image;
205 icon_layout = _create_layout(ud.app_view, ud.edj_path, "icon");
206 evas_object_size_hint_weight_set(icon_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
207 evas_object_size_hint_align_set(icon_layout, 0.0, 0.0);
209 icon_image = elm_image_add(icon_layout);
210 if (ecore_file_can_read(icon)) {
211 elm_image_file_set(icon_image, icon, NULL);
213 default_icon = __get_res_path("images/default_app_icon.png");
214 elm_image_file_set(icon_image, default_icon, NULL);
217 evas_object_size_hint_min_set(icon_image, ICON_IMG_SIZE, ICON_IMG_SIZE);
218 evas_object_size_hint_max_set(icon_image, ICON_IMG_SIZE, ICON_IMG_SIZE);
220 snprintf(string, sizeof(string), "<font_size=%d><color=#%s><shadow_color=#%s>%s</shadow_color></color></font_size>",
221 ICON_TXT_SIZE_NORMAL, ICON_TXT_COLOR, ICON_TXT_SHADOW_COLOR,
223 elm_object_part_text_set(icon_layout, "icon_name", string);
225 elm_object_part_content_set(icon_layout, "icon_content", icon_image);
227 evas_object_data_set(icon_layout, "id", strdup(app_id));
228 evas_object_data_set(icon_layout, "package", strdup(pkg_id));
229 evas_object_data_set(icon_layout, "removable", (const void *)removable);
231 evas_object_event_callback_add(icon_layout, EVAS_CALLBACK_DEL, __app_icon_del_cb, NULL);
232 evas_object_event_callback_add(icon_layout, EVAS_CALLBACK_MOUSE_DOWN, __app_icon_down_cb, NULL);
233 evas_object_event_callback_add(icon_layout, EVAS_CALLBACK_MOUSE_MOVE, __app_icon_move_cb, NULL);
234 evas_object_event_callback_add(icon_layout, EVAS_CALLBACK_MOUSE_UP, __app_icon_up_cb, NULL);
236 elm_object_signal_callback_add(icon_layout, "uninstall_button_clicked", "source", __app_icon_uninstall_btn_clicked_cb, NULL);
238 elm_table_pack(ud.app_view, icon_layout, __num_of_apps % 3, __num_of_apps / 3, 1, 1);
239 evas_object_size_hint_min_set(ud.app_view, 0, (__num_of_apps / 3 + 1) * ICON_SIZE_H);
241 ud.app_icon_list = eina_list_append(ud.app_icon_list, icon_layout);
245 evas_object_show(icon_image);
246 evas_object_show(icon_layout);
248 if (__is_edit_mode && removable) {
249 elm_object_signal_emit(icon_layout, "uninstall_button_show", "source");
253 void _destroy_app_icon(const char *pkg_id)
256 Eina_List *i, *i_next;
257 Evas_Object *app_icon;
260 EINA_LIST_FOREACH_SAFE(ud.app_icon_list, i, i_next, app_icon) {
261 app_pkg_id = evas_object_data_get(app_icon, "package");
262 if (strncmp(app_pkg_id, pkg_id, PATH_MAX)) {
263 elm_table_pack(ud.app_view, app_icon, index % 3, index / 3, 1, 1);
264 evas_object_size_hint_min_set(ud.app_view, 0, (__num_of_apps / 3 + 1) * ICON_SIZE_H);
268 elm_table_unpack(ud.app_view, app_icon);
269 evas_object_del(app_icon);
270 evas_object_size_hint_min_set(ud.app_view, 0, (__num_of_apps / 3 + 1) * ICON_SIZE_H);
271 ud.app_icon_list = eina_list_remove_list(ud.app_icon_list, i);
274 evas_object_size_hint_min_set(ud.app_view, 0, (__num_of_apps / 3 + 1) * ICON_SIZE_H);
277 void _update_app_icon_badge(const char *app_id, unsigned int count)
279 Eina_List *i, *i_next;
280 Evas_Object *app_icon;
281 char str[8], *icon_app_id;
283 EINA_LIST_FOREACH_SAFE(ud.app_icon_list, i, i_next, app_icon) {
284 icon_app_id = evas_object_data_get(app_icon, "id");
285 if (strncmp(icon_app_id, app_id, PATH_MAX) == 0) {
287 elm_object_signal_emit(app_icon, "icon_badge_hide", "source");
291 if (count > MAX_BADGE_DISPLAY_COUNT) {
292 snprintf(str, 8, "%d+", MAX_BADGE_DISPLAY_COUNT);
294 snprintf(str, 8, "%d", count);
296 elm_layout_text_set(app_icon, "badge_text", str);
297 elm_object_signal_emit(app_icon, "icon_badge_show", "source");