From 49ce2d56f1e766828970ffb950b1a0669d1a17c5 Mon Sep 17 00:00:00 2001 From: Taehyub Kim Date: Thu, 14 Sep 2023 20:50:55 +0900 Subject: [PATCH] DragAndDrop : Add Window AddListener Change-Id: I32effa0f1ea0f36df0aaf33563b9d16f260f8216 --- dali/devel-api/adaptor-framework/drag-and-drop.cpp | 10 ++ dali/devel-api/adaptor-framework/drag-and-drop.h | 17 +++ .../drag-and-drop/common/drag-and-drop-impl.h | 10 ++ .../generic/drag-and-drop-impl-generic.cpp | 10 ++ .../generic/drag-and-drop-impl-generic.h | 10 ++ .../tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp | 144 ++++++++++++++++++++- .../tizen-wayland/drag-and-drop-impl-ecore-wl2.h | 21 +++ 7 files changed, 221 insertions(+), 1 deletion(-) diff --git a/dali/devel-api/adaptor-framework/drag-and-drop.cpp b/dali/devel-api/adaptor-framework/drag-and-drop.cpp index 707f691..9a7a5b4 100644 --- a/dali/devel-api/adaptor-framework/drag-and-drop.cpp +++ b/dali/devel-api/adaptor-framework/drag-and-drop.cpp @@ -54,4 +54,14 @@ bool DragAndDrop::RemoveListener(Dali::Actor target) return GetImplementation(*this).RemoveListener(target); } +bool DragAndDrop::AddListener(Dali::Window target, DragAndDropFunction callback) +{ + return GetImplementation(*this).AddListener(target, callback); +} + +bool DragAndDrop::RemoveListener(Dali::Window target) +{ + return GetImplementation(*this).RemoveListener(target); +} + } // namespace Dali diff --git a/dali/devel-api/adaptor-framework/drag-and-drop.h b/dali/devel-api/adaptor-framework/drag-and-drop.h index eb2dc89..6e66a33 100644 --- a/dali/devel-api/adaptor-framework/drag-and-drop.h +++ b/dali/devel-api/adaptor-framework/drag-and-drop.h @@ -211,6 +211,23 @@ public: */ bool RemoveListener(Dali::Actor target); + /** + * @brief Add the listener for receiving the drag and drop events. + * + * @param[in] target The drop target object. + * @param[in] callback A drag and drop event callback. + * @return bool true if the listener is added successfully. + */ + bool AddListener(Dali::Window target, DragAndDropFunction callback); + + /** + * @brief Remove the listener. + * + * @param[in] target The drop target object. + * @return bool true if the listener is removed successfully. + */ + bool RemoveListener(Dali::Window target); + public: /** * @brief This constructor is used by Adaptor::GetDragAndDrop(). diff --git a/dali/internal/drag-and-drop/common/drag-and-drop-impl.h b/dali/internal/drag-and-drop/common/drag-and-drop-impl.h index 0a8c679..358beec 100644 --- a/dali/internal/drag-and-drop/common/drag-and-drop-impl.h +++ b/dali/internal/drag-and-drop/common/drag-and-drop-impl.h @@ -63,6 +63,16 @@ public: virtual bool RemoveListener(Dali::Actor target) = 0; /** + * @copydoc Dali::DragAndDrop::AddListener() + */ + virtual bool AddListener(Dali::Window window, Dali::DragAndDrop::DragAndDropFunction callback) = 0; + + /** + * @copydoc Dali::DragAndDrop::RemoveListener() + */ + virtual bool RemoveListener(Dali::Window target) = 0; + + /** * @copydoc Dali::DragAndDrop::SendData() */ virtual void SendData(void* event) = 0; diff --git a/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.cpp b/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.cpp index 18abea7..3eecfdc 100644 --- a/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.cpp +++ b/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.cpp @@ -76,6 +76,16 @@ bool DragAndDropGeneric::RemoveListener(Dali::Actor target) return true; } +bool DragAndDropGeneric::AddListener(Dali::Window target, Dali::DragAndDrop::DragAndDropFunction callback) +{ + return true; +} + +bool DragAndDropGeneric::RemoveListener(Dali::Window target) +{ + return true; +} + void DragAndDropGeneric::SendData(void* event) { return; diff --git a/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.h b/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.h index 434f234..94ac7c8 100644 --- a/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.h +++ b/dali/internal/drag-and-drop/generic/drag-and-drop-impl-generic.h @@ -62,6 +62,16 @@ public: bool RemoveListener(Dali::Actor target) override; /** + * @copydoc Dali::DragAndDrop::AddListener() + */ + bool AddListener(Dali::Window target, Dali::DragAndDrop::DragAndDropFunction callback) override; + + /** + * @copydoc Dali::DragAndDrop::RemoveListener() + */ + bool RemoveListener(Dali::Window target) override; + + /** * @copydoc Dali::DragAndDrop::SendData() */ void SendData(void* event) override; diff --git a/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp b/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp index 43258d2..49c45ff 100644 --- a/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp +++ b/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp @@ -261,6 +261,37 @@ bool DragAndDropEcoreWl::AddListener(Dali::Actor target, Dali::DragAndDrop::Drag return true; } +bool DragAndDropEcoreWl::AddListener(Dali::Window target, Dali::DragAndDrop::DragAndDropFunction callback) +{ + std::vector::iterator itr; + for(itr = mDropWindowTargets.begin(); itr < mDropWindowTargets.end(); itr++) + { + if((*itr).target == target) + { + return false; + } + } + + int windowId = INVALID_ECORE_WL2_WINDOW_ID; + + Ecore_Wl2_Window* window = AnyCast(target.GetNativeHandle()); + if(window == nullptr) + { + return false; + } + windowId = ecore_wl2_window_id_get(window); + + DropWindowTarget targetData; + targetData.target = target; + targetData.callback = callback; + targetData.inside = false; + targetData.windowId = windowId; + + mDropWindowTargets.push_back(targetData); + + return true; +} + bool DragAndDropEcoreWl::RemoveListener(Dali::Actor target) { std::vector::iterator itr; @@ -276,6 +307,21 @@ bool DragAndDropEcoreWl::RemoveListener(Dali::Actor target) return true; } +bool DragAndDropEcoreWl::RemoveListener(Dali::Window target) +{ + std::vector::iterator itr; + for(itr = mDropWindowTargets.begin(); itr < mDropWindowTargets.end(); itr++) + { + if((*itr).target == target) + { + mDropWindowTargets.erase(itr); + break; + } + } + + return true; +} + void DragAndDropEcoreWl::CallSourceEvent(Dali::DragAndDrop::SourceEventType type) { if(mSourceCallback) @@ -302,6 +348,19 @@ void DragAndDropEcoreWl::ResetDropTargets() } mDropTargets[i].inside = false; } + + for(std::size_t i = 0; i < mDropWindowTargets.size(); i++) + { + if(mDropWindowTargets[i].inside) + { + Dali::DragAndDrop::DragEvent dragEvent; + dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE); + Dali::Vector2 position(DEFAULT_POSITION, DEFAULT_POSITION); + dragEvent.SetPosition(position); + mDropWindowTargets[i].callback(dragEvent); + } + mDropWindowTargets[i].inside = false; + } } void DragAndDropEcoreWl::SendData(void* event) @@ -355,9 +414,17 @@ void DragAndDropEcoreWl::ReceiveData(void* event) Dali::DragAndDrop::DragEvent dragEvent(Dali::DragAndDrop::DragType::DROP, mPosition, ev->mimetype, ev->data); mDropTargets[mTargetIndex].callback(dragEvent); mDropTargets[mTargetIndex].inside = false; - ecore_wl2_offer_finish(ev->offer); } mTargetIndex = -1; + + if(mWindowTargetIndex != -1) + { + Dali::DragAndDrop::DragEvent dragEvent(Dali::DragAndDrop::DragType::DROP, mWindowPosition, ev->mimetype, ev->data); + mDropWindowTargets[mWindowTargetIndex].callback(dragEvent); + mDropWindowTargets[mWindowTargetIndex].inside = false; + } + mWindowTargetIndex = -1; + } Vector2 DragAndDropEcoreWl::RecalculatePositionByOrientation(int x, int y, Dali::Window window) @@ -449,6 +516,50 @@ bool DragAndDropEcoreWl::CalculateDragEvent(void* event) } } + for(std::size_t i = 0; i < mDropWindowTargets.size(); i++) + { + if(ev->win != mDropWindowTargets[i].windowId) + { + continue; + } + + // Recalculate Cursor by Orientation + Dali::Window window = mDropWindowTargets[i].target; + Dali::Window::WindowPosition position = window.GetPosition(); + Dali::Window::WindowSize size = window.GetSize(); + + bool currentInside = IsIntersection(ev->x + position.GetX(), ev->y + position.GetY(), position.GetX(), position.GetY(), size.GetWidth(), size.GetHeight()); + + // Calculate Drag Enter, Leave, Move Event + if(currentInside && !mDropWindowTargets[i].inside) + { + mDropWindowTargets[i].inside = true; + // Call Enter Event + dragEvent.SetAction(Dali::DragAndDrop::DragType::ENTER); + dragEvent.SetPosition(curPosition); + mDropWindowTargets[i].callback(dragEvent); + // Accept Offer + ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer)); + } + else if(!currentInside && mDropWindowTargets[i].inside) + { + mDropWindowTargets[i].inside = false; + // Call Leave Event + dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE); + dragEvent.SetPosition(curPosition); + mDropWindowTargets[i].callback(dragEvent); + // Reject Offer + ecore_wl2_offer_accept(ev->offer, NULL); + } + else if(currentInside && mDropWindowTargets[i].inside) + { + // Call Move Event + dragEvent.SetAction(Dali::DragAndDrop::DragType::MOVE); + dragEvent.SetPosition(curPosition); + mDropWindowTargets[i].callback(dragEvent); + } + } + return true; } @@ -458,6 +569,7 @@ bool DragAndDropEcoreWl::CalculateViewRegion(void* event) // Check the target object region mTargetIndex = -1; + mWindowTargetIndex = -1; for(std::size_t i = 0; i < mDropTargets.size(); i++) { @@ -492,6 +604,36 @@ bool DragAndDropEcoreWl::CalculateViewRegion(void* event) } } + for(std::size_t i = 0; i < mDropWindowTargets.size(); i++) + { + if(ev->win != mDropWindowTargets[i].windowId) + { + continue; + } + + // Recalculate Cursor by Orientation + Dali::Window window = mDropWindowTargets[i].target; + Dali::Window::WindowPosition position = window.GetPosition(); + Dali::Window::WindowSize size = window.GetSize(); + + // If the drop position is in the target object region, request drop data to the source object + if(IsIntersection(ev->x + position.GetX(), ev->y + position.GetY(), position.GetX(), position.GetY(), size.GetWidth(), size.GetHeight())) + { + mWindowTargetIndex = i; + mWindowPosition = Dali::Vector2(position.GetX(), position.GetY()); + + char* mimetype = (char*)eina_array_data_get(ecore_wl2_offer_mimes_get(ev->offer), 0); + if(mimetype) + { + ecore_wl2_offer_receive(ev->offer, mimetype); + Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL); + Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display); + ecore_wl2_display_flush(ecore_wl2_input_display_get(input)); + } + return true; + } + } + return false; } diff --git a/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.h b/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.h index 18a0f7b..acb1699 100644 --- a/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.h +++ b/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.h @@ -38,6 +38,14 @@ struct DropTarget int parentWindowId; }; +struct DropWindowTarget +{ + Dali::Window target; + Dali::DragAndDrop::DragAndDropFunction callback; + bool inside; + int windowId; +}; + /** * DragAndDrop Implementation */ @@ -66,11 +74,21 @@ public: bool AddListener(Dali::Actor target, Dali::DragAndDrop::DragAndDropFunction callback) override; /** + * @copydoc Dali::DragAndDrop::AddListener() + */ + bool AddListener(Dali::Window target, Dali::DragAndDrop::DragAndDropFunction callback) override; + + /** * @copydoc Dali::DragAndDrop::RemoveListener() */ bool RemoveListener(Dali::Actor target) override; /** + * @copydoc Dali::DragAndDrop::RemoveListener() + */ + bool RemoveListener(Dali::Window target) override; + + /** * @copydoc Dali::DragAndDrop::SendData() */ void SendData(void* event) override; @@ -135,12 +153,15 @@ private: Ecore_Event_Handler* mEnterHandler{nullptr}; Ecore_Event_Handler* mLeaveHandler{nullptr}; int mTargetIndex{0}; + int mWindowTargetIndex{0}; std::string mMimeType; std::string mData; int mDataSize{0}; Dali::Vector2 mPosition; + Dali::Vector2 mWindowPosition; Dali::DragAndDrop::SourceFunction mSourceCallback{nullptr}; std::vector mDropTargets; + std::vector mDropWindowTargets; }; // class DragAndDropEcoreWl } // namespace Adaptor -- 2.7.4