ecore_evas: add API to offset drag position relative to cursor

The values are stored in the ee itself. And it is the responsibility of
the engine to use that value correctly.
This commit is contained in:
Marcel Hollerbach 2022-05-31 21:15:03 +02:00
parent 54c6516373
commit af6134aa6c
6 changed files with 54 additions and 1 deletions

View File

@ -3816,6 +3816,19 @@ typedef void (*Ecore_Evas_Drag_Finished_Cb)(Ecore_Evas *ee, unsigned int seat, v
*/
EAPI Eina_Bool ecore_evas_drag_start(Ecore_Evas *ee, unsigned int seat, Eina_Content *content, Ecore_Evas *drag_rep,
const char* action, Ecore_Evas_Drag_Finished_Cb terminate_cb, void *data);
/**
* @brief Set the offset of the dragged symbol. Only valid during a drag
*
* @param[in] ee The Ecore Evas the drag operation started on.
* @param[in] seat The seat to use
* @param[in] offset The offset to apply to the upper left corner ofthe dragged window
*
* This must be called on the ee where ecore_evas_drag_start is called on, NOT on the drag representation
*
* @since 1.24
*/
EAPI void ecore_evas_drag_offset_set(Ecore_Evas *ee, unsigned int seat, Eina_Size2D offset);
/**
* @brief Cancels an ongoing drag operation.

View File

@ -5645,10 +5645,28 @@ ecore_evas_drag_start(Ecore_Evas *ee, unsigned int seat, Eina_Content *content,
ee->drag.free = terminate_cb;
ee->drag.data = data;
ee->drag.accepted = EINA_FALSE;
ee->drag.offset = EINA_SIZE2D(INT_MAX, INT_MAX);
return success;
}
EAPI void
ecore_evas_drag_offset_set(Ecore_Evas *ee, unsigned int seat, Eina_Size2D offset) {
Ecore_Evas_Selection_Seat_Buffers *buffers;
EINA_SAFETY_ON_NULL_RETURN(ee);
buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN(buffers);
EINA_SAFETY_ON_TRUE_RETURN(buffers->selection_buffer[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER] == NULL);
if (offset.w == INT_MAX || offset.h == INT_MAX)
{
ERR("Offset is INT_MAX, this is a reserved value! Executing Fallback!");
}
INF("Set offset to %d %d", offset.w, offset.h);
ee->drag.offset = offset;
}
EAPI Eina_Bool
ecore_evas_drag_cancel(Ecore_Evas *ee, unsigned int seat)
{

View File

@ -404,6 +404,7 @@ struct _Ecore_Evas
struct
{
Ecore_Evas *rep;
Eina_Size2D offset;
void *data;
Ecore_Evas_Drag_Finished_Cb free;
Eina_Bool accepted;

View File

@ -64,6 +64,12 @@ _efl_ui_dnd_drag_start(Eo *obj, Efl_Ui_Dnd_Data *pd, Eina_Content *content, cons
return drag_win;
}
EOLIAN static void
_efl_ui_dnd_drag_offset_set(Eo *obj EINA_UNUSED, Efl_Ui_Dnd_Data *pd, unsigned int seat, Eina_Size2D size)
{
ecore_evas_drag_offset_set(pd->ee, seat, size);
}
EOLIAN static void
_efl_ui_dnd_drag_cancel(Eo *obj EINA_UNUSED, Efl_Ui_Dnd_Data *pd, unsigned int seat)
{

View File

@ -53,6 +53,17 @@ mixin @beta Efl.Ui.Dnd requires Efl.Object {
of the content being dragged (like a thumbnail, for example).
Use @Efl.Content.content.set on it to do so.]]
}
@property drag_offset {
[[Set the offset during a drag that was initiated through drag_start]]
keys {
seat: uint; [[Seat setting the offset on.]]
}
values {
offset : Eina.Size2D; [[The offset for which the window will be shifted. The upper left of the window is
calculated by adding this offset to the cursor position]]
}
set {}
}
drag_cancel {
[[Cancels an on-going drag operation.]]
params {

View File

@ -776,10 +776,11 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format,
Eina_Array *mime_types;
Eina_Content *content;
Efl_Content *ui;
int x, y, w, h;
int x = 0, y = 0, w, h;
Efl_Ui_Widget *widget;
Elm_Drag_Data *dd;
const char *str_action;
Eina_Position2D pointer;
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
@ -803,6 +804,9 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format,
content = eina_content_new((Eina_Slice) EINA_SLICE_STR_FULL(data), eina_array_data_get(mime_types, 0));
ui = efl_ui_dnd_drag_start(obj, content, str_action, _default_seat(obj));
widget = createicon(createdata, ui, &x, &y);
evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &pointer.x, &pointer.y);
efl_ui_dnd_drag_offset_set(obj, _default_seat(obj), EINA_SIZE2D(x - pointer.x, y - pointer.y));
evas_object_geometry_get(widget, NULL, NULL, &w, &h);
evas_object_show(widget);
efl_content_set(ui, widget);