return Internal::Adaptor::GetDragAndDrop();
}
-bool DragAndDrop::StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const DragData& dragData)
+bool DragAndDrop::StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const DragData& dragData, Dali::DragAndDrop::SourceFunction callback)
{
- return GetImplementation(*this).StartDragAndDrop(source, shadow, dragData);
+ return GetImplementation(*this).StartDragAndDrop(source, shadowWindow, dragData, callback);
}
bool DragAndDrop::AddListener(Dali::Actor target, DragAndDropFunction callback)
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/window.h>
#include <dali/public-api/actors/actor.h>
#include <dali/public-api/math/rect.h>
#include <dali/public-api/object/base-handle.h>
{
public:
/**
+ * @brief Enumeration for the drag source event type in the source object
+ */
+ enum class SourceEventType
+ {
+ START, ///< Drag and drop is started.
+ CANCEL, ///< Drag and drop is cancelled.
+ ACCEPT, ///< Drag and drop is accepted.
+ FINISH ///< Drag and drop is finished.
+ };
+
+ /**
* @brief Enumeration for the drag event type in the target object
*/
enum class DragType
};
using DragAndDropFunction = std::function<void(const DragEvent&)>;
+ using SourceFunction = std::function<void(enum SourceEventType)>;
/**
* @brief Create an uninitialized DragAndDrop.
* @brief Start the drag operation.
*
* @param[in] source The drag source object.
- * @param[in] shadow The shadow object for drag object.
+ * @param[in] shadowWindow The shadow window for drag object.
* @param[in] dragData The data to send to target object.
+ * @param[in] callback The drag source event callback.
* @return bool true if the drag operation is started successfully.
*/
- bool StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const DragData& dragData);
+ bool StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const DragData& dragData, Dali::DragAndDrop::SourceFunction callback);
/**
* @brief Add the listener for receiving the drag and drop events.
// INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/accessibility.h>
#include <dali/devel-api/atspi-interfaces/accessible.h>
+#include <dali/devel-api/atspi-interfaces/component.h>
namespace Dali::Accessibility
{
*
* To be used as a proxy object, in those situations where you want to return an address in
* a different bridge (embedding for example), but the object itself isn't planned to be used
- * otherwise. This object has no parent, no children, an empty name and so on.
+ * otherwise. This object has a settable parent, no children, an empty name and so on.
*/
-class DALI_ADAPTOR_API ProxyAccessible : public virtual Accessible
+class DALI_ADAPTOR_API ProxyAccessible : public virtual Accessible, public virtual Component
{
public:
- ProxyAccessible() = default;
-
- ProxyAccessible(Address address)
- : mAddress(std::move(address))
+ ProxyAccessible()
+ : mAddress{},
+ mParent{nullptr}
{
}
void SetAddress(Address address)
{
- this->mAddress = std::move(address);
+ mAddress = std::move(address);
+ }
+
+ void SetParent(Accessible* parent)
+ {
+ mParent = parent;
}
std::string GetName() const override
Accessible* GetParent() override
{
- return nullptr;
+ return mParent;
}
size_t GetChildCount() const override
return {};
}
+ bool IsProxy() const override
+ {
+ return true;
+ }
+
Address GetAddress() const override
{
return mAddress;
return Dali::Actor{};
}
+ Rect<> GetExtents(CoordinateType type) const override
+ {
+ auto* parent = Component::DownCast(mParent);
+
+ return parent ? parent->GetExtents(type) : Rect<>{};
+ }
+
+ ComponentLayer GetLayer() const override
+ {
+ return ComponentLayer::WINDOW;
+ }
+
+ int16_t GetMdiZOrder() const override
+ {
+ return false;
+ }
+
+ bool GrabFocus() override
+ {
+ return false;
+ }
+
+ double GetAlpha() const override
+ {
+ return 0.0;
+ }
+
+ bool GrabHighlight() override
+ {
+ return false;
+ }
+
+ bool ClearHighlight() override
+ {
+ return false;
+ }
+
+ bool IsScrollable() const override
+ {
+ return false;
+ }
+
private:
- Address mAddress;
+ Address mAddress;
+ Accessible* mParent;
};
} // namespace Dali::Accessibility
/**
* @copydoc Dali::DragAndDrop::StartDragAndDrop()
*/
- virtual bool StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const Dali::DragAndDrop::DragData& data) = 0;
+ virtual bool StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const Dali::DragAndDrop::DragData& data, Dali::DragAndDrop::SourceFunction callback) = 0;
/**
* @copydoc Dali::DragAndDrop::AddListener()
{
}
-bool DragAndDropGeneric::StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const Dali::DragAndDrop::DragData& dragData)
+bool DragAndDropGeneric::StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const Dali::DragAndDrop::DragData& dragData, Dali::DragAndDrop::SourceFunction callback)
{
return true;
}
/**
* @copydoc Dali::DragAndDrop::StartDragAndDrop()
*/
- bool StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const Dali::DragAndDrop::DragData& data) override;
+ bool StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const Dali::DragAndDrop::DragData& data, Dali::DragAndDrop::SourceFunction callback) override;
/**
* @copydoc Dali::DragAndDrop::AddListener()
return ECORE_CALLBACK_PASS_ON;
}
+static Eina_Bool EcoreEventDataSourceEnd(void* data, int type, void* event)
+{
+ Ecore_Wl2_Event_Data_Source_End *ev = reinterpret_cast<Ecore_Wl2_Event_Data_Source_End*>(event);
+ DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
+ if(ev->cancelled)
+ {
+ dndImpl->CallSourceEvent(Dali::DragAndDrop::SourceEventType::CANCEL);
+ }
+ else
+ {
+ dndImpl->CallSourceEvent(Dali::DragAndDrop::SourceEventType::ACCEPT);
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool EcoreEventDataSourceDrop(void* data, int type, void* event)
+{
+ DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
+ dndImpl->CallSourceEvent(Dali::DragAndDrop::SourceEventType::FINISH);
+ return ECORE_CALLBACK_PASS_ON;
+}
+
static Eina_Bool EcoreEventOfferDataReady(void* data, int type, void* event)
{
DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
return ECORE_CALLBACK_PASS_ON;
}
+static Eina_Bool EcoreEventDataEnter(void* data, int type, void* event)
+{
+ Ecore_Wl2_Event_Dnd_Enter* ev = reinterpret_cast<Ecore_Wl2_Event_Dnd_Enter*>(event);
+
+ // Set default offer is reject
+ ecore_wl2_offer_accept(ev->offer, NULL);
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
Dali::DragAndDrop GetDragAndDrop()
{
Dali::DragAndDrop dnd;
DragAndDropEcoreWl::DragAndDropEcoreWl()
{
- mSendHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, this);
- mReceiveHandler = ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, EcoreEventOfferDataReady, this);
- mMotionHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION, EcoreEventDataMotion, this);
- mDropHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP, EcoreEventDataDrop, this);
+ // Source Events
+ mSendHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, this);
+ mSourceEndHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_END, EcoreEventDataSourceEnd, this);
+ mSourceDropHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_DROP, EcoreEventDataSourceDrop, this);
+
+ // Target Events
+ mReceiveHandler = ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, EcoreEventOfferDataReady, this);
+ mMotionHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION, EcoreEventDataMotion, this);
+ mDropHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP, EcoreEventDataDrop, this);
+ mEnterHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_ENTER, EcoreEventDataEnter, this);
}
DragAndDropEcoreWl::~DragAndDropEcoreWl()
{
+ // Source Events
ecore_event_handler_del(mSendHandler);
+ ecore_event_handler_del(mSourceEndHandler);
+ ecore_event_handler_del(mSourceDropHandler);
+
+ // Target Events
ecore_event_handler_del(mReceiveHandler);
ecore_event_handler_del(mMotionHandler);
ecore_event_handler_del(mDropHandler);
+ ecore_event_handler_del(mEnterHandler);
}
-bool DragAndDropEcoreWl::StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const Dali::DragAndDrop::DragData& data)
+bool DragAndDropEcoreWl::StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const Dali::DragAndDrop::DragData& data, Dali::DragAndDrop::SourceFunction callback)
{
// Get Parent Window
auto parent = Dali::DevelWindow::Get(source);
mMimeType = data.GetMimeType();
mData = data.GetData();
- // Apply Shadow Property
- shadow.SetProperty(Dali::Actor::Property::SIZE, Vector2(150, 150));
- shadow.SetProperty(Dali::Actor::Property::OPACITY, 0.9f);
+ // Set Source Event
+ mSourceCallback = callback;
- // Create Drag Window
- mDragWindow = Dali::Window::New(Dali::PositionSize(0, 0, 150, 150), "DragWindow", "class", true);
- mDragWindow.SetTransparency(true);
- mDragWindow.SetSize(Dali::Window::WindowSize(150, 150));
- mDragWindow.SetBackgroundColor(Color::TRANSPARENT);
- mDragWindow.Add(shadow);
+ // Set Drag Window
+ mDragWindow = shadowWindow;
// Start Drag and Drop
Ecore_Wl2_Window* parentWindow = AnyCast<Ecore_Wl2_Window*>(parent.GetNativeHandle());
// Start wayland drag and drop
mSerial = ecore_wl2_dnd_drag_start(input, parentWindow, dragWindow);
+ // Call Start Event
+ CallSourceEvent(Dali::DragAndDrop::SourceEventType::START);
+
return true;
}
return true;
}
+void DragAndDropEcoreWl::CallSourceEvent(Dali::DragAndDrop::SourceEventType type)
+{
+ if(mSourceCallback)
+ {
+ mSourceCallback(type);
+ }
+}
+
void DragAndDropEcoreWl::SendData(void* event)
{
Ecore_Wl2_Event_Data_Source_Send* ev = reinterpret_cast<Ecore_Wl2_Event_Data_Source_Send*>(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;
}
dragEvent.SetAction(Dali::DragAndDrop::DragType::ENTER);
dragEvent.SetPosition(curPosition);
mDropTargets[i].callback(dragEvent);
+ // Accept Offer
+ ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer));
}
else if(!currentInside && mDropTargets[i].inside)
{
dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE);
dragEvent.SetPosition(curPosition);
mDropTargets[i].callback(dragEvent);
+ // Reject Offer
+ ecore_wl2_offer_accept(ev->offer, NULL);
}
else if(currentInside && mDropTargets[i].inside)
{
char* mimetype = (char*)eina_array_data_get(ecore_wl2_offer_mimes_get(ev->offer), 0);
if(mimetype)
{
- ecore_wl2_offer_accept(ev->offer, 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);
/**
* @copydoc Dali::DragAndDrop::StartDragAndDrop()
*/
- bool StartDragAndDrop(Dali::Actor source, Dali::Actor shadow, const Dali::DragAndDrop::DragData& data) override;
+ bool StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const Dali::DragAndDrop::DragData& data, Dali::DragAndDrop::SourceFunction callback) override;
/**
* @copydoc Dali::DragAndDrop::AddListener()
*/
bool CalculateViewRegion(void* event) override;
+ /**
+ * @brief Call drag source events.
+ */
+ void CallSourceEvent(Dali::DragAndDrop::SourceEventType type);
+
private:
DragAndDropEcoreWl(const DragAndDropEcoreWl&) = delete;
DragAndDropEcoreWl& operator=(DragAndDropEcoreWl&) = delete;
DragAndDropEcoreWl& operator=(DragAndDropEcoreWl&&) = delete;
private:
- Dali::Window mDragWindow;
- uint32_t mSerial{0u};
- Ecore_Event_Handler* mSendHandler{nullptr};
- Ecore_Event_Handler* mReceiveHandler{nullptr};
- Ecore_Event_Handler* mMotionHandler{nullptr};
- Ecore_Event_Handler* mDropHandler{nullptr};
- int mTargetIndex{0};
- std::string mMimeType;
- std::string mData;
- int mDataSize{0};
- Dali::Vector2 mPosition;
+ Dali::Window mDragWindow;
+ uint32_t mSerial{0u};
+ Ecore_Event_Handler* mSendHandler{nullptr};
+ Ecore_Event_Handler* mSourceEndHandler{nullptr};
+ Ecore_Event_Handler* mSourceDropHandler{nullptr};
+ Ecore_Event_Handler* mReceiveHandler{nullptr};
+ Ecore_Event_Handler* mMotionHandler{nullptr};
+ Ecore_Event_Handler* mDropHandler{nullptr};
+ Ecore_Event_Handler* mEnterHandler{nullptr};
+ int mTargetIndex{0};
+ std::string mMimeType;
+ std::string mData;
+ int mDataSize{0};
+ Dali::Vector2 mPosition;
+ Dali::DragAndDrop::SourceFunction mSourceCallback{nullptr};
std::vector<DropTarget> mDropTargets;
}; // class DragAndDropEcoreWl
// mFrameCount will be 1 if the input image is non-animated image or animated image with single frame.
if(DALI_LIKELY(ReadWebPInformation()))
{
+#ifdef DALI_WEBP_AVAILABLE
+ WebPDataInit(&mWebPData);
+ mWebPData.size = mBufferSize;
+ mWebPData.bytes = mBuffer;
+
+ WebPDemuxer* demuxer = WebPDemux(&mWebPData);
+ uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS);
+ if(flags & ANIMATION_FLAG)
+ {
+ mIsAnimatedImage = true;
+ }
+
+ if(!mIsAnimatedImage)
+ {
+ int32_t imageWidth, imageHeight;
+ if(WebPGetInfo(mBuffer, mBufferSize, &imageWidth, &imageHeight))
+ {
+ mImageSize = ImageDimensions(imageWidth, imageHeight);
+ }
+ }
+#endif
#ifdef DALI_ANIMATED_WEBP_ENABLED
if(mIsAnimatedImage)
{
- WebPDataInit(&mWebPData);
- mWebPData.size = mBufferSize;
- mWebPData.bytes = mBuffer;
WebPAnimDecoderOptions webPAnimDecoderOptions;
WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions);
webPAnimDecoderOptions.color_mode = MODE_RGBA;
mImageSize = ImageDimensions(mWebPAnimInfo.canvas_width, mWebPAnimInfo.canvas_height);
}
#endif
-#ifdef DALI_WEBP_AVAILABLE
- if(!mIsAnimatedImage)
- {
- int32_t imageWidth, imageHeight;
- if(WebPGetInfo(mBuffer, mBufferSize, &imageWidth, &imageHeight))
- {
- mImageSize = ImageDimensions(imageWidth, imageHeight);
- }
- }
-#endif
mLoadSucceeded = true;
}
else
}
}
- fp = fileReader->GetFile();
+ if(fileReader)
+ {
+ fp = fileReader->GetFile();
+ }
}
if(DALI_LIKELY(fp != nullptr))
{
- if(DALI_LIKELY(!fseek(fp, 12, SEEK_SET)))
- {
- uint8_t mHeaderBuffer[5];
- fread(mHeaderBuffer, sizeof(WebPByteType), 5, fp);
- unsigned char VP8X[4] = {'V', 'P', '8', 'X'};
- bool isExtended = true;
- for(uint32_t i = 0; i < 4; ++i)
- {
- if(mHeaderBuffer[i] != VP8X[i])
- {
- isExtended = false;
- break;
- }
- }
- if(isExtended)
- {
- unsigned char extension = mHeaderBuffer[4];
- mIsAnimatedImage = ((extension >> 1) & 1) ? true : false;
- }
- }
-
if(mBufferSize == 0)
{
if(DALI_UNLIKELY(fseek(fp, 0, SEEK_END) <= -1))
void ReleaseResource()
{
+#ifdef DALI_WEBP_AVAILABLE
+ if(&mWebPData != nullptr)
+ {
+ mWebPData.bytes = nullptr;
+ WebPDataInit(&mWebPData);
+ }
+#endif
#ifdef DALI_ANIMATED_WEBP_ENABLED
if(mIsAnimatedImage)
{
- if(&mWebPData != nullptr)
- {
- mWebPData.bytes = nullptr;
- WebPDataInit(&mWebPData);
- }
if(mWebPAnimDecoder != nullptr)
{
WebPAnimDecoderDelete(mWebPAnimDecoder);
bool mIsAnimatedImage;
bool mIsLocalResource;
-#ifdef DALI_ANIMATED_WEBP_ENABLED
+#ifdef DALI_WEBP_AVAILABLE
WebPData mWebPData{0};
+#endif
+
+#ifdef DALI_ANIMATED_WEBP_ENABLED
WebPAnimDecoder* mWebPAnimDecoder{nullptr};
WebPAnimInfo mWebPAnimInfo{0};
Dali::Devel::PixelBuffer mPreLoadedFrame{};
DALI_LOG_WARNING("Unable to read to UpdateEvent File descriptor\n");
}
+ // Save value to prevent duplicate deletion
+ TriggerEventInterface::Options options = mOptions;
+
// Call the connected callback
CallbackBase::Execute(*mCallback);
//check if we should delete ourselves after the trigger
- if(mOptions == TriggerEventInterface::DELETE_AFTER_TRIGGER)
+ if(options == TriggerEventInterface::DELETE_AFTER_TRIGGER)
{
delete this;
}
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 1;
-const unsigned int ADAPTOR_MICRO_VERSION = 18;
+const unsigned int ADAPTOR_MICRO_VERSION = 19;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.1.18
+Version: 2.1.19
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT