return ECORE_CALLBACK_CANCEL;
}
+static void
+_dnd_enter_cb(void *data, Evas_Object *obj)
+{
+ INF("enter obj: %s", evas_object_type_get(obj));
+}
+
+//FIXME: drop_cb is not called, leave_cb is called: this should be fixed in elm dnd
+static void
+_dnd_leave_cb(void *data, Evas_Object *obj)
+{
+
+ Eext_Rotary_Selector_Data *rsd = data;
+
+ rsd->drag_done = EINA_TRUE;
+ if (rsd->stand_timer)
+ {
+ ecore_timer_del(rsd->stand_timer);
+ rsd->stand_timer = NULL;
+ }
+ if (rsd->drop_item_index != _ROTARY_SELECTOR_PRESSED_ITEM_INDEX_INVALID &&
+ rsd->drop_item_index != rsd->drag_item_index)
+ {
+ //move item to new pos
+ Eext_Rotary_Selector_Item *item;
+
+ item = eina_list_nth(rsd->item_list, rsd->drag_item_index);
+ rsd->item_list = eina_list_remove(rsd->item_list, item);
+ //delete tmp_item
+ evas_object_del(item->base.obj);
+
+ item = eina_list_nth(rsd->item_list, rsd->drop_item_index);
+ rsd->item_list = eina_list_prepend_relative(rsd->item_list, rsd->drag_item, item);
+ evas_object_show(rsd->drag_item->base.obj);
+
+ _item_rearrange(rsd, rsd->selected_index);
+ _items_transformation_update(rsd);
+ _items_invalidate(rsd);
+
+ _item_update_animation_run(rsd);
+ }
+ else
+ {
+ //add back
+ if (rsd->drag_item)
+ {
+ Eext_Rotary_Selector_Item *tmp_item;
+
+ tmp_item = eina_list_nth(rsd->item_list, rsd->drag_item_index);
+ rsd->item_list = eina_list_prepend_relative(rsd->item_list, rsd->drag_item, tmp_item);
+ rsd->item_list = eina_list_remove(rsd->item_list, tmp_item);
+
+ evas_object_show(rsd->drag_item->base.obj);
+
+ _item_rearrange(rsd, rsd->selected_index);
+ _items_transformation_update(rsd);
+ _items_invalidate(rsd);
+ _item_update_animation_run(rsd);
+ //delete tmp_item
+ evas_object_del(tmp_item->base.obj);
+ }
+ else
+ {
+ ERR("drag item is NULL");
+ }
+ }
+}
+
+static Eina_Bool
+_page_move(void *data)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+
+ if (rsd->stand_dir == EEXT_ROTARY_SELECTOR_DIRECTION_CW)
+ {
+ _page_animation_run(rsd, EINA_FALSE);
+ _selector_update(rsd, EINA_TRUE, EINA_TRUE);
+ }
+ else
+ {
+ _page_animation_run(rsd, EINA_TRUE);
+ _selector_update(rsd, EINA_TRUE, EINA_TRUE);
+ }
+ rsd->stand_timer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_drag_item_move_animator_cb(void *data)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+ Eina_List *l;
+ Eext_Rotary_Selector_Item *item;
+ int i = 0;
+ double p = 0.0f, dt;
+ int idx1 = rsd->drag_item_index;
+ int idx2 = rsd->drop_item_index;
+ Eina_Bool reverse = EINA_FALSE;
+ int first_index = rsd->current_page * _ROTARY_SELECTOR_PAGE_ITEM_MAX;
+ int last_index = 0;
+ double v[4] = {_ROTARY_SELECTOR_CUBIC_BEZIER_P1_X, _ROTARY_SELECTOR_CUBIC_BEZIER_P1_Y,
+ _ROTARY_SELECTOR_CUBIC_BEZIER_P2_X, _ROTARY_SELECTOR_CUBIC_BEZIER_P2_Y};
+
+ if (rsd->drag_done) return ECORE_CALLBACK_CANCEL;
+
+ last_index = (rsd->current_page + 1) * _ROTARY_SELECTOR_PAGE_ITEM_MAX - 1;
+ if (idx1 > idx2)
+ {
+ int tmp = idx1;
+ idx1 = idx2;
+ idx2 = tmp;
+ reverse = EINA_TRUE;
+
+ if (idx2 > last_index)
+ {
+ idx2 = last_index;
+ item = eina_list_nth(rsd->item_list, last_index);
+ evas_object_hide(item->base.obj);
+ }
+ }
+ else
+ {
+ if (idx1 < first_index)
+ {
+ idx1 = first_index;
+ //tmp_drag_item was removed from the list, must subtract 1
+ item = eina_list_nth(rsd->item_list, first_index - 1);
+ evas_object_hide(item->base.obj);
+ }
+ }
+
+ if (rsd->item_move_started)
+ {
+ rsd->item_move_started = EINA_FALSE;
+ rsd->item_move_start_time = ecore_time_unix_get();
+ }
+ dt = ecore_time_unix_get() - rsd->item_move_start_time;
+ p = ecore_animator_pos_map_n(dt / _ROTARY_SELECTOR_DRAG_ANIMATION_DURATION,
+ ECORE_POS_MAP_CUBIC_BEZIER, 4, v);
+
+ if (p <= 1.0f)
+ {
+ EINA_LIST_FOREACH(rsd->item_list, l, item)
+ {
+ if (i >= idx1 && i < idx2)
+ {
+ Evas_Object *button;
+ Eext_Rotary_Selector_Item_Coords *coords = NULL;
+ const float endAngle[] = { 300.f, 330.f, 0.f, 30.f, 60.f, 90.f,
+ 120.f, 150.f, 180.f, 210.f, 240.f };
+ float from = endAngle[item->index % _ROTARY_SELECTOR_PAGE_ITEM_MAX];
+ float to = from - 30;
+ int new_a;
+
+ if (reverse)
+ to = from + 30;
+
+ button = item->base.obj;
+ coords = &item->coords;
+ _circle_path_interpolator(rsd, p, from, to, rsd->radius, rsd->radius,
+ &coords->x, &coords->y, EINA_FALSE);
+ new_a = p * 255;
+ evas_object_move(button, coords->x, coords->y);
+ evas_object_color_set(button, new_a, new_a, new_a, new_a);
+ evas_object_show(button);
+ }
+
+ i++;
+ }
+ }
+ if (p >= 1.0f)
+ {
+ Eext_Rotary_Selector_Item *pos_item;
+
+ evas_object_show(rsd->tmp_drag_item->base.obj);
+ pos_item = eina_list_nth(rsd->item_list, rsd->drop_item_index);
+ rsd->item_list = eina_list_prepend_relative(rsd->item_list, rsd->tmp_drag_item,
+ pos_item);
+ _item_rearrange(rsd, rsd->selected_index);
+ _items_transformation_update(rsd);
+ _items_invalidate(rsd);
+ rsd->drag_item_index = eina_list_data_idx(rsd->item_list, rsd->tmp_drag_item);
+
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_drag_item_move(void *data)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+
+ rsd->stand_timer = NULL;
+ rsd->tmp_drag_item = eina_list_nth(rsd->item_list, rsd->drag_item_index);
+ if (!rsd->tmp_drag_item)
+ return ECORE_CALLBACK_CANCEL;
+
+ evas_object_hide(rsd->tmp_drag_item->base.obj);
+ rsd->item_list = eina_list_remove(rsd->item_list, rsd->tmp_drag_item);
+ rsd->item_move_start_time = ecore_loop_time_get();
+ rsd->item_move_started = EINA_TRUE;
+ rsd->drag_item_move_animator = ecore_animator_add(_drag_item_move_animator_cb, rsd);
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_dnd_pos_cb(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+
+ const double center_x = _ROTARY_SELECTOR_SCREEN_WIDTH / 2.0f;
+ const double center_y = _ROTARY_SELECTOR_SCREEN_HEIGHT / 2.0f;
+
+ rsd->drop_item_index = _ROTARY_SELECTOR_PRESSED_ITEM_INDEX_INVALID;
+ int point = sqrt(pow(center_x - x, 2) + pow(center_y - y, 2));
+ if (point > _ROTARY_SELECTOR_SELECTOR_TOUCH_AREA_WIDTH / 2)
+ {
+ double angle = _mouse_event_angle_get(x, y);
+ if (angle < 20.f)
+ {
+ if (rsd->current_page > 0)
+ {
+ if (rsd->stand_timer == NULL)
+ {
+ rsd->stand_dir = EEXT_ROTARY_SELECTOR_DIRECTION_CW;
+ rsd->stand_timer = ecore_timer_add(rsd->longpress_timeout,
+ _page_move, rsd);
+ }
+ }
+ }
+ else if (angle > 340.f)
+ {
+ int max_page = rsd->item_count / _ROTARY_SELECTOR_PAGE_ITEM_MAX;
+ if ((rsd->current_page + 1) * _ROTARY_SELECTOR_PAGE_ITEM_MAX < rsd->item_count)
+ {
+ if (rsd->stand_timer == NULL)
+ {
+ rsd->stand_dir = EEXT_ROTARY_SELECTOR_DIRECTION_CCW;
+ rsd->stand_timer = ecore_timer_add(rsd->longpress_timeout,
+ _page_move, rsd);
+ }
+ }
+ }
+ else
+ {
+ int i = 0, new_index;
+ int first_index = rsd->current_page * _ROTARY_SELECTOR_PAGE_ITEM_MAX;
+ const float touchAreaAngle[] = {45.f, 75.f, 105.f, 135.f, 165.f, 195.f,
+ 225.f, 255.f, 285.f, 315.f, 340.f};
+
+ //cancel stand timer
+ if (rsd->stand_timer)
+ {
+ ecore_timer_del(rsd->stand_timer);
+ rsd->stand_timer = NULL;
+ }
+ for(i = 0; i < _ROTARY_SELECTOR_PAGE_ITEM_MAX; i++)
+ {
+ if(angle < touchAreaAngle[i]) break;
+ }
+ new_index = first_index + i;
+ rsd->drop_item_index = new_index;
+ if (new_index != rsd->drag_item_index)
+ {
+ rsd->stand_timer = ecore_timer_add(rsd->longpress_timeout,
+ _drag_item_move, rsd);
+ }
+ }
+ }
+ else
+ {
+ //cancel stand timer
+ if (rsd->stand_timer)
+ {
+ ecore_timer_del(rsd->stand_timer);
+ rsd->stand_timer = NULL;
+ }
+ }
+}
+
+static Eina_Bool
+_dnd_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
+{
+ return EINA_TRUE; //FIXME: fix elm dnd and move dnd_drop_leave_cb to here
+}
+
+static Evas_Object *
+_image_create_icon(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+ Eext_Rotary_Selector_Item *item, *tmp_item;
+ int start_idx;
+ const char *file, *group;
+ Evas_Object *clone_img = NULL;
+ Evas_Object *icon, *item_icon, *action_bg;
+
+ if (!rsd)
+ {
+ ERR("failed");
+ return NULL;
+ }
+ //FIXME: xoff, yoff does not work
+ if (xoff) *xoff = rsd->item_width / 2;
+ if (yoff) *yoff = rsd->item_height / 2;
+
+
+ tmp_item = _item_create(rsd);
+ if (!tmp_item)
+ return NULL;
+ evas_object_show(tmp_item->base.obj);
+
+ item = eina_list_nth(rsd->item_list, rsd->pressed_item_index);
+ rsd->drag_item = item;
+ tmp_item->index = item->index;
+ rsd->item_list = eina_list_prepend_relative(rsd->item_list, tmp_item, item);
+ rsd->item_list = eina_list_remove(rsd->item_list, item);
+
+ icon = elm_button_add(parent);
+ elm_object_style_set(icon, "rotary_selector_item");
+ evas_object_resize(icon, rsd->item_width, rsd->item_height);
+ evas_object_show(icon);
+
+ action_bg = elm_layout_add(icon);
+ elm_layout_theme_set(action_bg, "rotary_selector", "item", "bg_image");
+ evas_object_show(action_bg);
+ elm_object_part_content_set(icon, "item,bg_image", action_bg);
+
+ start_idx = rsd->current_page * _ROTARY_SELECTOR_PAGE_ITEM_MAX;
+ tmp_item->delete_enabled = EINA_FALSE;
+ if (item->delete_enabled)
+ {
+ if (item->index >= start_idx &&
+ item->index < start_idx + _ROTARY_SELECTOR_PAGE_ITEM_MAX / 2 )
+ {
+ elm_object_signal_emit(icon, "elm,selector,delete,left", "elm");
+ }
+ else
+ {
+ elm_object_signal_emit(icon, "elm,selector,delete,right", "elm");
+ }
+ }
+ else
+ {
+ elm_object_signal_emit(icon, "elm,selector,delete,hide", "elm");
+ }
+
+ item_icon = elm_object_part_content_get(item->base.obj, "item,icon");
+ elm_image_file_get(item_icon, &file, &group);
+
+ if (file || group)
+ {
+ clone_img = elm_image_add(icon);
+ elm_image_file_set(clone_img, file, group);
+ evas_object_show(clone_img);
+ }
+ else
+ {
+ ERR("Cannot get image file path. Item icon only supports elm image");
+ }
+ elm_object_part_content_set(icon, "item,icon", clone_img);
+
+ evas_object_hide(item->base.obj);
+
+ _item_rearrange(rsd, rsd->selected_index);
+ _items_transformation_update(rsd);
+ _items_invalidate(rsd);
+
+#if 0
+ //FIXME: the data of proxy image returns NULL.
+ Evas_Object *proxy;
+ void *img_data;
+ Evas_Object *new_icon;
+
+ proxy = evas_object_image_filled_add(evas_object_evas_get(item_icon));
+ evas_object_image_source_set(proxy, item_icon);
+ evas_object_resize(proxy, rsd->item_width, rsd->item_height);
+ evas_object_move(proxy, 200, 200);
+ evas_object_show(proxy);
+
+ img_data = evas_object_image_data_get(proxy, EINA_FALSE);
+ if (!img_data)
+ ERR("Cannot get image data of proxy");
+ else
+ ERR("Got image data from porxy");
+
+ new_icon = evas_object_image_filled_add(evas_object_evas_get(parent));
+ evas_object_image_data_set(new_icon, img_data);
+ evas_object_resize(new_icon, rsd->item_width, rsd->item_height);
+ evas_object_move(new_icon, 100, 100);
+ evas_object_show(new_icon);
+
+ return new_icon;
+#endif
+
+
+ ERR("done");
+ return icon;
+}
+
+static void
+_drag_accept_cb(void *data, Evas_Object *obj, Eina_Bool accept)
+{
+ //ERR("obj: %s; accept: %d", evas_object_type_get(obj), accept);
+}
+
+static void
+_drag_done_cb(void *data, Evas_Object *obj)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+ if (rsd->drag_done) return;
+ //there was no dnd pos, leave, done at drop side
+ //add back item
+ if (rsd->drag_item)
+ {
+ Eext_Rotary_Selector_Item *tmp_item;
+
+ tmp_item = eina_list_nth(rsd->item_list, rsd->drag_item_index);
+ rsd->item_list = eina_list_prepend_relative(rsd->item_list, rsd->drag_item, tmp_item);
+ rsd->item_list = eina_list_remove(rsd->item_list, tmp_item);
+
+ evas_object_show(rsd->drag_item->base.obj);
+
+ _item_rearrange(rsd, rsd->selected_index);
+ _items_transformation_update(rsd);
+ _items_invalidate(rsd);
+ _item_update_animation_run(rsd);
+ //delete tmp_item
+ evas_object_del(tmp_item->base.obj);
+ }
+ else
+ {
+ ERR("drag item is NULL");
+ }
+}
+
+static Eina_Bool
+_item_longpress_cb(void *data)
+{
+ Eext_Rotary_Selector_Data *rsd = data;
+
+ rsd->on_delete_icon = EINA_FALSE;
+ rsd->drag_done = EINA_FALSE;
+ elm_drag_start(rsd->rotary_selector, ELM_SEL_FORMAT_TARGETS, "1", ELM_XDND_ACTION_COPY,
+ _image_create_icon, rsd,
+ NULL, NULL,
+ _drag_accept_cb, rsd,
+ _drag_done_cb, rsd);
+
+ rsd->longpress_timer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
static void
_event_area_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
elm_object_signal_emit(it->base.obj,
"elm,action,button,delete,selected", "");
}
- }
+ rsd->drag_item_index = new_index;
+ if (rsd->longpress_timer)
+ {
+ ecore_timer_del(rsd->longpress_timer);
+ rsd->longpress_timer = NULL;
+ }
+ rsd->longpress_timer = ecore_timer_add(rsd->longpress_timeout,
+ _item_longpress_cb, rsd);
+ }
else
{
_item_touched_signal_send(rsd, rsd->pressed_item_index, EINA_TRUE, EINA_FALSE);
ecore_timer_del(rsd->longpress_timer);
rsd->longpress_timer = NULL;
}
+ if (rsd->stand_timer)
+ {
+ ecore_timer_del(rsd->stand_timer);
+ rsd->stand_timer = NULL;
+ }
if (rsd->item_del_timer)
{
ecore_timer_del(rsd->item_del_timer);
rsd->item_del_timer = NULL;
}
+ if (rsd->drag_item_move_animator)
+ {
+ ecore_animator_del(rsd->drag_item_move_animator);
+ rsd->drag_item_move_animator = NULL;
+ }
if (rsd->del_item_move_animator)
{
ecore_animator_del(rsd->del_item_move_animator);
_rotary_selector_mouse_up_cb, rsd);
rsd->longpress_timeout = elm_config_longpress_timeout_get();
- rsd->longpress_timeout = elm_config_longpress_timeout_get(); _event_area_callback_add(rsd);
+ elm_drop_target_add(rotary_selector, ELM_SEL_FORMAT_TEXT,
+ _dnd_enter_cb, rsd,
+ _dnd_leave_cb, rsd,
+ _dnd_pos_cb, rsd,
+ _dnd_drop_cb, rsd);
+
+ _event_area_callback_add(rsd);
// for accessibility
evas_object_smart_callback_add(rotary_selector, "atspi,screen,reader,changed", _rotary_selector_screen_reader_changed, rsd);