#include <efl_util.h>
#include <app.h>
+#include <tzsh_softkey_service.h>
+#include <tzsh_softkey.h>
+
+
//#define WIN_X 184 // Portrait mode X
//#define WIN_Y 1192 // Portrait mode Y
#define SR_BG_IMAGE_W 1280
#define SR_BG_IMAGE_H 64
+#define POST_ANIM_WIN_W 120
+#define POST_ANIM_WIN_H 8
+
#define SOFTKEY_BG_IMAGE "img/02_bg_softkey_active.png"
typedef struct{
+ //Service data member
+ tzsh_h service_ws_shell;
+ tzsh_window service_tzsh_window;
+ tzsh_softkey_service_h softkey_service;
Evas_Object *window;
Evas_Object *normal_bg;
Evas_Object *screen_reader_bg;
}window_layout_data;
#define WINDOW_LAYOUT_DATA "WINDOW_LAYOUT_DATA"
+#define GESTURE_LAYER_DATA "GESTURE_LAYER_DATA"
static void
static void
win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
{
+ LOG_I("Deleting Window");
window_layout_data *pd = evas_object_data_get(obj, WINDOW_LAYOUT_DATA);
+
+ tzsh_softkey_service_destroy(pd->softkey_service);
+ tzsh_destroy(pd->service_ws_shell);
+ pd->softkey_service = NULL;
+ pd->service_ws_shell = NULL;
+ pd->service_tzsh_window = 0;
+
free(pd);
evas_object_data_set(obj, WINDOW_LAYOUT_DATA, NULL);
+ evas_object_data_set(obj, GESTURE_LAYER_DATA, NULL);
ui_app_exit();
}
+static Evas_Event_Flags window_gesture_momentum_callback(void *data, void *event_info)
+{
+ softkey_visible_state_change();
+
+ return EVAS_EVENT_FLAG_ON_HOLD;
+}
+
+
static void
update_window_layout(Evas_Object *win, softkey_container_mode mode)
{
elm_win_screen_size_get(win, NULL, NULL, NULL, &screen_h);
LOG_I("Screen Height: [H: %d]", screen_h);
+ Evas_Object *gesture_layer = (Evas_Object*)evas_object_data_get(win, GESTURE_LAYER_DATA);
+
switch(mode)
{
case SOFTKEY_MODE_NORMAL:
win_y = (screen_h - WIN_H);
evas_object_move(win, WIN_X, win_y);
evas_object_resize(win, WIN_W, WIN_H);
+ elm_gesture_layer_cb_set(gesture_layer, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END, window_gesture_momentum_callback, NULL);
break;
case SOFTKEY_MODE_SCREEN_READER:
win_y = (screen_h - SR_WIN_H);
evas_object_move(win, SR_WIN_X, win_y);
evas_object_resize(win, SR_WIN_W, SR_WIN_H);
+ elm_gesture_layer_cb_del(gesture_layer, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END, window_gesture_momentum_callback, NULL);
break;
default:
LOG_E("window mode is invalid. failed to update layout");
LOG_I("Setting Window Position Y: %d", win_y);
}
+static Evas_Object* create_gesture_layer(Evas_Object *win)
+{
+ Evas_Object *gesture_layer = elm_gesture_layer_add(win);
+ if(gesture_layer == NULL)
+ {
+ LOG_E("Failed to create gesture layer, swiping might not properly");
+ return NULL;
+ }
+ elm_gesture_layer_attach(gesture_layer, win);
+ evas_object_show(gesture_layer);
+ return gesture_layer;
+}
+
static Evas_Object*
create_window(softkey_container_mode mode)
{
- Evas_Object *win = elm_win_add(NULL, "SoftKey-Container", ELM_WIN_NOTIFICATION);
+ Evas_Object *win = elm_win_add(NULL, "SoftKey-Container", ELM_WIN_BASIC);
if(win == NULL)
{
LOG_E("Failed to create elm_win object");
}
elm_win_title_set(win, "SoftKey-Container");
- /** Set Notification level for the window. */
- efl_util_set_notification_window_level(win, EFL_UTIL_NOTIFICATION_LEVEL_TOP);
-
elm_win_alpha_set(win, EINA_TRUE);
elm_win_borderless_set(win, EINA_TRUE);
elm_win_autodel_set(win, EINA_TRUE);
evas_object_smart_callback_add(win, "delete,request", win_delete_request_cb, NULL);
- /** set window property to skip focus events */
- elm_win_prop_focus_skip_set(win, EINA_TRUE);
-
/** window resize hint set */
elm_win_aux_hint_add(win, "wm.policy.win.user.geometry", "1");
/** Disabling focus for the window */
elm_object_focus_allow_set(win, EINA_FALSE);
+ /** Adding gesture layer to window for swipe up and down event */
+ Evas_Object *gesture = create_gesture_layer(win);
+ if(gesture)
+ {
+ evas_object_data_set(win, GESTURE_LAYER_DATA, (const void*)gesture);
+ }
+
/** update window layout based on mode */
update_window_layout(win, mode);
return bg_rect;
}
+void softkey_window_geometry_update(Evas_Object *win, Eina_Bool post_animation)
+{
+ if(win == NULL)
+ {
+ LOG_E("Window object is null, can't update geometry");
+ return;
+ }
+
+ int screen_h = 0, screen_w = 0, win_x = 0, win_y = 0;
+ elm_win_screen_size_get(win, NULL, NULL, &screen_w, &screen_h);
+
+ if(post_animation)
+ {
+ evas_object_resize(win, POST_ANIM_WIN_W, POST_ANIM_WIN_H);
+ win_x = (screen_w - POST_ANIM_WIN_W)/2;
+ win_y = (screen_h - POST_ANIM_WIN_H);
+ evas_object_move(win, win_x, win_y);
+ }
+ else
+ {
+ evas_object_resize(win, WIN_W, WIN_H);
+ win_x = (screen_w - WIN_W)/2;
+ win_y = (screen_h - POST_ANIM_WIN_H);
+ evas_object_move(win, win_x, win_y);
+ }
+}
+
+static void
+softkey_service_visible_change_cb(void *data, tzsh_softkey_service_h service, tzsh_softkey_service_state_visible_e show)
+{
+ // Do something
+ LOG_E("visible change callback: %d", show);
+ if (show)
+ tzsh_softkey_service_show(service);
+ else
+ tzsh_softkey_service_hide(service);
+}
+
+static void
+softkey_service_expand_change_cb(void *data, tzsh_softkey_service_h service, tzsh_softkey_service_state_expand_e expand)
+{
+ // Do something
+ LOG_E("expand change callback: %d", expand);
+}
+
+static void
+softkey_service_opacity_change_cb(void *data, tzsh_softkey_service_h service, tzsh_softkey_service_state_opacity_e opacity)
+{
+ // Do something
+ LOG_E("opacity change callback: %d", opacity);
+}
+
+
+static tzsh_softkey_service_h create_tzsh_softkey_service(Evas_Object *win, window_layout_data *win_data)
+{
+ if(win == NULL && win_data == NULL)
+ {
+ LOG_E("Window: %p or win_data: %p may be null", win, win_data);
+ return NULL;
+ }
+ win_data->service_tzsh_window = elm_win_window_id_get(win);
+ if(win_data->service_tzsh_window == 0)
+ {
+ LOG_E("failed to get window id from window");
+ return NULL;
+ }
+
+ win_data->service_ws_shell = tzsh_create(TZSH_TOOLKIT_TYPE_EFL);
+ if(win_data->service_ws_shell == NULL)
+ {
+ LOG_E("failed to create tizen shell for softkey service");
+ win_data->service_tzsh_window = 0;
+ return NULL;
+ }
+
+ tzsh_softkey_service_h service = tzsh_softkey_service_create(win_data->service_ws_shell, win_data->service_tzsh_window);
+ if(service == NULL)
+ {
+ LOG_E("Failed to create softkey service");
+ tzsh_destroy(win_data->service_ws_shell);
+ win_data->service_ws_shell = NULL;
+ win_data->service_tzsh_window = 0;
+ return NULL;
+ }
+
+ tzsh_softkey_service_show(service);
+
+ //adding sofkey service callback
+ tzsh_softkey_service_visible_request_cb_set(service, softkey_service_visible_change_cb, win_data);
+ tzsh_softkey_service_expand_request_cb_set(service, softkey_service_expand_change_cb, win_data);
+ tzsh_softkey_service_opacity_request_cb_set(service, softkey_service_opacity_change_cb, win_data);
+
+ return service;
+}
Evas_Object* create_winodw_layout(softkey_container_mode mode)
{
free(win_data);
return NULL;
}
+ win_data->softkey_service = create_tzsh_softkey_service(win, win_data);
+ if(win_data->softkey_service == NULL)
+ {
+ LOG_E("Failed to create tzsh softkey service for softkey-container");
+ //return;
+ }
Evas_Object *root_grid = create_root_layout(win, mode);
return win;
}
-
-
void softkey_window_visible_state_changed(Evas_Object *win, softkey_container_visible_state state, void *data)
{
window_layout_data *win_data = evas_object_data_get(win, WINDOW_LAYOUT_DATA);
return;
}
- //setting visible state data in window layout data
+ // setting visible state data in window layout data
// we need to reset this data after animation end.
// because visible state data will be invalid after animation end.
win_data->animation_data = data;
{
window_layout_bg_image_visible_set(win_data->normal_bg, EINA_TRUE);
}
- softkey_container_transalation_effect(win_data->root_grid, window_translation_animation_end, win_data);
+ softkey_container_transalation_effect(win_data->window, window_translation_animation_end, win_data);
}
Evas_Object* window_layout_root_grid_object_get(Evas_Object *win)
Evas_Object *home_key;
Evas_Object *back_key;
Ecore_Timer *autohide_timer;
+ Ecore_Idler *state_idler;
softkey_visible_state_anim_data anim_data;
softkey_container_mode current_mode;
softkey_container_visible_state current_visible_state;
static Eina_Bool auto_hide_timer_callback(void *data)
{
+ LOG_E("");
appdata_s *ad = data;
softkey_visible_state_change();
ad->autohide_timer = NULL;
return g_appdata.current_visible_state;
}
+void softkey_container_geometry_update(Eina_Bool post_animation)
+{
+ LOG_E("");
+ if(softkey_container_current_mode_get() == SOFTKEY_MODE_NORMAL)
+ {
+ LOG_E("post_animation: %d", post_animation);
+ softkey_window_geometry_update(g_appdata.win, post_animation);
+ softkey_activate_bar_geometry_update(g_appdata.activate_bar, post_animation);
+ }
+}
+
void softkey_container_current_visible_state_set( softkey_container_visible_state state)
{
g_appdata.current_visible_state = state;
ecore_timer_del(g_appdata.autohide_timer);
g_appdata.autohide_timer = NULL;
}
+ // This is required to resize/reposition the window to size of activate bar so that it doesn't
+ // block the event for the window behind it.
+ softkey_container_geometry_update(EINA_TRUE);
}
}
}
}
}
+static Eina_Bool softkey_visible_state_idler_cb(void *data)
+{
+ int state = (intptr_t)data;
+ LOG_I("Current Visible state: %d", state);
+
+ softkey_container_current_visible_state_set(state);
+
+ g_appdata.anim_data.visible_state = state;
+ g_appdata.anim_data.anim_complete_count = 0;
+ g_appdata.anim_data.isAnimating = EINA_FALSE;
+
+ g_appdata.state_idler = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
Eina_Bool softkey_visible_state_animation_end(void *data)
{
//After all the animation completed than only update visible state.
if(anim_data->anim_complete_count == ALL_ANIMATION_COMPLETED)
{
+ int state = anim_data->visible_state;
if(anim_data->visible_state == SOFTKEY_STATE_VISIBLE_MINIMIZED)
{
- softkey_container_current_visible_state_set(SOFTKEY_STATE_VISIBLE_FULL);
- anim_data->visible_state = SOFTKEY_STATE_VISIBLE_FULL;
+ state = SOFTKEY_STATE_VISIBLE_FULL;
}
else if(anim_data->visible_state == SOFTKEY_STATE_VISIBLE_FULL)
{
- softkey_container_current_visible_state_set(SOFTKEY_STATE_VISIBLE_MINIMIZED);
- anim_data->visible_state = SOFTKEY_STATE_VISIBLE_MINIMIZED;
+ state = SOFTKEY_STATE_VISIBLE_MINIMIZED;
}
- anim_data->anim_complete_count = 0;
- anim_data->isAnimating = EINA_FALSE;
+ //Delete the old idler before create new one.
+ if(g_appdata.state_idler)
+ {
+ ecore_idler_del(g_appdata.state_idler);
+ g_appdata.state_idler = NULL;
+ }
+ // Idler is used here because we want to finish the animation completely before chaning state.
+ g_appdata.state_idler = ecore_idler_add(softkey_visible_state_idler_cb, (void*)(intptr_t)state);
return EINA_TRUE;
}
return EINA_FALSE;
void softkey_visible_state_change()
{
+ LOG_E("");
appdata_s *ad = softkey_container_appdata_get();
if(ad->anim_data.isAnimating)
{
ad->anim_data.visible_state = ad->current_visible_state;
ad->anim_data.isAnimating = EINA_TRUE;
+ if(ad->current_visible_state == SOFTKEY_STATE_VISIBLE_MINIMIZED)
+ {
+ // This is required to resize and reposition window to actual size before animation start
+ // This reset the operation done in softkey_container_current_visible_state_set for softkey state SOFTKEY_STATE_VISIBLE_MINIMIZED.
+ softkey_container_geometry_update(EINA_FALSE);
+ }
softkey_window_visible_state_changed(ad->win, ad->current_visible_state, &(ad->anim_data));
softkey_activate_bar_visible_state_change(ad->activate_bar, ad->current_visible_state, &(ad->anim_data));
}
ad->back_key = create_back_key(root_grid, ad->current_mode, back_key_state);
ad->activate_bar = create_activate_bar(ad->win, ad->current_mode);
-
}
static bool