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