scroller in scroller.... works! well with scrollers for now (elm_scroller).
authorCarsten Haitzler <raster@rasterman.com>
Fri, 7 May 2010 13:21:45 +0000 (13:21 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Fri, 7 May 2010 13:21:45 +0000 (13:21 +0000)
need to fix up some other instances of use of elm_smart_scroller. it's a 1
liner.

SVN revision: 48667

src/bin/test.c
src/bin/test_scroller.c
src/lib/elm_genlist.c
src/lib/elm_priv.h
src/lib/elm_scroller.c
src/lib/elm_widget.c
src/lib/els_scroller.c
src/lib/els_scroller.h

index 2e34985..7f166b5 100644 (file)
@@ -51,6 +51,7 @@ void test_progressbar(void *data, Evas_Object *obj, void *event_info);
 void test_fileselector(void *data, Evas_Object *obj, void *event_info);
 void test_separator(void *data, Evas_Object *obj, void *event_info);
 void test_scroller(void *data, Evas_Object *obj, void *event_info);
+void test_scroller2(void *data, Evas_Object *obj, void *event_info);
 void test_spinner(void *data, Evas_Object *obj, void *event_info);
 void test_index(void *data, Evas_Object *obj, void *event_info);
 void test_photocam(void *data, Evas_Object *obj, void *event_info);
@@ -243,6 +244,7 @@ my_win_main(void)
    ADD_TEST("File Selector", test_fileselector);
    ADD_TEST("Separator", test_separator);
    ADD_TEST("Scroller", test_scroller);
+   ADD_TEST("Scroller 2", test_scroller2);
    ADD_TEST("Spinner", test_spinner);
    ADD_TEST("Index", test_index);
    ADD_TEST("Photocam", test_photocam);
index bcd47c1..210e90f 100644 (file)
@@ -126,4 +126,138 @@ test_scroller(void *data, Evas_Object *obj, void *event_info)
    evas_object_resize(win, 320, 320);
    evas_object_show(win);
 }
+
+void
+click_through(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("click went through on %p\n", obj);
+}
+
+void
+test_scroller2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bt, *bx, *bx2, *bg, *sc, *tb, *tb2, *rc;
+   int i, j;
+
+   win = elm_win_add(NULL, "scroller2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Scroller 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
+
+   /* { */
+   for (i = 0; i < 3; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Vertical");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+        elm_box_pack_end(bx, bt);
+        evas_object_show(bt);
+     }
+   /* } */
+   
+   /* { */
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(sc, EVAS_HINT_FILL, 0.5);
+   elm_scroller_bounce_set(sc, 1, 0);
+   elm_scroller_content_min_limit(sc, 0, 1);
+   elm_box_pack_end(bx, sc);
+   evas_object_show(sc);
+   
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+
+   for (i = 0; i < 10; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "... Horizontal scrolling ...");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        elm_box_pack_end(bx2, bt);
+        evas_object_show(bt);
+     }
+   
+   elm_scroller_content_set(sc, bx2);
+   evas_object_show(bx2);
+   /* } */
+
+   /* { */
+   for (i = 0; i < 3; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Vertical");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+        elm_box_pack_end(bx, bt);
+        evas_object_show(bt);
+     }
+   /* } */
+   
+   /* { */
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, tb);
+   evas_object_show(tb);
+   
+   rc = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_size_hint_min_set(rc, 200, 120);
+   elm_table_pack(tb, rc, 0, 0, 1, 1);
+   
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(sc, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, sc, 0, 0, 1, 1);
+   evas_object_show(sc);
+   
+   tb2 = elm_table_add(win);
+
+   for (j = 0; j < 16; j++)
+     {
+        for (i = 0; i < 16; i++)
+          {
+             bt = elm_button_add(win);
+             elm_button_label_set(bt, "Both");
+             evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+             elm_table_pack(tb2, bt, i, j, 1, 1);
+             evas_object_show(bt);
+          }
+     }
+   
+   elm_scroller_content_set(sc, tb2);
+   evas_object_show(tb2);
+   /* } */
+   
+   for (i = 0; i < 24; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Vertical");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+        elm_box_pack_end(bx, bt);
+        evas_object_show(bt);
+     }
+   
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_scroller_bounce_set(sc, 0, 1);
+   elm_win_resize_object_add(win, sc);
+   elm_scroller_content_set(sc, bx);
+   evas_object_show(bx);
+   evas_object_show(sc);
+   
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
 #endif
index 453fff1..9ed0afe 100644 (file)
@@ -412,6 +412,19 @@ _sizing_eval(Evas_Object *obj)
    evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
    minh = -1;
    if (wd->mode != ELM_LIST_LIMIT) minw = -1;
+   else
+     {
+        Evas_Coord  vmw, vmh, vw, vh;
+        
+        minw = wd->minw;
+        maxw = -1;
+        elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+        if ((minw > 0) && (vw < minw)) vw = minw;
+        else if ((maxw > 0) && (vw > maxw)) vw = maxw;
+        minw = -1;
+        edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
+        minw = vmw + minw;
+     }
    evas_object_size_hint_min_set(obj, minw, minh);
    evas_object_size_hint_max_set(obj, maxw, maxh);
 }
@@ -2876,10 +2889,7 @@ elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode)
    if (!wd) return;
    if (wd->mode == mode) return;
    wd->mode = mode;
-   if (wd->mode == ELM_LIST_LIMIT)
-     elm_scroller_content_min_limit(wd->scr, 1, 0);
-   else
-     elm_scroller_content_min_limit(wd->scr, 0, 0);
+   _sizing_eval(obj);
 }
 
 /**
index 7dcaa9f..024f75d 100644 (file)
@@ -148,7 +148,13 @@ EAPI void         elm_widget_style_set(Evas_Object *obj, const char *style);
 EAPI const char  *elm_widget_style_get(const Evas_Object *obj);
 EAPI void         elm_widget_type_set(Evas_Object *obj, const char *type);
 EAPI const char  *elm_widget_type_get(const Evas_Object *obj);
-
+EAPI void         elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock);
+EAPI void         elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock);
+EAPI Eina_Bool    elm_widget_drag_lock_x_get(Evas_Object *obj);
+EAPI Eina_Bool    elm_widget_drag_lock_y_get(Evas_Object *obj);
+EAPI int          elm_widget_drag_child_locked_x_get(Evas_Object *obj);
+EAPI int          elm_widget_drag_child_locked_y_get(Evas_Object *obj);
+    
 EAPI Eina_Bool    elm_widget_is(const Evas_Object *obj);
 EAPI Evas_Object *elm_widget_parent_widget_get(const Evas_Object *obj);
 
index 976350a..79d200d 100644 (file)
@@ -307,6 +307,7 @@ elm_scroller_add(Evas_Object *parent)
    wd->widget_base = eina_stringshare_add("base");
    
    wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
 //   elm_smart_scroller_theme_set(wd->scr, 
 //                                wd->widget_name, 
 //                                wd->widget_base,
index 4017620..bd7818b 100644 (file)
@@ -40,10 +40,16 @@ struct _Smart_Data
    int            scroll_freeze;
    double         scale;
    const char    *style;
-   unsigned char  can_focus : 1;
-   unsigned char  child_can_focus : 1;
-   unsigned char  focused : 1;
-   unsigned char  disabled : 1;
+   
+   int            child_drag_x_locked;
+   int            child_drag_y_locked;
+   Eina_Bool      drag_x_locked : 1;
+   Eina_Bool      drag_y_locked : 1;
+   
+   Eina_Bool      can_focus : 1;
+   Eina_Bool      child_can_focus : 1;
+   Eina_Bool      focused : 1;
+   Eina_Bool      disabled : 1;
 };
 
 /* local subsystem functions */
@@ -82,10 +88,12 @@ static void
 _sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
 {
    Evas_Object *o = obj;
-   do {
-      if (_elm_widget_is(o)) break;
-      o = evas_object_smart_parent_get(o);
-   } while (o);
+   do 
+     {
+        if (_elm_widget_is(o)) break;
+        o = evas_object_smart_parent_get(o);
+     }
+   while (o);
    if (!o) return;
    if (!elm_widget_can_focus_get(o)) return;
    elm_widget_focus_steal(o);
@@ -911,6 +919,104 @@ elm_widget_type_get(const Evas_Object *obj)
    return "";
 }
 
+
+
+
+
+
+
+
+
+static void
+_propagate_x_drag_lock(Evas_Object *obj, int dir)
+{
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   if (sd->parent_obj)
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
+        if (sd2)
+          {
+             sd2->child_drag_x_locked += dir;
+             _propagate_x_drag_lock(sd->parent_obj, dir);
+          }
+     }
+}
+
+static void
+_propagate_y_drag_lock(Evas_Object *obj, int dir)
+{
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   if (sd->parent_obj)
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
+        if (sd2)
+          {
+             sd2->child_drag_y_locked += dir;
+             _propagate_y_drag_lock(sd->parent_obj, dir);
+          }
+     }
+}
+
+EAPI void
+elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
+{
+   API_ENTRY return;
+   if (sd->drag_x_locked == lock) return;
+   sd->drag_x_locked = lock;
+   if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
+   else _propagate_x_drag_lock(obj, -1);
+}
+
+EAPI void
+elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock)
+{
+   API_ENTRY return;
+   if (sd->drag_y_locked == lock) return;
+   sd->drag_y_locked = lock;
+   if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
+   else _propagate_y_drag_lock(obj, -1);
+}
+
+EAPI Eina_Bool
+elm_widget_drag_lock_x_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   printf("check %p x lock %i\n", obj, sd->drag_x_locked);
+   return sd->drag_x_locked;
+}
+
+EAPI Eina_Bool
+elm_widget_drag_lock_y_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   printf("check %p y lock %i\n", obj, sd->drag_y_locked);
+   return sd->drag_y_locked;
+}
+
+EAPI int
+elm_widget_drag_child_locked_x_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->child_drag_x_locked;
+}
+
+EAPI int
+elm_widget_drag_child_locked_y_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->child_drag_y_locked;
+}
+
+
+
+
+
+
+
+
+
+
+
 /* local subsystem functions */
 static void
 _smart_reconfigure(Smart_Data *sd)
index a781c5e..f2f94d6 100644 (file)
@@ -19,6 +19,8 @@ struct _Smart_Data
    Evas_Object *edje_obj;
    Evas_Object *event_obj;
 
+   Evas_Object *widget;
+   
    Elm_Smart_Scroller_Policy hbar_flags, vbar_flags;
 
    struct {
@@ -46,10 +48,12 @@ struct _Smart_Data
       Ecore_Animator *bounce_y_animator;
       Evas_Coord locked_x, locked_y;
       unsigned char now : 1;
+      unsigned char want_dragged : 1;
       unsigned char dragged : 1;
+      unsigned char dragged_began : 1;
       unsigned char dir_x : 1;
       unsigned char dir_y : 1;
-      unsigned char dir_none : 1;
+//      unsigned char dir_none : 1;
       unsigned char locked : 1;
       unsigned char bounce_x_hold : 1;
       unsigned char bounce_y_hold : 1;
@@ -624,40 +628,48 @@ bounce_eval(Smart_Data *sd)
    if (py > my) py = my;
    b2x = px;
    b2y = py;
-   if (!sd->down.bounce_x_animator)
+   if ((!sd->widget) || 
+       (!elm_widget_drag_child_locked_x_get(sd->widget)))
      {
-        if (sd->bouncemex)
+        if (!sd->down.bounce_x_animator)
           {
-             if (sd->scrollto.x.animator)
+             if (sd->bouncemex)
                {
-                  ecore_animator_del(sd->scrollto.x.animator);
-                  sd->scrollto.x.animator = NULL;
+                  if (sd->scrollto.x.animator)
+                    {
+                       ecore_animator_del(sd->scrollto.x.animator);
+                       sd->scrollto.x.animator = NULL;
+                    }
+                  sd->down.bounce_x_animator = ecore_animator_add(_smart_bounce_x_animator, sd);
+                  sd->down.anim_start2 = ecore_loop_time_get();
+                  sd->down.bx = bx;
+                  sd->down.bx0 = bx;
+                  sd->down.b2x = b2x;
+                  if (sd->down.momentum_animator) sd->down.b0x = sd->down.ax;
+                  else sd->down.b0x = 0;
                }
-             sd->down.bounce_x_animator = ecore_animator_add(_smart_bounce_x_animator, sd);
-             sd->down.anim_start2 = ecore_loop_time_get();
-             sd->down.bx = bx;
-             sd->down.bx0 = bx;
-             sd->down.b2x = b2x;
-             if (sd->down.momentum_animator) sd->down.b0x = sd->down.ax;
-             else sd->down.b0x = 0;
           }
      }
-   if (!sd->down.bounce_y_animator)
+   if ((!sd->widget) || 
+       (!elm_widget_drag_child_locked_y_get(sd->widget)))
      {
-        if (sd->bouncemey)
+        if (!sd->down.bounce_y_animator)
           {
-             if (sd->scrollto.y.animator)
+             if (sd->bouncemey)
                {
-                  ecore_animator_del(sd->scrollto.y.animator);
-                  sd->scrollto.y.animator = NULL;
+                  if (sd->scrollto.y.animator)
+                    {
+                       ecore_animator_del(sd->scrollto.y.animator);
+                       sd->scrollto.y.animator = NULL;
+                    }
+                  sd->down.bounce_y_animator = ecore_animator_add(_smart_bounce_y_animator, sd);
+                  sd->down.anim_start3 = ecore_loop_time_get();
+                  sd->down.by = by;
+                  sd->down.by0 = by;
+                  sd->down.b2y = b2y;
+                  if (sd->down.momentum_animator) sd->down.b0y = sd->down.ay;
+                  else sd->down.b0y = 0;
                }
-             sd->down.bounce_y_animator = ecore_animator_add(_smart_bounce_y_animator, sd);
-             sd->down.anim_start3 = ecore_loop_time_get();
-             sd->down.by = by;
-             sd->down.by0 = by;
-             sd->down.b2y = b2y;
-             if (sd->down.momentum_animator) sd->down.b0y = sd->down.ay;
-             else sd->down.b0y = 0;
           }
      }
 }
@@ -1050,6 +1062,13 @@ elm_smart_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y,
    _smart_scrollto_y(sd, _elm_config->bring_in_scroll_friction, y);
 }
 
+void
+elm_smart_scroller_widget_set(Evas_Object *obj, Evas_Object *wid)
+{
+   API_ENTRY return;
+   sd->widget = wid;
+}
+
 /* local subsystem functions */
 static void
 _smart_edje_drag_v_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
@@ -1239,7 +1258,7 @@ _smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSE
 
    sd = data;
    ev = event_info;
-   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+//   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
    if (_elm_config->thumbscroll_enable)
      {
         if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
@@ -1291,7 +1310,7 @@ _smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSE
             sd->down.dragged = 0;
             sd->down.dir_x = 0;
             sd->down.dir_y = 0;
-            sd->down.dir_none = 0;
+//          sd->down.dir_none = 0;
             sd->down.x = ev->canvas.x;
             sd->down.y = ev->canvas.y;
             elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
@@ -1307,6 +1326,7 @@ _smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSE
             sd->down.history[0].x = ev->canvas.x;
             sd->down.history[0].y = ev->canvas.y;
          }
+        sd->down.dragged_began = 0;
      }
 }
 
@@ -1314,7 +1334,41 @@ static int
 _smart_hold_animator(void *data)
 {
    Smart_Data *sd = data;
-   elm_smart_scroller_child_pos_set(sd->smart_obj, sd->down.hold_x, sd->down.hold_y);
+   Evas_Coord ox, oy;
+   
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
+   if (sd->down.dir_x)
+     {
+        if ((!sd->widget) || 
+            (!elm_widget_drag_child_locked_x_get(sd->widget)))
+          {
+             ox = sd->down.hold_x;
+          }
+     }
+   if (sd->down.dir_y)
+     {
+        if ((!sd->widget) || 
+            (!elm_widget_drag_child_locked_y_get(sd->widget)))
+          {
+             oy = sd->down.hold_y;
+          }
+     }
+   elm_smart_scroller_child_pos_set(sd->smart_obj, ox, oy);
+   return 1;
+}
+
+static Eina_Bool
+_smart_event_post_up(void *data, Evas *e)
+{
+   Smart_Data *sd = data;
+   if (sd->widget)
+     {
+        if (sd->down.dragged)
+          {
+             elm_widget_drag_lock_x_set(sd->widget, 0);
+             elm_widget_drag_lock_y_set(sd->widget, 0);
+          }
+     }
    return 1;
 }
 
@@ -1327,7 +1381,8 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev
 
    sd = data;
    ev = event_info;
-   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+//   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+   evas_post_event_callback_push(e, _smart_event_post_up, sd);
    // FIXME: respect elm_widget_scroll_hold_get of parent container
    if (_elm_config->thumbscroll_enable)
      {
@@ -1419,10 +1474,18 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev
                        Evas_Coord pgx, pgy;
 
                        elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
-                       pgx = _smart_page_x_get(sd, ox);
-                       if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
-                       pgy = _smart_page_y_get(sd, oy);
-                       if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_x_get(sd->widget)))
+                         {
+                            pgx = _smart_page_x_get(sd, ox);
+                            if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+                         }
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_y_get(sd->widget)))
+                         {
+                            pgy = _smart_page_y_get(sd, oy);
+                            if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+                         }
                     }
               }
              else
@@ -1432,12 +1495,29 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev
                        Evas_Coord pgx, pgy;
 
                        elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
-                       pgx = _smart_page_x_get(sd, ox);
-                       if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
-                       pgy = _smart_page_y_get(sd, oy);
-                       if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_x_get(sd->widget)))
+                         {
+                            pgx = _smart_page_x_get(sd, ox);
+                            if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+                         }
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_y_get(sd->widget)))
+                         {
+                            pgy = _smart_page_y_get(sd, oy);
+                            if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+                         }
+                    }
+                  if (sd->down.hold_animator)
+                    {
+                       ecore_animator_del(sd->down.hold_animator);
+                       sd->down.hold_animator = NULL;
                     }
                }
+             sd->down.dragged_began = 0;
+             sd->down.dir_x = 0;
+             sd->down.dir_y = 0;
+             sd->down.want_dragged = 0;
             sd->down.dragged = 0;
             sd->down.now = 0;
              elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
@@ -1464,12 +1544,31 @@ _smart_onhold_animator(void *data)
         vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
         vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
         elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
-        sd->down.onhold_vxe += vx;
-        sd->down.onhold_vye += vy;
-        x = ox + (int)sd->down.onhold_vxe;
-        y = oy + (int)sd->down.onhold_vye;
-        sd->down.onhold_vxe -= (int)sd->down.onhold_vxe;
-        sd->down.onhold_vye -= (int)sd->down.onhold_vye;
+        x = ox;
+        y = oy;
+        
+        if (sd->down.dir_x)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_x_get(sd->widget)))
+               {
+                  sd->down.onhold_vxe += vx;
+                  x = ox + (int)sd->down.onhold_vxe;
+                  sd->down.onhold_vxe -= (int)sd->down.onhold_vxe;
+               }
+          }
+        
+        if (sd->down.dir_y)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_y_get(sd->widget)))
+               {
+                  sd->down.onhold_vye += vy;
+                  y = oy + (int)sd->down.onhold_vye;
+                  sd->down.onhold_vye -= (int)sd->down.onhold_vye;
+               }
+          }
+        
         elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
 //        printf("scroll %i %i\n", sd->down.hold_x, sd->down.hold_y);
      }
@@ -1477,6 +1576,51 @@ _smart_onhold_animator(void *data)
    return 1;
 }
 
+static Eina_Bool
+_smart_event_post_move(void *data, Evas *e)
+{
+   Smart_Data *sd = data;
+   if (sd->down.want_dragged)
+     {
+        int start = 0;
+        
+        if (sd->down.dir_x)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_x_get(sd->widget)))
+               {
+                  sd->down.want_dragged = 0;
+                  sd->down.dragged = 1;
+                  if (sd->widget)
+                    {
+                       elm_widget_drag_lock_x_set(sd->widget, 1);
+                    }
+                  start = 1;
+               }
+             else
+               sd->down.dir_x = 0;
+          }
+        if (sd->down.dir_y)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_y_get(sd->widget)))
+               {
+                  sd->down.want_dragged = 0;
+                  sd->down.dragged = 1;
+                  if (sd->widget)
+                    {
+                       elm_widget_drag_lock_y_set(sd->widget, 1);
+                    }
+                  start = 1;
+               }
+             else
+               sd->down.dir_y = 0;
+          }
+        if (start) _smart_drag_start(sd->smart_obj);
+     }
+   return 1;
+}
+
 static void
 _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
 {
@@ -1486,13 +1630,14 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
 
    sd = data;
    ev = event_info;
-   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+//   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+   evas_post_event_callback_push(e, _smart_event_post_move, sd);
    // FIXME: respect elm_widget_scroll_hold_get of parent container
    if (_elm_config->thumbscroll_enable)
      {
        if (sd->down.now)
          {
-             int faildir = 0;
+             int dodir = 0;
 
 #ifdef SCROLLDBG
              printf("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
@@ -1507,33 +1652,47 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
             sd->down.history[0].x = ev->cur.canvas.x;
             sd->down.history[0].y = ev->cur.canvas.y;
 
-            x = ev->cur.canvas.x - sd->down.x;
-            if (x < 0) x = -x;
-            y = ev->cur.canvas.y - sd->down.y;
-            if (y < 0) y = -y;
-            if ((sd->one_dir_at_a_time) &&
-                (!sd->down.dir_x) && (!sd->down.dir_y) && (!sd->down.dir_none))
-              {
-                  if (x > _elm_config->thumbscroll_threshhold)
+             if (!sd->down.dragged_began)
+               {
+                  x = ev->cur.canvas.x - sd->down.x;
+                  if (x < 0) x = -x;
+                  y = ev->cur.canvas.y - sd->down.y;
+                  if (y < 0) y = -y;
+                  if ((sd->one_dir_at_a_time) &&
+                      (!((sd->down.dir_x) || (sd->down.dir_y))))
+                    /* && (!sd->down.dir_none))*/
                     {
-                       if (x > (y * 2))
+                       if (x > _elm_config->thumbscroll_threshhold)
                          {
-                           sd->down.dir_x = 1;
-                           sd->down.dir_y = 0;
-                        }
-                       else faildir++;
-                   }
-                  if (y > _elm_config->thumbscroll_threshhold)
-                   {
-                       if (y > (x * 2))
-                        {
-                           sd->down.dir_x = 0;
-                           sd->down.dir_y = 1;
+                            if (x > (y * 2))
+                              {
+                                 sd->down.dir_x = 1;
+                                 sd->down.dir_y = 0;
+                                 dodir++;
+                              }
                          }
-                       else faildir++;
-                   }
-                  if (faildir) sd->down.dir_none = 1;
-              }
+                       if (y > _elm_config->thumbscroll_threshhold)
+                         {
+                            if (y > (x * 2))
+                              {
+                                 sd->down.dir_x = 0;
+                                 sd->down.dir_y = 1;
+                                 dodir++;
+                              }
+                         }
+                       if (!dodir)
+                         {
+                            //sd->down.dir_none = 1;
+                            sd->down.dir_x = 1;
+                            sd->down.dir_y = 1;
+                         }
+                    }
+                  else
+                    {
+                       sd->down.dir_x = 1;
+                       sd->down.dir_y = 1;
+                    }
+               }
              if ((!sd->hold) && (!sd->freeze))
                {
                   if ((sd->down.dragged) ||
@@ -1541,15 +1700,27 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
                        (_elm_config->thumbscroll_threshhold *
                         _elm_config->thumbscroll_threshhold)))
                     {
+                       sd->down.dragged_began = 1;
                        if (!sd->down.dragged)
                          {
-                            evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
-                            _smart_drag_start(sd->smart_obj);
+                            sd->down.want_dragged = 1;
+//                            evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
+//                            _smart_drag_start(sd->smart_obj);
                          }
-                       ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
-                       sd->down.dragged = 1;
-                       x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
-                       y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
+                       if (sd->down.dragged)
+                         {
+                            ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+                         }
+//                       ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+//                       sd->down.dragged = 1;
+                       if (sd->down.dir_x)
+                         x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
+                       else
+                         x = sd->down.sx;
+                       if (sd->down.dir_y)
+                         y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
+                       else
+                         y = sd->down.sy;
                        if ((sd->down.dir_x) || (sd->down.dir_y))
                          {
                             if (!sd->down.locked)
@@ -1558,15 +1729,17 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
                                  sd->down.locked_y = y;
                                  sd->down.locked = 1;
                               }
-                            if (sd->down.dir_x) y = sd->down.locked_y;
-                            else x = sd->down.locked_x;
+                            if (!((sd->down.dir_x) && (sd->down.dir_y)))
+                              {
+                                 if (sd->down.dir_x) y = sd->down.locked_y;
+                                 else x = sd->down.locked_x;
+                              }
                          }
                        sd->down.hold_x = x;
                        sd->down.hold_y = y;
                        if (!sd->down.hold_animator)
-                         {
-                            sd->down.hold_animator = ecore_animator_add(_smart_hold_animator, sd);
-                         }
+                         sd->down.hold_animator = 
+                         ecore_animator_add(_smart_hold_animator, sd);
 //                       printf("a %i %i\n", sd->down.hold_x, sd->down.hold_y);
 //                       _smart_onhold_animator(sd);
 //                       elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
index b343207..24b8fdf 100644 (file)
@@ -30,3 +30,4 @@ void elm_smart_scroller_bounce_allow_set        (Evas_Object *obj, Eina_Bool hor
 void elm_smart_scroller_bounce_allow_get        (const Evas_Object *obj, Eina_Bool *horiz, Eina_Bool *vert);
 void elm_smart_scroller_paging_set              (Evas_Object *obj, double pagerel_h, double pagerel_v, Evas_Coord pagesize_h, Evas_Coord pagesize_v);
 void elm_smart_scroller_region_bring_in         (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+void elm_smart_scroller_widget_set              (Evas_Object *obj, Evas_Object *wid);