Enlightenment CVS committal

Author  : codewarrior
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        etk_dnd.c etk_widget.c etk_widget.h 


Log Message:
- add theme stuff to show when a widget accepts a drop
- add per widget dnd types, now widgets can opt to only get image/png or 
text/uri-list etc.
- remove generate dnd aware code for widgets, make widgets select wether they 
want to be a drag source or drag destinaion or both
- reflect new changes in etk_test

===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_dnd.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -3 -r1.5 -r1.6
--- etk_dnd.c   13 Feb 2006 00:00:01 -0000      1.5
+++ etk_dnd.c   14 Feb 2006 02:28:02 -0000      1.6
@@ -33,10 +33,13 @@
 
 #define ETK_DND_INSIDE(x, y, xx, yy, ww, hh) (((x) < ((xx) + (ww))) && ((y) < 
((yy) + (hh))) && ((x) >= (xx)) && ((y) >= (yy)))
 
-extern Etk_Widget *_etk_selection_widget;
+extern Etk_Widget  *_etk_selection_widget;
 
-static Etk_Widget *_etk_dnd_widget = NULL;
-static Evas_List  *_etk_dnd_handlers = NULL;
+static char       **_etk_dnd_types          = NULL;
+static int          _etk_dnd_types_num      = 0;
+static Etk_Widget  *_etk_dnd_widget         = NULL;
+static Evas_List   *_etk_dnd_handlers       = NULL;
+static int          _etk_dnd_widget_accepts = 0;
 
 #if HAVE_ECORE_X
 static void _etk_xdnd_container_get_widgets_at(Etk_Toplevel_Widget *top, int 
x, int y, int offx, int offy, Evas_List **list);
@@ -94,7 +97,15 @@
  **************************/
 
 #if HAVE_ECORE_X
-/* Search the container recursively for the widget that accepts xdnd */
+/**
+ * @brief Search the container recursively for the widget that accepts xdnd
+ * @param top top level widget
+ * @param x the x coord we're searching under
+ * @param y the y coord we're searching under
+ * @param xoff the x offset for the window
+ * @param yoff the y offset for the window
+ * @param list the evas list we're going to append widgets to
+ */
 static void _etk_xdnd_container_get_widgets_at(Etk_Toplevel_Widget *top, int 
x, int y, int offx, int offy, Evas_List **list)
 {
 
@@ -104,7 +115,7 @@
    if (!top || !list)
       return;
    
-   for (l = etk_widget_dnd_aware_widgets_get(); l; l = l->next)
+   for (l = etk_widget_dnd_dest_widgets_get(); l; l = l->next)
    {
       Etk_Widget *widget;
       
@@ -117,22 +128,44 @@
    }
 }
 
-/* TODO: doc */
+/**
+ * @brief The event handler for when a drag enters our window
+ */
 static int _etk_xdnd_enter_handler(void *data, int type, void *event)
 {
    Ecore_X_Event_Xdnd_Enter *ev;
-   //int i;
+   int i;
    
    ev = event;
    
-//   printf("enter window!\n");
-//   for (i = 0; i < ev->num_types; i++)
-//      printf("type: %s\n", ev->types[i]);
+   printf("enter window!\n");   
+   for (i = 0; i < ev->num_types; i++)
+     printf("type: %s\n", ev->types[i]);   
+   
+   if(_etk_dnd_types != NULL && _etk_dnd_types_num >= 0)
+   {
+      for (i = 0; i < _etk_dnd_types_num; i++)
+       if(_etk_dnd_types[i]) free(_etk_dnd_types[i]);
+   }
+   
+   if(_etk_dnd_types != NULL) free(_etk_dnd_types);
+   _etk_dnd_types_num = 0;
+   
+   if(ev->num_types > 0)
+   {
+      _etk_dnd_types = calloc(ev->num_types, sizeof(char*));
+      for (i = 0; i < ev->num_types; i++)
+       _etk_dnd_types[i] = strdup(ev->types[i]);
+
+      _etk_dnd_types_num = ev->num_types;
+   }
    
    return 1;
 }
 
-/* TODO: doc */
+/**
+ * @brief The event handler for when a drag is moving in our window
+ */
 static int _etk_xdnd_position_handler(void *data, int type, void *event)
 {
    Ecore_X_Event_Xdnd_Position *ev;
@@ -171,6 +204,7 @@
          {
             etk_widget_drag_leave(_etk_dnd_widget);
             _etk_dnd_widget = NULL;
+           _etk_dnd_widget_accepts = 0;
          }
       }
       
@@ -181,18 +215,55 @@
    if (children != NULL)
    {   
       Ecore_X_Rectangle rect;
+      int i;
       
       widget = (evas_list_last(children))->data;
       etk_widget_geometry_get(widget, &wx, &wy, &ww, &wh);
-      _etk_dnd_widget = widget;
-      /* TODO: filter types according to what widget wants */
+
       rect.x = wx;
       rect.y = wy;
       rect.width = ww;
-      rect.height = wh;        
-      ecore_x_dnd_send_status(1, 1, rect, ECORE_X_DND_ACTION_PRIVATE);
+      rect.height = wh;
+      
+      if(_etk_dnd_widget == widget && _etk_dnd_widget_accepts)
+      {
+        etk_widget_drag_motion(widget);
+        ecore_x_dnd_send_status(1, 1, rect, ECORE_X_DND_ACTION_PRIVATE);
+      }
+      else
+      {      
+        _etk_dnd_widget = widget;
       
-      etk_widget_drag_motion(widget);
+        /* first case - no specific types, so just accept */
+        if(_etk_dnd_widget->dnd_types == NULL || 
_etk_dnd_widget->dnd_types_num <= 0)
+        {
+           ecore_x_dnd_send_status(1, 1, rect, ECORE_X_DND_ACTION_PRIVATE);
+           _etk_dnd_widget_accepts = 1;
+           etk_widget_drag_enter(widget);
+           return 1;
+        }
+        
+        /* second case - we found matching types, accept */
+        for(i = 0; i < _etk_dnd_types_num; i++)
+          {
+             int j;
+             
+             for(j = 0; j < _etk_dnd_widget->dnd_types_num; j++)
+               {
+                  if(!strcmp(_etk_dnd_widget->dnd_types[j], _etk_dnd_types[i]))
+                  {
+                     ecore_x_dnd_send_status(1, 1, rect, 
ECORE_X_DND_ACTION_PRIVATE);
+                     _etk_dnd_widget_accepts = 1;
+                     etk_widget_drag_enter(widget);
+                     return 1;
+                  }
+               }
+          }
+        
+        /* third case - no matches at all, dont accept */
+        ecore_x_dnd_send_status(0, 1, rect, ECORE_X_DND_ACTION_PRIVATE);
+        _etk_dnd_widget_accepts = 0;
+      }
    }
    else
    {
@@ -212,11 +283,24 @@
 static int _etk_xdnd_drop_handler(void *data, int type, void *event)
 {
    Ecore_X_Event_Xdnd_Drop *ev;
+   int i;
    
    //printf("drop\n");
    ev = event;
    
-   ecore_x_selection_xdnd_request(ev->win, "text/uri-list");
+   /* first case - if we dont have a type preferece, send everyting */
+   if(_etk_dnd_widget->dnd_types == NULL || _etk_dnd_widget->dnd_types_num <= 
0)
+   {
+      for(i = 0; i < _etk_dnd_types_num; i++)
+       ecore_x_selection_xdnd_request(ev->win, _etk_dnd_types[i]);
+   }
+   /* second case - send only our preferred types */
+   else
+   {
+      for(i = 0; i < _etk_dnd_widget->dnd_types_num; i++)
+       ecore_x_selection_xdnd_request(ev->win, _etk_dnd_widget->dnd_types[i]);
+   }
+   
    return 1;
 }
 
@@ -270,27 +354,30 @@
          break;
       
       case ECORE_X_SELECTION_XDND:
-        files = ev->data;
-       
-        if (!_etk_dnd_widget || files->num_files < 1)
-            break;     
-       
-        /* free old data, should this be done here? */
-        for (i = 0; i < _etk_dnd_widget->dnd_files_num; i++)
-            free(_etk_dnd_widget->dnd_files[i]);
-         free(_etk_dnd_widget->dnd_files);         
-       
-         _etk_dnd_widget->dnd_files = calloc(files->num_files, sizeof(char*));
-         
-         /* Fill in the drop data into the widget */
-         _etk_dnd_widget->dnd_files_num = files->num_files;
-         for (i = 0; i < files->num_files; i++)        
-       _etk_dnd_widget->dnd_files[i] = strdup(files->files[i]);         
-       
-         /* emit the drop signal so the widget can react */
-         etk_widget_drag_drop(_etk_dnd_widget);
-         _etk_dnd_widget = NULL;
+        if(!strcmp(ev->target, "text/uri-list"))
+        {      
+           files = ev->data;
        
+           if (!_etk_dnd_widget || files->num_files < 1)
+             break;    
+           
+           /* free old data, should this be done here? */
+           for (i = 0; i < _etk_dnd_widget->dnd_files_num; i++)
+             free(_etk_dnd_widget->dnd_files[i]);
+           free(_etk_dnd_widget->dnd_files);       
+           
+           _etk_dnd_widget->dnd_files = calloc(files->num_files, 
sizeof(char*));
+           
+           /* Fill in the drop data into the widget */
+           _etk_dnd_widget->dnd_files_num = files->num_files;
+           for (i = 0; i < files->num_files; i++)      
+             _etk_dnd_widget->dnd_files[i] = strdup(files->files[i]);
+        }
+           
+        /* emit the drop signal so the widget can react */
+        etk_widget_drag_drop(_etk_dnd_widget);
+        _etk_dnd_widget = NULL;         
+        
          ecore_x_dnd_send_finished();
          break;
        
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -3 -r1.31 -r1.32
--- etk_widget.c        13 Feb 2006 01:10:20 -0000      1.31
+++ etk_widget.c        14 Feb 2006 02:28:02 -0000      1.32
@@ -56,6 +56,7 @@
    ETK_WIDGET_UNFOCUS_SIGNAL,
    ETK_WIDGET_SCROLL_SIZE_CHANGED_SIGNAL,
    ETK_WIDGET_DRAG_DROP_SIGNAL,
+   ETK_WIDGET_DRAG_ENTER_SIGNAL,     
    ETK_WIDGET_DRAG_MOTION_SIGNAL,
    ETK_WIDGET_DRAG_LEAVE_SIGNAL,
    ETK_WIDGET_SELECTION_RECEIVED_SIGNAL,
@@ -93,6 +94,7 @@
 
 static void _etk_widget_drag_drop_handler(Etk_Widget *widget);
 static void _etk_widget_drag_motion_handler(Etk_Widget *widget);
+static void _etk_widget_drag_enter_handler(Etk_Widget *widget);
 static void _etk_widget_drag_leave_handler(Etk_Widget *widget);
 
 static void _etk_widget_mouse_in_cb(void *data, Evas *evas, Evas_Object 
*object, void *event_info);
@@ -139,7 +141,7 @@
 static Etk_Bool _etk_widget_propagate_event = ETK_TRUE;
 static Etk_Bool _etk_widget_intercept_show_hide = ETK_TRUE;
 static Evas_Smart *_etk_widget_event_object_smart = NULL;
-static Evas_List *_etk_widget_dnd_widgets;
+static Evas_List *_etk_widget_dnd_dest_widgets;
 
 /**************************
  *
@@ -180,6 +182,7 @@
       _etk_widget_signals[ETK_WIDGET_UNFOCUS_SIGNAL] =       
etk_signal_new("unfocus",       widget_type, ETK_MEMBER_OFFSET(Etk_Widget, 
unfocus), etk_marshaller_VOID__VOID,    NULL, NULL);
       _etk_widget_signals[ETK_WIDGET_DRAG_DROP_SIGNAL] =     
etk_signal_new("drag_drop",     widget_type, ETK_MEMBER_OFFSET(Etk_Widget, 
drag_drop),   etk_marshaller_VOID__VOID, NULL, NULL);
       _etk_widget_signals[ETK_WIDGET_DRAG_MOTION_SIGNAL] =   
etk_signal_new("drag_motion",   widget_type, ETK_MEMBER_OFFSET(Etk_Widget, 
drag_motion), etk_marshaller_VOID__VOID, NULL, NULL);
+      _etk_widget_signals[ETK_WIDGET_DRAG_ENTER_SIGNAL] =    
etk_signal_new("drag_enter",    widget_type, ETK_MEMBER_OFFSET(Etk_Widget, 
drag_enter),  etk_marshaller_VOID__VOID, NULL, NULL);
       _etk_widget_signals[ETK_WIDGET_DRAG_LEAVE_SIGNAL] =    
etk_signal_new("drag_leave",    widget_type, ETK_MEMBER_OFFSET(Etk_Widget, 
drag_leave),  etk_marshaller_VOID__VOID, NULL, NULL);
       _etk_widget_signals[ETK_WIDGET_SELECTION_RECEIVED_SIGNAL] = 
etk_signal_new("selection_received", widget_type, -1,                           
etk_marshaller_VOID__POINTER, NULL, NULL);
       _etk_widget_signals[ETK_WIDGET_CLIPBOARD_RECEIVED_SIGNAL] = 
etk_signal_new("clipboard_received", widget_type, -1,                           
etk_marshaller_VOID__POINTER, NULL, NULL);
@@ -1267,11 +1270,11 @@
 }
 
 /**
- * @brief Sets whether the widget is dnd aware or not
+ * @brief Sets whether the widget is dnd destination
  * @param widget a widget
- * @param on ETK_TRUE to enable dnd, ETK_FALSE to disable it
+ * @param on ETK_TRUE to enable this widget as a dnd destination, ETK_FALSE to 
disable it
  */
-void etk_widget_dnd_aware_set(Etk_Widget *widget, Etk_Bool on)
+void etk_widget_dnd_dest_set(Etk_Widget *widget, Etk_Bool on)
 {
    if (!widget)
       return;
@@ -1279,21 +1282,21 @@
    if (on)
    {
       widget->accepts_dnd = ETK_TRUE;
-      _etk_widget_dnd_widgets = evas_list_append(_etk_widget_dnd_widgets, 
widget);
+      _etk_widget_dnd_dest_widgets = 
evas_list_append(_etk_widget_dnd_dest_widgets, widget);
    }
    else
    {
       widget->accepts_dnd = ETK_FALSE;
-      _etk_widget_dnd_widgets = evas_list_remove(_etk_widget_dnd_widgets, 
widget);
+      _etk_widget_dnd_dest_widgets = 
evas_list_remove(_etk_widget_dnd_dest_widgets, widget);
    }
 }
 
 /**
- * @brief Checks whether the widget is dnd aware
+ * @brief Checks whether the widget is a dnd destination
  * @param widget a widget
- * @return Returns ETK_TRUE if the widget is dnd aware, ETK_FALSE otherwise
+ * @return Returns ETK_TRUE if the widget is a dnd destination, ETK_FALSE 
otherwise
  */
-Etk_Bool etk_widget_dnd_aware_get(Etk_Widget *widget)
+Etk_Bool etk_widget_dnd_dest_get(Etk_Widget *widget)
 {
    if (!widget)
       return ETK_FALSE;
@@ -1301,6 +1304,57 @@
 }
 
 /**
+ * @brief Sets the possible types for dnd
+ * @param widget a widget
+ * @param types list of acceptable types
+ * @param num number of types
+ */
+void etk_widget_dnd_types_set(Etk_Widget *widget, char **types, int num)
+{
+   int i;
+   
+   if (!widget)
+      return;
+   
+   /* free old data */
+   if(num <= 0 || types == NULL || 
+     (widget->dnd_types_num > 0 && widget->dnd_types != NULL))
+   {
+      
+      for(i = 0; i < widget->dnd_types_num; i++)
+       if(widget->dnd_types[i]) free(widget->dnd_types[i]);
+      
+      if(widget->dnd_types) free(widget->dnd_types);
+      
+      widget->dnd_types = NULL;
+      widget->dnd_types_num = 0;
+      return;
+   }
+   
+   widget->dnd_types = calloc(num, sizeof(char*));
+   for(i = 0; i < num; i++)
+     widget->dnd_types[i] = strdup(types[i]);
+   
+   widget->dnd_types_num = num;
+}
+
+/**
+ * @brief Gets the possible types for dnd
+ * @param widget a widget
+ * @param num number of types that the widget has
+ * @return returns the dnd types this widget supports
+ */
+const char **etk_widget_dnd_types_get(Etk_Widget *widget, int *num)
+{
+   if (!widget)
+      return ETK_FALSE;
+   
+   if(num)
+     *num = widget->dnd_types_num;
+   return widget->dnd_types;
+}
+
+/**
  * @brief Gets the list of the files dropped on the widget
  * @param widget a widget
  * @param on ETK_TRUE to enable dnd, ETK_FALSE to disable it
@@ -1320,12 +1374,12 @@
 }
 
 /**
- * @brief Gets the list of the dnd-aware widgets
- * @return Returns the list of the dnd-aware widgets
+ * @brief Gets the list of the widgets that are dnd destinations
+ * @return Returns the list of the dnd destination widgets
  */
-Evas_List *etk_widget_dnd_aware_widgets_get()
+Evas_List *etk_widget_dnd_dest_widgets_get()
 {
-   return _etk_widget_dnd_widgets;
+   return _etk_widget_dnd_dest_widgets;
 }
 
 /**
@@ -1351,7 +1405,19 @@
 }
 
 /**
- * @brief Sends the "drag_motion" signal
+ * @brief Sends the "drag_enter" signal
+ * @param widget a widget
+ */
+void etk_widget_drag_enter(Etk_Widget *widget)
+{
+   if (!widget)
+      return;
+
+   etk_signal_emit(_etk_widget_signals[ETK_WIDGET_DRAG_ENTER_SIGNAL], 
ETK_OBJECT(widget), NULL);
+}
+
+/**
+ * @brief Sends the "drag_leave" signal
  * @param widget a widget
  */
 void etk_widget_drag_leave(Etk_Widget *widget)
@@ -1419,6 +1485,7 @@
    widget->unfocus = _etk_widget_unfocus_handler;
    widget->drag_drop = _etk_widget_drag_drop_handler;
    widget->drag_motion = _etk_widget_drag_motion_handler;
+   widget->drag_enter = _etk_widget_drag_enter_handler;   
    widget->drag_leave = _etk_widget_drag_leave_handler; 
 
    widget->left_inset = 0;
@@ -1455,7 +1522,9 @@
    widget->accepts_dnd = ETK_FALSE;
    widget->dnd_files = NULL;
    widget->dnd_files_num = 0;
-
+   widget->dnd_types = NULL;
+   widget->dnd_types_num = 0;
+   
    etk_signal_connect_full(_etk_widget_signals[ETK_WIDGET_MOUSE_IN_SIGNAL], 
ETK_OBJECT(widget), ETK_CALLBACK(_etk_widget_signal_mouse_in_cb), NULL, 
ETK_FALSE, ETK_FALSE);
    etk_signal_connect_full(_etk_widget_signals[ETK_WIDGET_MOUSE_OUT_SIGNAL], 
ETK_OBJECT(widget), ETK_CALLBACK(_etk_widget_signal_mouse_out_cb), NULL, 
ETK_FALSE, ETK_FALSE);
    etk_signal_connect_full(_etk_widget_signals[ETK_WIDGET_MOUSE_DOWN_SIGNAL], 
ETK_OBJECT(widget), ETK_CALLBACK(_etk_widget_signal_mouse_down_cb), NULL, 
ETK_FALSE, ETK_FALSE);
@@ -1488,7 +1557,7 @@
       free(widget->dnd_files[i]);
    free(widget->dnd_files);
    if (widget->accepts_dnd)
-      _etk_widget_dnd_widgets = evas_list_remove(_etk_widget_dnd_widgets, 
widget);
+      _etk_widget_dnd_dest_widgets = 
evas_list_remove(_etk_widget_dnd_dest_widgets, widget);
    
    free(widget->theme_file);
    free(widget->theme_group);
@@ -1666,6 +1735,15 @@
    etk_widget_theme_object_signal_emit(widget, "drag_motion");
 }
 
+/* Default handler for the "drag_enter" signal */
+static void _etk_widget_drag_enter_handler(Etk_Widget *widget)
+{
+   if (!widget)
+      return;
+
+   etk_widget_theme_object_signal_emit(widget, "drag_enter");
+}
+
 /* Default handler for the "drag_leave" signal */
 static void _etk_widget_drag_leave_handler(Etk_Widget *widget)
 {
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- etk_widget.h        12 Feb 2006 20:08:20 -0000      1.19
+++ etk_widget.h        14 Feb 2006 02:28:02 -0000      1.20
@@ -175,6 +175,7 @@
    void (*unfocus)(Etk_Widget *widget);
    void (*drag_drop)(Etk_Widget *widget);
    void (*drag_motion)(Etk_Widget *widget);
+   void (*drag_enter)(Etk_Widget *widget);   
    void (*drag_leave)(Etk_Widget *widget);
 
    unsigned char realized : 1;
@@ -192,7 +193,9 @@
    unsigned char accepts_dnd : 1;
    
    char **dnd_files;
-   int dnd_files_num;
+   int    dnd_files_num;
+   char **dnd_types;
+   int    dnd_types_num;
 };
 
 Etk_Type *etk_widget_type_get();
@@ -263,13 +266,14 @@
 void etk_widget_clip_unset(Etk_Widget *widget);
 Evas_Object *etk_widget_clip_get(Etk_Widget *widget);
 
-void etk_widget_dnd_aware_set(Etk_Widget *widget, Etk_Bool on);
-Etk_Bool etk_widget_dnd_aware_get(Etk_Widget *widget);
-Evas_List *etk_widget_dnd_aware_widgets_get();
+void etk_widget_dnd_dest_set(Etk_Widget *widget, Etk_Bool on);
+Etk_Bool etk_widget_dnd_dest_get(Etk_Widget *widget);
+Evas_List *etk_widget_dnd_dest_widgets_get();
 const char **etk_widget_dnd_files_get(Etk_Widget *e, int *num_files);
 
 void etk_widget_drag_drop(Etk_Widget *widget);
 void etk_widget_drag_motion(Etk_Widget *widget);
+void etk_widget_drag_enter(Etk_Widget *widget);
 void etk_widget_drag_leave(Etk_Widget *widget);
 
 void etk_widget_selection_received(Etk_Widget *widget, 
Etk_Event_Selection_Request *event);




-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to