Enlightenment CVS committal Author : ningerso Project : e17 Module : libs/ewl
Dir : e17/libs/ewl/src/lib Modified Files: ewl_dnd.c ewl_embed.c ewl_embed.h ewl_window.h ewl_widget.c Log Message: Move DND awareness to embed rather than the window. Improve type negotiation on target widgets. Auto-detect when flagging windows for DND awareness is necessary. =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_dnd.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -3 -r1.23 -r1.24 --- ewl_dnd.c 8 Sep 2006 01:05:17 -0000 1.23 +++ ewl_dnd.c 8 Sep 2006 07:12:43 -0000 1.24 @@ -34,6 +34,7 @@ char *ewl_dnd_drop_types[] = { "text/uri-list", "text/plain", NULL }; static char *ewl_dnd_types_encode(const char **types); +static char * ewl_dnd_type_stpcpy(char *dst, const char *src); static int ewl_dnd_types_encoded_contains(char *types, char *type); static int ewl_dnd_event_mouse_up(void *data, int type, void *event); @@ -134,7 +135,17 @@ type = ecore_hash_get(ewl_dnd_provided_hash, w); IF_FREE(type); - ecore_hash_set(ewl_dnd_provided_hash, w, ewl_dnd_types_encode(types)); + if (types && *types) { + type = ewl_dnd_types_encode(types); + ecore_hash_set(ewl_dnd_provided_hash, w, type); + ewl_object_flags_add(EWL_OBJECT(w), EWL_FLAG_PROPERTY_DRAGGABLE, + EWL_FLAGS_PROPERTY_MASK); + } + else { + ewl_object_flags_remove(EWL_OBJECT(w), + EWL_FLAG_PROPERTY_DRAGGABLE, + EWL_FLAGS_PROPERTY_MASK); + } DLEAVE_FUNCTION(DLEVEL_STABLE); } @@ -195,10 +206,32 @@ DCHECK_PARAM_PTR("w", w); DCHECK_TYPE("w", w, EWL_WIDGET_TYPE); - type = ecore_hash_get(ewl_dnd_accepted_hash, w); + type = ecore_hash_remove(ewl_dnd_accepted_hash, w); IF_FREE(type); - ecore_hash_set(ewl_dnd_accepted_hash, w, ewl_dnd_types_encode(types)); + if (types && *types) { + type = ewl_dnd_types_encode(types); + ecore_hash_set(ewl_dnd_accepted_hash, w, type); + ewl_object_flags_add(EWL_OBJECT(w), EWL_FLAG_PROPERTY_DND_AWARE, + EWL_FLAGS_PROPERTY_MASK); + if (REALIZED(w) && !OBSCURED(w)) { + Ewl_Embed *emb; + + emb = ewl_embed_widget_find(w); + ewl_embed_dnd_aware_set(emb); + } + } + else { + ewl_object_flags_remove(EWL_OBJECT(w), + EWL_FLAG_PROPERTY_DND_AWARE, + EWL_FLAGS_PROPERTY_MASK); + if (REALIZED(w) && !OBSCURED(w)) { + Ewl_Embed *emb; + + emb = ewl_embed_widget_find(w); + ewl_embed_dnd_aware_remove(emb); + } + } DLEAVE_FUNCTION(DLEVEL_STABLE); } @@ -267,8 +300,8 @@ parent = parent->parent; /* Now check if this obj we found is a window */ - if (parent && ewl_widget_type_is(parent, "window")) - DRETURN_PTR(&(EWL_WINDOW(parent)->dnd_types), DLEVEL_STABLE); + if (parent && ewl_widget_type_is(parent, "embed")) + DRETURN_PTR(&(EWL_EMBED(parent)->dnd_types), DLEVEL_STABLE); DRETURN_PTR(NULL, DLEVEL_STABLE); } @@ -474,7 +507,7 @@ type = tmptype = NEW(char, len + 1); count = i; for (i = 0; i < count; i++) { - tmptype = stpcpy(tmptype, types[i]); + tmptype = ewl_dnd_type_stpcpy(tmptype, types[i]); tmptype++; } *tmptype = '\0'; @@ -482,6 +515,19 @@ DRETURN_PTR(type, DLEVEL_STABLE); } +static char * +ewl_dnd_type_stpcpy(char *dst, const char *src) +{ + while (*src) { + *dst = *src; + dst++; + src++; + } + *dst = '\0'; + + return dst; +} + static int ewl_dnd_event_dnd_move(void *data __UNUSED__, int type __UNUSED__, void *event) @@ -531,7 +577,7 @@ pos = ecore_hash_keys(ewl_dnd_position_hash); ecore_list_goto_first(pos); while ((val = ecore_list_remove_first(pos))) { - EWL_WINDOW(val)->dnd_last_position = NULL; + EWL_EMBED(val)->dnd_last_position = NULL; ecore_hash_remove(ewl_dnd_position_hash, val); } ecore_list_destroy(pos); =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_embed.c,v retrieving revision 1.78 retrieving revision 1.79 diff -u -3 -r1.78 -r1.79 --- ewl_embed.c 8 Sep 2006 01:05:17 -0000 1.78 +++ ewl_embed.c 8 Sep 2006 07:12:43 -0000 1.79 @@ -671,12 +671,12 @@ embed->last.mouse_in = widget; - if (embed->dnd_widget && ewl_object_state_has(EWL_OBJECT(embed->dnd_widget), + if (embed->last.drag_widget && ewl_object_state_has(EWL_OBJECT(embed->last.drag_widget), EWL_FLAG_STATE_DND)) - ewl_callback_call_with_event_data(embed->dnd_widget, + ewl_callback_call_with_event_data(embed->last.drag_widget, EWL_CALLBACK_MOUSE_MOVE, &ev); else - embed->dnd_widget = NULL; + embed->last.drag_widget = NULL; if (embed->last.clicked && ewl_object_state_has(EWL_OBJECT(embed->last.clicked), EWL_FLAG_STATE_PRESSED)) @@ -694,53 +694,70 @@ * @return Returns no value. * @brief Sends the event for a DND drop into an embed. */ -void +const char * ewl_embed_dnd_drop_feed(Ewl_Embed *embed, int x, int y, int internal) { Ewl_Widget *widget = NULL; - Ewl_Event_Dnd_Drop ev; - void *drop_data = NULL; + const char *result = NULL; DENTER_FUNCTION(DLEVEL_STABLE); - DCHECK_PARAM_PTR("embed", embed); - DCHECK_TYPE("embed", embed, EWL_EMBED_TYPE); + DCHECK_PARAM_PTR_RET("embed", embed, FALSE); + DCHECK_TYPE_RET("embed", embed, EWL_EMBED_TYPE, FALSE); ewl_embed_active_set(embed, TRUE); - ev.x = x; - ev.y = y; - widget = ewl_container_child_at_recursive_get(EWL_CONTAINER(embed), x, y); if (widget) { + int i; Ewl_Widget *parent; - - embed->dnd_widget = widget; - if (internal) { - Ewl_Widget_Drag cb; - - /* Retrieve the callback for this widget's data */ - cb = (Ewl_Widget_Drag)ewl_widget_data_get(widget, "DROP_CB"); - if (cb) { - drop_data = (*cb)(); - ev.data = drop_data; + /* Request a DND data request */ + for (i = 0; i < embed->dnd_types.num_types; i++) { + if (ewl_dnd_accepted_types_contains(widget, embed->dnd_types.types[i])) { + result = embed->dnd_types.types[i]; + break; } - } else { - /* Handle external drops */ - ev.data = NULL; } - parent = widget; - while (parent) { - ewl_callback_call_with_event_data(parent, - EWL_CALLBACK_DND_DROP, &ev); - parent = parent->parent; + + if (result) { + Ewl_Event_Dnd_Drop ev; + + ev.x = x; + ev.y = y; + + if (internal) { + Ewl_Widget_Drag cb; + + /* Retrieve the callback for widget's data */ + /* FIXME: We shouldn't use widget data like + * this, and there needs to be a data request / + * send protocol with widgets anyways */ + cb = (Ewl_Widget_Drag)ewl_widget_data_get(widget, "DROP_CB"); + if (cb) { + void *drop_data; + drop_data = (*cb)(); + ev.data = drop_data; + } + } else { + /* Handle external drops */ + ev.data = NULL; + } + + + embed->last.drag_widget = widget; + parent = widget; + while (parent) { + ewl_callback_call_with_event_data(parent, + EWL_CALLBACK_DND_DROP, &ev); + parent = parent->parent; + } } ewl_dnd_drag_widget_clear(); } - DLEAVE_FUNCTION(DLEVEL_STABLE); + DRETURN_PTR(result, DLEVEL_STABLE); } /** @@ -772,17 +789,13 @@ widget = ewl_container_child_at_recursive_get(EWL_CONTAINER(embed), x, y); if (widget) { Ewl_Widget *parent; - Ewl_Window *window; - - /* First see if we need to send an 'enter' to this widget */ - window = ewl_window_window_find(embed->evas_window); /* If the last position event was over a different widget, * feed the leaving widget a 'null' */ - if (window->dnd_last_position != widget) { - if (window->dnd_last_position) { + if (embed->dnd_last_position != widget) { + if (embed->dnd_last_position) { - parent = window->dnd_last_position; + parent = embed->dnd_last_position; while (parent) { ewl_callback_call_with_event_data(parent, EWL_CALLBACK_DND_LEAVE, &ev); @@ -809,8 +822,9 @@ parent = parent->parent; } - ewl_dnd_position_windows_set(EWL_WIDGET(window)); - window->dnd_last_position = widget; + embed->last.drop_widget = widget; + ewl_dnd_position_windows_set(EWL_WIDGET(embed)); + embed->dnd_last_position = widget; *px = CURRENT_X(widget); *py = CURRENT_Y(widget); @@ -921,15 +935,15 @@ /* * If a widget is expecting DND data, send the data to the widget */ - if (embed->dnd_widget) { - if (ewl_dnd_accepted_types_contains(embed->dnd_widget, type)) { + if (embed->last.drop_widget) { + if (ewl_dnd_accepted_types_contains(embed->last.drop_widget, type)) { /* * setup the event struct */ ev.type = type; ev.data = data; ev.len = len; - ewl_callback_call_with_event_data(embed->dnd_widget, + ewl_callback_call_with_event_data(embed->last.drop_widget, EWL_CALLBACK_DND_DATA, &ev); } @@ -1432,10 +1446,15 @@ && ewl_widget_parent_of(w, e->last.mouse_in))) e->last.mouse_in = NULL; - if ((w == e->dnd_widget) + if ((w == e->last.drop_widget) + || (RECURSIVE(w) + && ewl_widget_parent_of(w, e->last.drop_widget))) + e->last.drop_widget = NULL; + + if ((w == e->last.drag_widget) || (RECURSIVE(w) - && ewl_widget_parent_of(w, e->dnd_widget))) - e->dnd_widget = NULL; + && ewl_widget_parent_of(w, e->last.drag_widget))) + e->last.drag_widget = NULL; DLEAVE_FUNCTION(DLEVEL_STABLE); } @@ -1646,6 +1665,9 @@ emb); } + if (emb->dnd_count) + ewl_engine_embed_dnd_aware_set(emb); + DLEAVE_FUNCTION(DLEVEL_STABLE); } @@ -1833,7 +1855,29 @@ DCHECK_PARAM_PTR("embed", embed); DCHECK_TYPE("embed", embed, EWL_EMBED_TYPE); - ewl_engine_embed_dnd_aware_set(embed); + if (REALIZED(embed) && (embed->dnd_count == 0)) + ewl_engine_embed_dnd_aware_set(embed); + embed->dnd_count++; + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +/** + * @param embed: the embed to remove dnd aware + * @return Returns no value. + * @brief Cancels an embed as being DND aware + */ +void +ewl_embed_dnd_aware_remove(Ewl_Embed *embed) +{ + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("embed", embed); + DCHECK_TYPE("embed", embed, EWL_EMBED_TYPE); + + /* FIXME: Need to remove the XdndAware property on refcount == 0 + if (REALIZED(embed) && (embed->dnd_count == 0)) + ewl_engine_embed_dnd_aware_set(embed); */ + embed->dnd_count--; DLEAVE_FUNCTION(DLEVEL_STABLE); } =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_embed.h,v retrieving revision 1.24 retrieving revision 1.25 diff -u -3 -r1.24 -r1.25 --- ewl_embed.h 8 Sep 2006 01:05:17 -0000 1.24 +++ ewl_embed.h 8 Sep 2006 07:12:43 -0000 1.25 @@ -62,19 +62,23 @@ Ecore_Hash *obj_cache; /**< Hash of object queues for reuse */ - int focus; /**< Indicates if it receives focus */ - struct { Ewl_Widget *clicked; /**< Last clicked widget */ Ewl_Widget *focused; /**< Last focused widget */ Ewl_Widget *mouse_in; /**< Last widget to receive a mouse_in */ + Ewl_Widget *drop_widget; /**< The current DND drop target */ + Ewl_Widget *drag_widget; /**< The current DND drag source */ } last; /**< Collection of widgets to last receive events */ int x; /**< Screen relative horizontal position of window */ int y; /**< Screen relative vertical position of window */ - Ewl_Widget *dnd_widget; /**< The current DND widget */ + int dnd_count; /**< DND aware widget count */ + int focus; /**< Indicates if it receives focus */ + + Ewl_Dnd_Types dnd_types; /**< The dnd type */ + Ewl_Widget *dnd_last_position; /**< The last dnd position */ }; Ewl_Widget *ewl_embed_new(void); @@ -101,7 +105,7 @@ unsigned int modifiers); void ewl_embed_dnd_position_feed(Ewl_Embed *embed, int x, int y,int*,int*,int*,int*); -void ewl_embed_dnd_drop_feed(Ewl_Embed* embed, int x, int y, int internal); +const char *ewl_embed_dnd_drop_feed(Ewl_Embed* embed, int x, int y, int internal); void ewl_embed_dnd_data_feed(Ewl_Embed* embed, void *data, unsigned int len); void ewl_embed_selection_data_feed(Ewl_Embed *embed, char *type, void *data, unsigned int len); @@ -142,6 +146,7 @@ void ewl_embed_thaw(Ewl_Embed *e); void ewl_embed_dnd_aware_set(Ewl_Embed *embed); +void ewl_embed_dnd_aware_remove(Ewl_Embed *embed); /* * Internally used callbacks, override at your own risk. =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_window.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -3 -r1.21 -r1.22 --- ewl_window.h 8 Sep 2006 01:05:17 -0000 1.21 +++ ewl_window.h 8 Sep 2006 07:12:43 -0000 1.22 @@ -48,9 +48,6 @@ char *classname; /**< Current class on the provided window */ Ewl_Window_Flags flags; /**< Flags indicating window properties */ - - Ewl_Dnd_Types dnd_types; /**< The dnd type */ - Ewl_Widget *dnd_last_position; /**< The last dnd position */ }; Ewl_Widget *ewl_window_new(void); =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_widget.c,v retrieving revision 1.98 retrieving revision 1.99 diff -u -3 -r1.98 -r1.99 --- ewl_widget.c 5 Sep 2006 02:14:24 -0000 1.98 +++ ewl_widget.c 8 Sep 2006 07:12:43 -0000 1.99 @@ -2213,6 +2213,13 @@ DRETURN(DLEVEL_STABLE); /* + * Increment the dnd awareness counter on the embed. + */ + if (ewl_object_flags_has(EWL_OBJECT(w), EWL_FLAG_PROPERTY_DND_AWARE, + EWL_FLAGS_PROPERTY_MASK)) + ewl_embed_dnd_aware_set(emb); + + /* * Smart Object allocation */ if (!w->smart_object) { @@ -2379,6 +2386,13 @@ DRETURN(DLEVEL_STABLE); pc = EWL_CONTAINER(w->parent); + + /* + * Decrement the dnd awareness counter on the embed. + */ + if (ewl_object_flags_has(EWL_OBJECT(w), EWL_FLAG_PROPERTY_DND_AWARE, + EWL_FLAGS_PROPERTY_MASK)) + ewl_embed_dnd_aware_remove(emb); /* * Remove all properties on the edje and hand it back to the embed for ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs