Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/etk

Dir     : e17/libs/etk/src/lib


Modified Files:
        etk_scrolled_view.c etk_scrolled_view.h 


Log Message:


ticks finger scrolling stuff for etk.

===================================================================
RCS file: /cvs/e/e17/libs/etk/src/lib/etk_scrolled_view.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -3 -r1.33 -r1.34
--- etk_scrolled_view.c 28 Sep 2007 20:01:27 -0000      1.33
+++ etk_scrolled_view.c 10 Apr 2008 09:03:08 -0000      1.34
@@ -37,7 +37,15 @@
 static Etk_Bool _etk_scrolled_view_child_added_cb(Etk_Object *object, void 
*child, void *data);
 static Etk_Bool _etk_scrolled_view_child_removed_cb(Etk_Object *object, void 
*child, void *data);
 static Etk_Bool _etk_scrolled_view_child_scroll_size_changed_cb(Etk_Object 
*object, void *data);
+static int _etk_scrolled_view_motive_bounce(void *data); 
 
+
+static Etk_Bool _etk_scrolled_view_mouse_down(Etk_Object *object, 
Etk_Event_Mouse_Down *event, void *data); 
+static Etk_Bool _etk_scrolled_view_mouse_up(Etk_Object *object, 
Etk_Event_Mouse_Up *event, void *data);
+static Etk_Bool _etk_scrolled_view_mouse_click(Etk_Object *object, 
Etk_Event_Mouse_Up *event, void *data);
+static Etk_Bool _etk_scrolled_view_mouse_move(Etk_Object *object, 
Etk_Event_Mouse_Move *event, void *data); 
+
+static Etk_Bool _etk_scrolled_view_bar_mouse_down(Etk_Object *object, 
Etk_Event_Mouse_Down *event, void *data); 
 /**************************
  *
  * Implementation
@@ -173,6 +181,106 @@
       *vpolicy = scrolled_view ? scrolled_view->vpolicy : ETK_POLICY_AUTO;
 }
 
+/**
+ * @brief Set the scrolled view dragable or not
+ * @param scrolled_view a scrolled view
+ * @param dragable The scrolled view is dragable or not?
+ */ 
+void etk_scrolled_view_dragable_set(Etk_Scrolled_View *scrolled_view, Etk_Bool 
dragable) 
+{
+   if (!scrolled_view)
+      return;
+   scrolled_view->drag.dragable = dragable;
+}
+
+/**
+ * @brief Get the scrolled view dragable flag
+ * @param scrolled_view a scrolled view
+ * @return Returns ETK_TURE if the scrolled view is dragable
+ */
+Etk_Bool etk_scrolled_view_dragable_get(Etk_Scrolled_View *scrolled_view) 
+{
+   if (!scrolled_view)
+      return ETK_FALSE;
+   return scrolled_view->drag.dragable;
+}
+
+/**
+ * @brief Set the scrolled view boucy or not.
+ * @param scrolled_view  a scrolled view
+ * @param bouncy The scrolled view is bouncy or not (Default TRUE)
+ */ 
+void etk_scrolled_view_drag_bouncy_set(Etk_Scrolled_View *scrolled_view, 
Etk_Bool bouncy) 
+{
+   if (!scrolled_view)
+      return;
+   scrolled_view->drag.bouncy = bouncy;
+}
+
+/**
+ * @brief  Get the scrolled view bouncy flag
+ * @param scrolled_view  a scrolled view
+ * @return Returns ETK_TURE if the scrolled view is bouncy
+ */ 
+Etk_Bool etk_scrolled_view_drag_bouncy_get(Etk_Scrolled_View *scrolled_view) 
+{
+   if (!scrolled_view)
+      return ETK_FALSE;
+   return scrolled_view->drag.bouncy;
+}
+
+/**
+ * @brief Set the scrolled view sample interval to calculate the scrolling 
speed.
+ * @param scrolled_view a scrolled view
+ * @param interval The interval of sampling latest scrolling speed (minimial 
0.2 second, default 0.5 second)
+ * @return Returns the actual sampling interval set. If scrolled_view is NULL 
returns 0.0f. 
+ */
+double etk_scrolled_view_drag_sample_interval_magic_set(Etk_Scrolled_View 
*scrolled_view,double interval) 
+{
+   if (!scrolled_view)
+      return 0.0f;
+   interval = interval >= 0.2f ? interval : 0.2f;
+   scrolled_view->drag.sample_magic = interval;
+   return scrolled_view->drag.sample_magic;
+}
+
+/**
+ * @brief Get the scrolled view sample interval to calculate the scrolling 
speed.
+ * @param scrolled_view a scrolled view
+ * @return Returns the sampling interval. If scrolled_view is NULL return 
0.0f. 
+ */
+double etk_scrolled_view_drag_sample_interval_magic_get(Etk_Scrolled_View 
*scrolled_view)
+{
+   if (!scrolled_view)
+      return 0.0f;
+   return scrolled_view->drag.sample_magic;
+}
+
+/**
+ * @brief Set the damping magic number of a dragable scrolled view
+ * @param scrolled_view a scrolled view
+ * @param damping The damping factor of the dragable scrolled view (default 
100)
+ * @return Returns the actual damping factor set
+ */ 
+unsigned int etk_scrolled_view_drag_damping_magic_set(Etk_Scrolled_View 
*scrolled_view,unsigned int damping)
+{
+   if (!scrolled_view)
+      return 0;
+   scrolled_view->drag.damping_magic = damping;
+   return scrolled_view->drag.damping_magic;
+}
+
+/**
+ * @brief Get the damping magic number of a dragable scrolled view
+ * @param scrolled_view a scrolled view
+ * @return Returns the actual damping factor
+ */ 
+unsigned int etk_scrolled_view_drag_damping_magic_get(Etk_Scrolled_View 
*scrolled_view) 
+{
+   if (!scrolled_view)
+      return 0;
+   return scrolled_view->drag.damping_magic;
+}
 
 /**************************
  *
@@ -189,6 +297,14 @@
    scrolled_view->hpolicy = ETK_POLICY_AUTO;
    scrolled_view->vpolicy = ETK_POLICY_AUTO;
 
+   scrolled_view->drag.bar_pressed = ETK_FALSE;
+   scrolled_view->drag.dragable    = ETK_FALSE;
+   scrolled_view->drag.bouncy      = ETK_TRUE;
+
+   // FIXME This can be put in etk_config (Make whole system be configured)
+   etk_scrolled_view_drag_sample_interval_magic_set(scrolled_view,0.5f);
+   etk_scrolled_view_drag_damping_magic_set(scrolled_view,100);
+
    scrolled_view->hscrollbar = etk_hscrollbar_new(0.0, 0.0, 0.0, 12.0, 50.0, 
0.0);
    etk_widget_theme_parent_set(scrolled_view->hscrollbar, 
ETK_WIDGET(scrolled_view));
    etk_widget_parent_set(scrolled_view->hscrollbar, ETK_WIDGET(scrolled_view));
@@ -205,11 +321,18 @@
    ETK_WIDGET(scrolled_view)->size_allocate = _etk_scrolled_view_size_allocate;
 
    etk_signal_connect_by_code(ETK_WIDGET_KEY_DOWN_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_key_down_cb), NULL);
+   etk_signal_connect_by_code(ETK_WIDGET_MOUSE_DOWN_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_mouse_down), 
&scrolled_view->drag);
+   etk_signal_connect_by_code(ETK_WIDGET_MOUSE_UP_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_mouse_up), 
&scrolled_view->drag);
+   etk_signal_connect_by_code(ETK_WIDGET_MOUSE_CLICK_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_mouse_click), 
&scrolled_view->drag);
+   etk_signal_connect_by_code(ETK_WIDGET_MOUSE_MOVE_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_mouse_move), 
&scrolled_view->drag);
    etk_signal_connect_by_code(ETK_WIDGET_MOUSE_WHEEL_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_mouse_wheel), NULL);
    etk_signal_connect_by_code(ETK_CONTAINER_CHILD_ADDED_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_child_added_cb), 
NULL);
    etk_signal_connect_by_code(ETK_CONTAINER_CHILD_REMOVED_SIGNAL, 
ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_child_removed_cb), 
NULL);
    etk_signal_connect_by_code(ETK_RANGE_VALUE_CHANGED_SIGNAL, 
ETK_OBJECT(scrolled_view->hscrollbar), 
ETK_CALLBACK(_etk_scrolled_view_hscrollbar_value_changed_cb), scrolled_view);
+   etk_signal_connect_by_code(ETK_WIDGET_MOUSE_DOWN_SIGNAL, 
ETK_OBJECT(scrolled_view->hscrollbar), 
ETK_CALLBACK(_etk_scrolled_view_bar_mouse_down), scrolled_view);
    etk_signal_connect_by_code(ETK_RANGE_VALUE_CHANGED_SIGNAL, 
ETK_OBJECT(scrolled_view->vscrollbar), 
ETK_CALLBACK(_etk_scrolled_view_vscrollbar_value_changed_cb), scrolled_view);
+   etk_signal_connect_by_code(ETK_WIDGET_MOUSE_DOWN_SIGNAL, 
ETK_OBJECT(scrolled_view->vscrollbar), 
ETK_CALLBACK(_etk_scrolled_view_bar_mouse_down), scrolled_view);
+
 }
 
 /* Sets the property whose id is "property_id" to the value "value" */
@@ -390,6 +513,94 @@
    etk_widget_size_allocate(child, child_geometry);
 }
 
+/* Check if reaching the boundary */
+static inline double _etk_scrolled_view_bounce_check (Etk_Range * range, 
double delta,double v) 
+{
+   double pos = (range->value + delta);
+   if (pos <= range->lower) 
+   {
+      pos = range->lower + (range->lower - pos);
+      v *= -1;
+   }
+   etk_range_value_set(range, pos);
+   if (pos > range->value) 
+      v *= -1;
+   return v;
+}
+
+/* Animator for inertial scrolling */
+static int _etk_scrolled_view_motive_bounce(void *data) 
+{
+   Etk_Scrolled_View *scrolled_view = ETK_SCROLLED_VIEW(data);
+   struct Etk_Scrolled_View_Mouse_Drag *drag;
+   Etk_Range *vscrollbar_range;
+   Etk_Range *hscrollbar_range;
+   double delta_time;
+   double delta_V;
+   double delta_x;
+   double delta_y;
+   if (!scrolled_view) 
+      return 0;
+   drag = &scrolled_view->drag;
+   if (drag->mouse_down) 
+      return 0;
+
+   // Using trapezoid method to calculate the distance. 
+   delta_time = ecore_time_get() - drag->timestamp;
+   delta_V = delta_time * (drag->damping_magic + abs(drag->Vx)+ 
abs(drag->Vy))/2;
+   delta_time = delta_time < 0.01f ? 0.01f: delta_time;
+
+   if (drag->Vx < delta_V && drag->Vx > -delta_V) 
+   {
+      delta_x = 0;
+      drag->Vx = 0;
+   } 
+   else if (drag->Vx > 0)
+   {
+      delta_x = ((drag->Vx * 2) - delta_V) * delta_time / 2;
+      drag->Vx = drag->Vx - delta_V;
+   } 
+   else 
+   {
+      delta_x = ((drag->Vx * 2) + delta_V) * delta_time / 2;
+      drag->Vx = drag->Vx +  delta_V;
+   }
+
+   if (drag->Vy < delta_V && drag->Vy > -delta_V) 
+   {
+      drag->Vy = 0;
+      delta_y = 0;
+   } 
+   else if(drag->Vy > 0)
+   {
+      delta_y = ((drag->Vy * 2) - delta_V) * delta_time / 2;
+      drag->Vy = drag->Vy - delta_V;
+   } else 
+   {
+      delta_y = ((drag->Vy * 2) + delta_V) * delta_time / 2;
+      drag->Vy = drag->Vy + delta_V;
+   }
+
+   if (drag->Vx == 0 && drag->Vy == 0) 
+      return 0;
+
+   vscrollbar_range = ETK_RANGE(scrolled_view->vscrollbar);
+   hscrollbar_range = ETK_RANGE(scrolled_view->hscrollbar);
+   if (drag->bouncy)  
+   {
+      drag->Vx = _etk_scrolled_view_bounce_check(hscrollbar_range, delta_x, 
drag->Vx);
+      drag->Vy = _etk_scrolled_view_bounce_check(vscrollbar_range, delta_y, 
drag->Vy);
+   }
+   else 
+   {
+      drag->Vx = drag->Vx == _etk_scrolled_view_bounce_check(hscrollbar_range, 
delta_x, drag->Vx) ? drag->Vx : 0.0f;
+      drag->Vy = drag->Vy == _etk_scrolled_view_bounce_check(vscrollbar_range, 
delta_y, drag->Vy) ? drag->Vy : 0.0f;
+   }
+   drag->timestamp = ecore_time_get();
+   return 1;
+}
+
+
 /**************************
  *
  * Callbacks and handlers
@@ -431,6 +642,135 @@
    return propagate;
 }
 
+/* Called when mouse button has been pressed down */
+static Etk_Bool _etk_scrolled_view_mouse_down(Etk_Object *object, 
Etk_Event_Mouse_Down *event, void *data) 
+{
+   Etk_Scrolled_View *scrolled_view;
+   Etk_Range *vscrollbar_range;
+   Etk_Range *hscrollbar_range;
+   struct Etk_Scrolled_View_Mouse_Drag *drag = (struct 
Etk_Scrolled_View_Mouse_Drag *) data;
+
+   if (!(scrolled_view = ETK_SCROLLED_VIEW(object)))
+      return ETK_FALSE;
+
+   if (!drag->dragable) 
+      return ETK_FALSE;
+
+   if (!drag->mouse_down && event->button) 
+   {
+      vscrollbar_range = ETK_RANGE(scrolled_view->vscrollbar);
+      hscrollbar_range = ETK_RANGE(scrolled_view->hscrollbar);
+      drag->mouse_down = ETK_TRUE;
+      drag->timestamp = ecore_time_get(); 
+      drag->old_timestamp = 0.0f;
+      drag->position = event->widget;
+      drag->bar_position.x = hscrollbar_range->value;
+      drag->bar_position.y = vscrollbar_range->value;
+   }
+   return ETK_FALSE;
+}
+
+/* Called when mouse is dragging */
+static Etk_Bool _etk_scrolled_view_mouse_move(Etk_Object *object, 
Etk_Event_Mouse_Move *event, void *data) 
+{
+   Etk_Scrolled_View *scrolled_view;
+   Etk_Range *vscrollbar_range;
+   Etk_Range *hscrollbar_range;
+   double delta_time;
+   struct Etk_Scrolled_View_Mouse_Drag *drag = (struct 
Etk_Scrolled_View_Mouse_Drag *) data;
+
+   if (!(scrolled_view = ETK_SCROLLED_VIEW(object)))
+      return ETK_FALSE;
+
+   if (!drag->dragable)
+      return ETK_FALSE;
+
+   if (!drag->mouse_down) 
+      return ETK_FALSE;
+
+   if (!event->buttons) 
+      return ETK_FALSE;
+
+   vscrollbar_range = ETK_RANGE(scrolled_view->vscrollbar);
+   hscrollbar_range = ETK_RANGE(scrolled_view->hscrollbar);
+   if (drag->scroll_flag == 0) 
+   {
+         drag->scroll_flag = (event->cur.widget.y - 
drag->position.y)/vscrollbar_range->step_increment || (event->cur.widget.x - 
drag->position.x)/hscrollbar_range->step_increment;
+   }
+
+   if (drag->scroll_flag) 
+   {
+      if (drag->bar_pressed==ETK_FALSE) 
+      {
+         etk_range_value_set(vscrollbar_range, vscrollbar_range->value - 
(event->cur.widget.y - drag->position.y));
+         etk_range_value_set(hscrollbar_range, hscrollbar_range->value - 
(event->cur.widget.x - drag->position.x));
+      }
+      drag->position  = event->cur.widget;
+      delta_time = ecore_time_get() - drag->timestamp;
+      // in case delta_time is zero
+      delta_time = delta_time == 0.0f ? drag->sample_magic : delta_time;
+      if (delta_time > drag->sample_magic || drag->old_timestamp == 0) 
+      {
+         drag->old_timestamp = drag->timestamp;
+         drag->timestamp = ecore_time_get();
+         drag->Vx = (hscrollbar_range->value - drag->bar_position.x) / 
delta_time;
+         drag->Vy = (vscrollbar_range->value - drag->bar_position.y) / 
delta_time;
+         drag->bar_position.x = hscrollbar_range->value;
+         drag->bar_position.y = vscrollbar_range->value;
+      }
+      return ETK_TRUE;
+   }
+   return ETK_FALSE;
+}
+
+/* Called when mouse button has been released */
+static Etk_Bool _etk_scrolled_view_mouse_up(Etk_Object *object, 
Etk_Event_Mouse_Up *event, void *data) 
+{
+   Etk_Scrolled_View *scrolled_view;
+   struct Etk_Scrolled_View_Mouse_Drag *drag = (struct 
Etk_Scrolled_View_Mouse_Drag *) data;
+
+   if (!(scrolled_view = ETK_SCROLLED_VIEW(object)))
+      return ETK_FALSE;
+
+   if (!drag->dragable) 
+      return ETK_FALSE;
+
+   if (!drag->mouse_down) 
+      return ETK_FALSE;
+
+   if (drag->bar_pressed == ETK_TRUE) 
+   {
+      drag->bar_pressed = ETK_FALSE;
+      return ETK_FALSE;
+   }
+
+   drag->mouse_down = ETK_FALSE;
+
+   if (drag->scroll_flag) 
+   {
+      drag->timestamp = ecore_time_get();
+      ecore_animator_add(&_etk_scrolled_view_motive_bounce, scrolled_view);
+      return ETK_TRUE;
+   }
+   return ETK_FALSE;
+}
+
+/* Called when mouse button has been clicked */
+static Etk_Bool _etk_scrolled_view_mouse_click (Etk_Object *object, 
Etk_Event_Mouse_Up *event, void *data) 
+{
+   Etk_Scrolled_View *scrolled_view;
+   struct Etk_Scrolled_View_Mouse_Drag *drag = (struct 
Etk_Scrolled_View_Mouse_Drag *) data;
+   if (!(scrolled_view = ETK_SCROLLED_VIEW(object)))
+      return ETK_TRUE;
+
+   if (drag->scroll_flag) 
+   {
+      drag->scroll_flag = 0;
+      return ETK_TRUE;
+   }
+   return ETK_FALSE;
+}
+
 /* Called when the user wants to scroll the scrolled view with the mouse wheel 
*/
 static Etk_Bool _etk_scrolled_view_mouse_wheel(Etk_Object *object, 
Etk_Event_Mouse_Wheel *event, void *data)
 {
@@ -457,6 +797,18 @@
 
    return ETK_TRUE;
 }
+
+/* Called when dragging on the scrollbar */
+static Etk_Bool _etk_scrolled_view_bar_mouse_down(Etk_Object *object, 
Etk_Event_Mouse_Down *event, void *data) 
+{
+   Etk_Scrolled_View *scrolled_view;
+   Etk_Widget *child;
+   if (!(scrolled_view = ETK_SCROLLED_VIEW(data)) || !(child = 
ETK_BIN(scrolled_view)->child) || !child->scroll)
+      return ETK_FALSE;
+   scrolled_view->drag.bar_pressed = ETK_TRUE;
+   return ETK_FALSE;
+}
+
 
 /* Called when the value of the vscrollbar has changed */
 static Etk_Bool _etk_scrolled_view_vscrollbar_value_changed_cb(Etk_Object 
*object, double value, void *data)
===================================================================
RCS file: /cvs/e/e17/libs/etk/src/lib/etk_scrolled_view.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -3 -r1.12 -r1.13
--- etk_scrolled_view.h 19 Sep 2007 20:16:26 -0000      1.12
+++ etk_scrolled_view.h 10 Apr 2008 09:03:08 -0000      1.13
@@ -33,9 +33,24 @@
    ETK_POLICY_AUTO,     /**< The scrollbar is shown and hidden automatically 
whether or not the child can fit
                          * entirely in the scrolled view */
    ETK_POLICY_SHOW,     /**< The scrollbar is always visible */
-   ETK_POLICY_HIDE      /**< The scrollbar is always hidden */
+   ETK_POLICY_HIDE,     /**< The scrollbar is always hidden */
 } Etk_Scrolled_View_Policy;
 
+struct Etk_Scrolled_View_Mouse_Drag 
+{
+   Etk_Bool mouse_down;
+   Etk_Bool bar_pressed;
+   Etk_Bool dragable;
+   Etk_Bool bouncy;
+   int scroll_flag;
+   Etk_Position position;
+   Etk_Position bar_position;
+   double sample_magic;
+   unsigned int damping_magic;
+   double timestamp;
+   double old_timestamp;
+   double Vx,Vy;
+};
 
 /**
  * @brief @widget The structure of a scrolled view
@@ -52,9 +67,12 @@
 
    Etk_Scrolled_View_Policy hpolicy;
    Etk_Scrolled_View_Policy vpolicy;
+
+   struct Etk_Scrolled_View_Mouse_Drag drag;
 };
 
 
+
 Etk_Type   *etk_scrolled_view_type_get(void);
 Etk_Widget *etk_scrolled_view_new(void);
 
@@ -63,6 +81,14 @@
 void        etk_scrolled_view_add_with_viewport(Etk_Scrolled_View 
*scrolled_view, Etk_Widget *child);
 void        etk_scrolled_view_policy_set(Etk_Scrolled_View *scrolled_view, 
Etk_Scrolled_View_Policy hpolicy, Etk_Scrolled_View_Policy vpolicy);
 void        etk_scrolled_view_policy_get(Etk_Scrolled_View *scrolled_view, 
Etk_Scrolled_View_Policy *hpolicy, Etk_Scrolled_View_Policy *vpolicy);
+void        etk_scrolled_view_dragable_set(Etk_Scrolled_View *scrolled_view, 
Etk_Bool dragable);
+Etk_Bool    etk_scrolled_view_dragable_get(Etk_Scrolled_View *scrolled_view);
+void        etk_scrolled_view_drag_bouncy_set(Etk_Scrolled_View 
*scrolled_view, Etk_Bool bouncy);
+Etk_Bool    etk_scrolled_view_drag_bouncy_get(Etk_Scrolled_View 
*scrolled_view);
+double      etk_scrolled_view_drag_sample_interval_magic_set(Etk_Scrolled_View 
*scrolled_view,double interval);
+double      etk_scrolled_view_drag_sample_interval_magic_get(Etk_Scrolled_View 
*scrolled_view);
+unsigned int etk_scrolled_view_drag_damping_magic_set(Etk_Scrolled_View 
*scrolled_view,unsigned int damping);
+unsigned int etk_scrolled_view_drag_damping_magic_get(Etk_Scrolled_View 
*scrolled_view);
 
 /** @} */
 



-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to