raster pushed a commit to branch master.

http://git.enlightenment.org/core/elementary.git/commit/?id=f99be3a1d6bdc63153598b592b5437c33da44bf0

commit f99be3a1d6bdc63153598b592b5437c33da44bf0
Author: Jyotiprakash Sahoo <[email protected]>
Date:   Tue Dec 16 16:56:34 2014 +0900

    genlist: added reorder feature on key events
    
    Summary: This feature allows user to reorder items using up/down keys.
    
    Test Plan: elementary_test -to "Genlist Reorder Mode"
    
    Reviewers: singh.amitesh, raster, seoz, SanghyeonLee
    
    Differential Revision: https://phab.enlightenment.org/D1262
    
    Conflicts:
        src/bin/test_genlist.c
        src/lib/elm_genlist_legacy.h
---
 src/bin/test_genlist.c       | 141 ++++++++++++++++++++++++++++++++++++++++-
 src/lib/elm_genlist.c        | 145 ++++++++++++++++++++++++++++++++++++++++++-
 src/lib/elm_genlist.h        |   7 ++-
 src/lib/elm_genlist_legacy.h |  30 ++++++++-
 src/lib/elm_widget_genlist.h |   9 +++
 5 files changed, 326 insertions(+), 6 deletions(-)

diff --git a/src/bin/test_genlist.c b/src/bin/test_genlist.c
index 448e417..6c9ddb8 100644
--- a/src/bin/test_genlist.c
+++ b/src/bin/test_genlist.c
@@ -5,6 +5,8 @@
 #endif
 #include <Elementary.h>
 
+static int tween_mode_val;
+
 Evas_Object * _elm_min_set(Evas_Object *obj, Evas_Object *parent,
                            Evas_Coord w, Evas_Coord h);
 
@@ -2087,6 +2089,44 @@ _reorder_tg_changed_cb(void *data, Evas_Object *obj, 
void *event_info EINA_UNUSE
    elm_genlist_reorder_mode_set(data, elm_check_state_get(obj));
 }
 
+static void
+_focus_highlight_ck_changed_cb(void *data, Evas_Object *obj, void *event_info 
EINA_UNUSED)
+{
+   elm_win_focus_highlight_enabled_set(data, elm_check_state_get(obj));
+}
+
+static void
+_tween_mode_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+{
+   switch (tween_mode_val)
+     {
+        case 1:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_LINEAR);
+           break;
+        case 2:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_ACCELERATE);
+           break;
+        case 3:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_DECELERATE);
+           break;
+        case 4:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_SINUSOIDAL);
+           break;
+        case 5:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_DIVISOR_INTERP);
+           break;
+        case 6:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_BOUNCE);
+           break;
+        case 7:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_SPRING);
+           break;
+        default:
+           elm_genlist_reorder_mode_start(data, ECORE_POS_MAP_LINEAR);
+           break;
+     }
+}
+
 /**
  * gl_moved is called after an item was reordered.
  * This is only called when reorder mode is enabled.
@@ -2144,11 +2184,12 @@ static void gl_moved_before(Evas_Object *data 
EINA_UNUSED, Evas_Object *obj EINA
 void
 test_genlist11(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
 {
-   Evas_Object *win, *fr, *lb, *bx, *tg, *gl;
+   Evas_Object *win, *fr, *lb, *bx, *tg, *gl, *hbx, *ck, *grp, *rd;
    int i;
 
    api_data *api = calloc(1, sizeof(api_data));
    win = elm_win_util_standard_add("genlist-reorder-mode", "Genlist Reorder 
Mode");
+   elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
    elm_win_autodel_set(win, EINA_TRUE);
    evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _cleanup_cb, api);
 
@@ -2176,20 +2217,116 @@ test_genlist11(void *data EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, void *event
    api->gl = gl;
    evas_object_show(gl);
 
+   hbx = elm_box_add(win);
+   elm_box_horizontal_set(hbx, EINA_TRUE);
+   evas_object_size_hint_weight_set(hbx, EVAS_HINT_EXPAND, 0);
+   elm_box_padding_set(hbx, 20, 0);
+   elm_box_pack_end(bx, hbx);
+   evas_object_show(hbx);
+
    tg = elm_check_add(win);
    elm_object_style_set(tg, "toggle");
    elm_object_text_set(tg, "Reorder Mode:");
    elm_check_state_set(tg, elm_config_mirrored_get());
    evas_object_smart_callback_add(tg, "changed", _reorder_tg_changed_cb, gl);
-   elm_box_pack_end(bx, tg);
+   elm_box_pack_end(hbx, tg);
    evas_object_show(tg);
 
+   ck = elm_check_add(win);
+   elm_object_text_set(ck, "Focus Highlight");
+   elm_check_state_set(ck, elm_win_focus_highlight_enabled_get(win));
+   evas_object_smart_callback_add(ck, "changed", 
_focus_highlight_ck_changed_cb, win);
+   elm_box_pack_end(hbx, ck);
+   evas_object_show(ck);
+
+   lb = elm_label_add(win);
+   elm_object_text_set(lb, "Select reorder tween mode:");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   hbx = elm_box_add(win);
+   elm_box_horizontal_set(hbx, EINA_TRUE);
+   evas_object_size_hint_weight_set(hbx, EVAS_HINT_EXPAND, 0);
+   elm_box_pack_end(bx, hbx);
+   evas_object_show(hbx);
+
+   grp = rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Linear");
+   elm_radio_state_value_set(rd, 1);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Accelerate");
+   elm_radio_state_value_set(rd, 2);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   elm_radio_group_add(rd, grp);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Decelerate");
+   elm_radio_state_value_set(rd, 3);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   elm_radio_group_add(rd, grp);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Sinusoidal");
+   elm_radio_state_value_set(rd, 4);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   elm_radio_group_add(rd, grp);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   hbx = elm_box_add(win);
+   elm_box_horizontal_set(hbx, EINA_TRUE);
+   evas_object_size_hint_weight_set(hbx, EVAS_HINT_EXPAND, 0);
+   elm_box_pack_end(bx, hbx);
+   evas_object_show(hbx);
+
+   rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Divisor Interpolation");
+   elm_radio_state_value_set(rd, 5);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   elm_radio_group_add(rd, grp);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Bounce");
+   elm_radio_state_value_set(rd, 6);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   elm_radio_group_add(rd, grp);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   rd = elm_radio_add(win);
+   elm_object_text_set(rd, "Spring");
+   elm_radio_state_value_set(rd, 7);
+   elm_radio_value_pointer_set(rd, &tween_mode_val);
+   elm_radio_group_add(rd, grp);
+   evas_object_smart_callback_add(rd, "changed", _tween_mode_changed_cb, gl);
+   elm_box_pack_end(hbx, rd);
+   evas_object_show(rd);
+
+   elm_radio_value_set(grp, 1);
+
    api->itc1 = elm_genlist_item_class_new();
    api->itc1->item_style = "default";
    api->itc1->func.text_get = gl_text_get;
    api->itc1->func.content_get = gl_content_get;
    api->itc1->func.state_get = gl_state_get;
    api->itc1->func.del = NULL;
+
    evas_object_smart_callback_add(gl, "moved", (Evas_Smart_Cb)gl_moved, gl);
    evas_object_smart_callback_add(gl, "moved,after", 
(Evas_Smart_Cb)gl_moved_after, gl);
    evas_object_smart_callback_add(gl, "moved,before", 
(Evas_Smart_Cb)gl_moved_before, gl);
diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
index 1d858e8..8656e22 100644
--- a/src/lib/elm_genlist.c
+++ b/src/lib/elm_genlist.c
@@ -89,7 +89,9 @@
     cmd(SIG_ITEM_FOCUSED, "item,focused", "") \
     cmd(SIG_ITEM_UNFOCUSED, "item,unfocused", "") \
     cmd(SIG_PRESSED, "pressed", "") \
-    cmd(SIG_RELEASED, "released", "")
+    cmd(SIG_RELEASED, "released", "") \
+    cmd(SIG_ITEM_REORDER_START, "item,reorder,anim,start", "") \
+    cmd(SIG_ITEM_REORDER_STOP, "item,reorder,anim,stop", "")
 
 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
 
@@ -109,7 +111,11 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] 
= {
 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
 static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
-
+static void _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after);
+static void _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before);
+EOLIAN static void _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED,
+                                                 Elm_Genlist_Data *sd,
+                                                 Eina_Bool reorder_mode);
 
 static const Elm_Action key_actions[] = {
    {"move", _key_action_move},
@@ -2716,6 +2722,98 @@ _key_action_move_dir(Evas_Object *obj, 
Elm_Focus_Direction dir, Eina_Bool multi)
    return EINA_FALSE;
 }
 
+static void
+_anim_end(Elm_Genlist_Data *sd)
+{
+   if (sd->reorder.dir == ELM_FOCUS_UP)
+     _item_move_after(sd->reorder.it2, sd->reorder.it1);
+   else if (sd->reorder.dir == ELM_FOCUS_DOWN)
+     _item_move_after(sd->reorder.it1, sd->reorder.it2);
+
+   ecore_job_del(sd->calc_job);
+   sd->calc_job = ecore_job_add(_calc_job, sd->obj);
+}
+
+static Eina_Bool
+_item_swap_cb(void *data, double pos)
+{
+   Elm_Genlist_Data *sd = data;
+   double frame = pos;
+   Evas_Coord xx1, yy1, xx2, yy2;
+   double dx, dy;
+
+   switch (sd->reorder.tween_mode)
+     {
+        case ECORE_POS_MAP_LINEAR:
+           frame = ecore_animator_pos_map(frame, sd->reorder.tween_mode, 0, 0);
+           break;
+        case ECORE_POS_MAP_ACCELERATE:
+        case ECORE_POS_MAP_DECELERATE:
+        case ECORE_POS_MAP_SINUSOIDAL:
+           frame = ecore_animator_pos_map(frame, sd->reorder.tween_mode, 1.0, 
0);
+           break;
+        case ECORE_POS_MAP_DIVISOR_INTERP:
+        case ECORE_POS_MAP_BOUNCE:
+        case ECORE_POS_MAP_SPRING:
+           frame = ecore_animator_pos_map(frame, sd->reorder.tween_mode, 1.0, 
1.0);
+           break;
+        default:
+           // use ECORE_POS_MAP_LINEAR as default tween mode
+           frame = ecore_animator_pos_map(frame, sd->reorder.tween_mode, 0, 0);
+           break;
+     }
+
+   dx = sd->reorder.x2 - sd->reorder.x1;
+   dy = sd->reorder.y2 - sd->reorder.y1;
+
+   xx1 = sd->reorder.x1 + (dx * frame);
+   yy1 = sd->reorder.y1 + (dy * frame);
+   xx2 = sd->reorder.x2 - (dx * frame);
+   yy2 = sd->reorder.y2 - (dy * frame);
+
+   evas_object_move(VIEW(sd->reorder.it2), xx2, yy2);
+   evas_object_move(VIEW(sd->reorder.it1), xx1, yy1);
+
+   if (pos == 1.0)
+     {
+        elm_genlist_item_bring_in((Elm_Object_Item *)sd->reorder.it2, 
ELM_GENLIST_ITEM_SCROLLTO_IN);
+        _anim_end(sd);
+        evas_object_smart_callback_call(sd->obj, SIG_ITEM_REORDER_STOP, 
sd->reorder.it1);
+        sd->reorder.running = EINA_FALSE;
+     }
+
+   _elm_widget_focus_highlight_start(sd->obj);
+
+   return EINA_TRUE;
+}
+
+
+static void
+_swap_items(Elm_Gen_Item *it1, Elm_Gen_Item *it2, Elm_Focus_Direction dir)
+{
+   ELM_GENLIST_DATA_GET_FROM_ITEM(it1, sd);
+   Evas_Coord xx1, yy1, xx2, yy2;
+
+   if (!it1 || !it2) return;
+
+   sd->reorder.running = EINA_TRUE;
+   sd->reorder.dir = dir;
+   sd->reorder.it1 = it1;
+   sd->reorder.it2 = it2;
+
+   evas_object_geometry_get(VIEW(it1), &xx1, &yy1, NULL, NULL);
+   evas_object_geometry_get(VIEW(it2), &xx2, &yy2, NULL, NULL);
+   sd->reorder.x1 = xx1;
+   sd->reorder.y1 = yy1;
+   sd->reorder.x2 = xx2;
+   sd->reorder.y2 = yy2;
+
+   evas_object_raise(VIEW(it1));
+   evas_object_smart_callback_call(sd->obj, SIG_ITEM_REORDER_START, 
sd->reorder.it1);
+   //TODO: Add elm config for time
+   ecore_animator_timeline_add(0.3, _item_swap_cb, sd);
+}
+
 static Eina_Bool
 _key_action_move(Evas_Object *obj, const char *params)
 {
@@ -2762,6 +2860,18 @@ _key_action_move(Evas_Object *obj, const char *params)
      }
    else if (!strcmp(dir, "up"))
      {
+        if (sd->reorder.running) return EINA_TRUE;
+        if (sd->reorder_mode)
+          {
+             Elm_Gen_Item *up = (Elm_Gen_Item 
*)elm_genlist_item_prev_get(sd->focused_item);
+             ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focused_it);
+             ELM_GENLIST_ITEM_DATA_GET(up, up2);
+
+             _swap_items(focused_it, up2, ELM_FOCUS_UP);
+
+             return EINA_TRUE;
+          }
+
         if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return 
EINA_TRUE;
         else return EINA_FALSE;
      }
@@ -2773,6 +2883,18 @@ _key_action_move(Evas_Object *obj, const char *params)
      }
    else if (!strcmp(dir, "down"))
      {
+        if (sd->reorder.running) return EINA_TRUE;
+        if (sd->reorder_mode)
+          {
+             Elm_Gen_Item *down = (Elm_Gen_Item 
*)elm_genlist_item_next_get(sd->focused_item);
+             ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focused_it);
+             ELM_GENLIST_ITEM_DATA_GET(down, down2);
+
+             _swap_items(focused_it, down2, ELM_FOCUS_DOWN);
+
+             return EINA_TRUE;
+          }
+
         if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return 
EINA_TRUE;
         else return EINA_FALSE;
      }
@@ -7342,6 +7464,25 @@ _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data 
*sd, Eina_Bool decorate
    sd->calc_job = ecore_job_add(_calc_job, sd->obj);
 }
 
+EAPI void
+elm_genlist_reorder_mode_start(Evas_Object *obj, Ecore_Pos_Map tween_mode)
+{
+   ELM_GENLIST_CHECK(obj);
+   ELM_GENLIST_DATA_GET(obj, sd);
+
+   sd->reorder.tween_mode = tween_mode;
+   _elm_genlist_reorder_mode_set(obj, sd, EINA_TRUE);
+}
+
+EAPI void
+elm_genlist_reorder_mode_stop(Evas_Object *obj)
+{
+   ELM_GENLIST_CHECK(obj);
+   ELM_GENLIST_DATA_GET(obj, sd);
+
+   _elm_genlist_reorder_mode_set(obj, sd, EINA_FALSE);
+}
+
 EOLIAN static void
 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, 
Eina_Bool reorder_mode)
 {
diff --git a/src/lib/elm_genlist.h b/src/lib/elm_genlist.h
index c95d472..af6f06f 100644
--- a/src/lib/elm_genlist.h
+++ b/src/lib/elm_genlist.h
@@ -379,7 +379,12 @@
  * - @c "unfocused" - When the genlist has lost focus. (since 1.8)
  * - @c "item,focused" - When the genlist item has recieved focus. (since 1.10)
  * - @c "item,unfocused" - When the genlist item has lost focus. (since 1.10)
- *
+ * - @c "item,reorder,anim,start" - This is called when a genglist item's 
movement
+     has just started by keys in reorder mode. The %c event_info parameter
+ *   is the item that is going to move. (since 1.13)
+ * - @c "item,reorder,anim,stop" - This is called when a genlist item's 
movement just
+     stopped in reorder mode. The %c event_info parameter is the item
+     that was moved. (since 1.13)
  *
  * Supported elm_object_item common APIs
  * @li @ref elm_object_item_part_content_get
diff --git a/src/lib/elm_genlist_legacy.h b/src/lib/elm_genlist_legacy.h
index 77866c0..f8345ed 100644
--- a/src/lib/elm_genlist_legacy.h
+++ b/src/lib/elm_genlist_legacy.h
@@ -31,5 +31,33 @@ EAPI Evas_Object                  
*elm_genlist_add(Evas_Object *parent);
 EAPI Elm_Object_Item *
 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth);
 
-#include "elm_genlist_item.eo.legacy.h"
+/**
+ * Enable item reorder mode with keys for genlist widget
+ *
+ * @param obj The genlist object
+ * @param tween_mode Position mappings for animation
+ * @see _Ecore_Pos_Map
+ *
+ * @see elm_genlist_reorder_mode_stop()
+ * @since 1.13
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_reorder_mode_start(Evas_Object *obj, Ecore_Pos_Map tween_mode);
+
+/**
+ * Stop item reorder mode with keys for genlist widget
+ *
+ * @param obj The genlist object
+ *
+ * @see elm_genlist_reorder_mode_start()
+ * @since 1.13
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_reorder_mode_stop(Evas_Object *obj);
+
 #include "elm_genlist.eo.legacy.h"
+#include "elm_genlist_item.eo.legacy.h"
diff --git a/src/lib/elm_widget_genlist.h b/src/lib/elm_widget_genlist.h
index 623ae65..3cdeb0b 100644
--- a/src/lib/elm_widget_genlist.h
+++ b/src/lib/elm_widget_genlist.h
@@ -140,6 +140,15 @@ struct _Elm_Genlist_Data
    Elm_Genlist_Item_Move_Effect_Mode     move_effect_mode;
    int                                   reorder_fast;
 
+   struct
+   {
+      Elm_Gen_Item                          *it1, *it2; /**< The items which 
are getting swapped */
+      Elm_Focus_Direction                   dir; /**< focus key direction */
+      Ecore_Pos_Map                         tween_mode; /**< Position mappings 
for animation */
+      Evas_Coord                            x1, y1, x2, y2; /**< Coordinates 
of it1 and it2 */
+      Eina_Bool                             running : 1; /**< animation is 
happening */
+   } reorder;
+
    Eina_Bool                             focus_on_selection_enabled : 1;
    Eina_Bool                             tree_effect_enabled : 1;
    Eina_Bool                             auto_scroll_enabled : 1;

-- 


Reply via email to