#include <wx/wxprec.h>
#include <wx/wx.h>
#include "../include/wxdragon.h"
#include <wx/dnd.h>
#include <wx/tokenzr.h>
class WxdTextDropTargetFull : public wxTextDropTarget {
public:
WxdTextDropTargetFull(wxd_OnEnter_Callback onEnter, wxd_OnDragOver_Callback onDragOver,
wxd_OnLeave_Callback onLeave, wxd_OnDrop_Callback onDrop,
wxd_OnData_Callback onData, wxd_OnDropText_Callback onDropText,
void* userData, wxd_FreeUserData_Callback freeUserData)
: m_onEnter(onEnter), m_onDragOver(onDragOver), m_onLeave(onLeave), m_onDrop(onDrop),
m_onData(onData), m_onDropText(onDropText), m_userData(userData),
m_freeUserData(freeUserData)
{
WXD_LOG_TRACE("WxdTextDropTargetFull created");
}
virtual ~WxdTextDropTargetFull()
{
WXD_LOG_TRACE("WxdTextDropTargetFull destroyed");
if (m_userData && m_freeUserData) {
m_freeUserData(m_userData);
m_userData = nullptr;
}
}
virtual wxDragResult
OnEnter(wxCoord x, wxCoord y, wxDragResult defResult) override
{
if (m_onEnter) {
wxd_DragResult result =
m_onEnter(x, y, static_cast<wxd_DragResult>(defResult), m_userData);
return static_cast<wxDragResult>(result);
}
return wxTextDropTarget::OnEnter(x, y, defResult);
}
virtual wxDragResult
OnDragOver(wxCoord x, wxCoord y, wxDragResult defResult) override
{
if (m_onDragOver) {
wxd_DragResult result =
m_onDragOver(x, y, static_cast<wxd_DragResult>(defResult), m_userData);
return static_cast<wxDragResult>(result);
}
return wxTextDropTarget::OnDragOver(x, y, defResult);
}
virtual void
OnLeave() override
{
if (m_onLeave) {
m_onLeave(m_userData);
}
else {
wxTextDropTarget::OnLeave();
}
}
virtual bool
OnDrop(wxCoord x, wxCoord y) override
{
if (m_onDrop) {
return m_onDrop(x, y, m_userData);
}
return wxTextDropTarget::OnDrop(x, y);
}
virtual wxDragResult
OnData(wxCoord x, wxCoord y, wxDragResult defResult) override
{
wxDragResult baseResult = wxTextDropTarget::OnData(x, y, defResult);
if (baseResult != wxDragNone && m_onData) {
wxd_DragResult result =
m_onData(x, y, static_cast<wxd_DragResult>(defResult), m_userData);
return static_cast<wxDragResult>(result);
}
return baseResult;
}
virtual bool
OnDropText(wxCoord x, wxCoord y, const wxString& text) override
{
if (m_onDropText) {
wxScopedCharBuffer utf8 = text.utf8_str();
return m_onDropText(utf8.data(), x, y, m_userData);
}
return false;
}
private:
wxd_OnEnter_Callback m_onEnter;
wxd_OnDragOver_Callback m_onDragOver;
wxd_OnLeave_Callback m_onLeave;
wxd_OnDrop_Callback m_onDrop;
wxd_OnData_Callback m_onData;
wxd_OnDropText_Callback m_onDropText;
void* m_userData;
wxd_FreeUserData_Callback m_freeUserData;
};
class WxdFileDropTargetFull : public wxFileDropTarget {
public:
WxdFileDropTargetFull(wxd_OnEnter_Callback onEnter, wxd_OnDragOver_Callback onDragOver,
wxd_OnLeave_Callback onLeave, wxd_OnDrop_Callback onDrop,
wxd_OnData_Callback onData, wxd_OnDropFiles_Callback onDropFiles,
void* userData, wxd_FreeUserData_Callback freeUserData)
: m_onEnter(onEnter), m_onDragOver(onDragOver), m_onLeave(onLeave), m_onDrop(onDrop),
m_onData(onData), m_onDropFiles(onDropFiles), m_userData(userData),
m_freeUserData(freeUserData)
{
WXD_LOG_TRACE("WxdFileDropTargetFull created");
}
virtual ~WxdFileDropTargetFull()
{
WXD_LOG_TRACE("WxdFileDropTargetFull destroyed");
if (m_userData && m_freeUserData) {
m_freeUserData(m_userData);
m_userData = nullptr;
}
}
virtual wxDragResult
OnEnter(wxCoord x, wxCoord y, wxDragResult defResult) override
{
if (m_onEnter) {
wxd_DragResult result =
m_onEnter(x, y, static_cast<wxd_DragResult>(defResult), m_userData);
return static_cast<wxDragResult>(result);
}
return wxFileDropTarget::OnEnter(x, y, defResult);
}
virtual wxDragResult
OnDragOver(wxCoord x, wxCoord y, wxDragResult defResult) override
{
if (m_onDragOver) {
wxd_DragResult result =
m_onDragOver(x, y, static_cast<wxd_DragResult>(defResult), m_userData);
return static_cast<wxDragResult>(result);
}
return wxFileDropTarget::OnDragOver(x, y, defResult);
}
virtual void
OnLeave() override
{
if (m_onLeave) {
m_onLeave(m_userData);
}
else {
wxFileDropTarget::OnLeave();
}
}
virtual bool
OnDrop(wxCoord x, wxCoord y) override
{
if (m_onDrop) {
return m_onDrop(x, y, m_userData);
}
return wxFileDropTarget::OnDrop(x, y);
}
virtual wxDragResult
OnData(wxCoord x, wxCoord y, wxDragResult defResult) override
{
wxDragResult baseResult = wxFileDropTarget::OnData(x, y, defResult);
if (baseResult != wxDragNone && m_onData) {
wxd_DragResult result =
m_onData(x, y, static_cast<wxd_DragResult>(defResult), m_userData);
return static_cast<wxDragResult>(result);
}
return baseResult;
}
virtual bool
OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) override
{
if (m_onDropFiles) {
return m_onDropFiles(reinterpret_cast<const wxd_ArrayString_t*>(&filenames), x, y,
m_userData);
}
return false;
}
private:
wxd_OnEnter_Callback m_onEnter;
wxd_OnDragOver_Callback m_onDragOver;
wxd_OnLeave_Callback m_onLeave;
wxd_OnDrop_Callback m_onDrop;
wxd_OnData_Callback m_onData;
wxd_OnDropFiles_Callback m_onDropFiles;
void* m_userData;
wxd_FreeUserData_Callback m_freeUserData;
};
extern "C" {
WXD_EXPORTED wxd_TextDropTarget_t*
wxd_TextDropTarget_CreateFull(wxd_Window_t* window, wxd_OnEnter_Callback onEnter,
wxd_OnDragOver_Callback onDragOver, wxd_OnLeave_Callback onLeave,
wxd_OnDrop_Callback onDrop, wxd_OnData_Callback onData,
wxd_OnDropText_Callback onDropText, void* userData,
wxd_FreeUserData_Callback freeUserData)
{
if (!window)
return nullptr;
wxWindow* wx_window = reinterpret_cast<wxWindow*>(window);
WxdTextDropTargetFull* drop_target = new WxdTextDropTargetFull(onEnter, onDragOver, onLeave,
onDrop, onData, onDropText,
userData, freeUserData);
wx_window->SetDropTarget(drop_target);
return reinterpret_cast<wxd_TextDropTarget_t*>(drop_target);
}
WXD_EXPORTED wxd_FileDropTarget_t*
wxd_FileDropTarget_CreateFull(wxd_Window_t* window, wxd_OnEnter_Callback onEnter,
wxd_OnDragOver_Callback onDragOver, wxd_OnLeave_Callback onLeave,
wxd_OnDrop_Callback onDrop, wxd_OnData_Callback onData,
wxd_OnDropFiles_Callback onDropFiles, void* userData,
wxd_FreeUserData_Callback freeUserData)
{
if (!window)
return nullptr;
wxWindow* wx_window = reinterpret_cast<wxWindow*>(window);
WxdFileDropTargetFull* drop_target = new WxdFileDropTargetFull(onEnter, onDragOver, onLeave,
onDrop, onData, onDropFiles,
userData, freeUserData);
wx_window->SetDropTarget(drop_target);
return reinterpret_cast<wxd_FileDropTarget_t*>(drop_target);
}
}