From c9057ae1c565cc4ae6c2cf84dd19d65a64ee2b7b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 21 Oct 1999 17:47:45 +0000 Subject: [PATCH] OnEnter/OnDragOver API update (compiles, links, somewhat runs under wxGTK) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4113 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/dnd.h | 33 +++++++++++------- include/wx/gtk/dnd.h | 3 +- include/wx/gtk1/dnd.h | 3 +- src/gtk/dnd.cpp | 26 ++++++--------- src/gtk1/dnd.cpp | 26 ++++++--------- src/msw/ole/droptgt.cpp | 74 +++++++++++++++++++++++++++++++++++++---- 6 files changed, 112 insertions(+), 53 deletions(-) diff --git a/include/wx/dnd.h b/include/wx/dnd.h index 3bee4fc7c3..2106b00a4c 100644 --- a/include/wx/dnd.h +++ b/include/wx/dnd.h @@ -97,19 +97,28 @@ public: { if (m_dataObject) delete m_dataObject; m_dataObject = dataObject; } - // called when mouse enters/leaves the window: might be used to give - // some visual feedback to the user - virtual void OnLeave() { } + // these functions are called when data is moved over position (x, y) and + // may return either wxDragCopy, wxDragMove or wxDragNone depending on + // what would happen if the data were dropped here. + // + // the last parameter is what would happen by default and is determined by + // the platform-specific logic (for example, under Windows it's wxDragCopy + // if Ctrl key is pressed and wxDragMove otherwise) except that it will + // always be wxDragNone if the carried data is in an unsupported format. + + // called when the mouse enters the window (only once until OnLeave()) + virtual wxDragResult OnEnter(wxCoord x, wxCoord y, wxDragResult def) + { return OnDragOver(x, y, def); } + + // called when the mouse moves in the window - shouldn't take long to + // execute or otherwise mouse movement would be too slow + virtual wxDragResult OnDragOver(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), + wxDragResult def) + { return def; } - // this function is called when data enters over position (x, y) - if it - // returns TRUE, the dragging icon can indicate that the window would - // accept a drop here - virtual bool OnEnter(wxCoord x, wxCoord y) = 0; - - // this function is called when data is move over position (x, y) - if it - // returns TRUE, the dragging icon can indicate that the window would - // accept a drop here - virtual bool OnMove(wxCoord x, wxCoord y) = 0; + // called when mouse leaves the window: might be used to remove the + // feedback which was given in OnEnter() + virtual void OnLeave() { } // this function is called when data is dropped at position (x, y) - if it // returns TRUE, OnData() will be called immediately afterwards which will diff --git a/include/wx/gtk/dnd.h b/include/wx/gtk/dnd.h index aa45735342..379c0e94ef 100644 --- a/include/wx/gtk/dnd.h +++ b/include/wx/gtk/dnd.h @@ -45,8 +45,7 @@ class wxDropTarget: public wxDropTargetBase public: wxDropTarget(wxDataObject *dataObject = (wxDataObject*) NULL ); - virtual bool OnEnter(wxCoord x, wxCoord y) ; - virtual bool OnMove(wxCoord x, wxCoord y); + virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def); virtual bool OnDrop(wxCoord x, wxCoord y); virtual bool OnData(wxCoord x, wxCoord y); virtual bool GetData(); diff --git a/include/wx/gtk1/dnd.h b/include/wx/gtk1/dnd.h index aa45735342..379c0e94ef 100644 --- a/include/wx/gtk1/dnd.h +++ b/include/wx/gtk1/dnd.h @@ -45,8 +45,7 @@ class wxDropTarget: public wxDropTargetBase public: wxDropTarget(wxDataObject *dataObject = (wxDataObject*) NULL ); - virtual bool OnEnter(wxCoord x, wxCoord y) ; - virtual bool OnMove(wxCoord x, wxCoord y); + virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def); virtual bool OnDrop(wxCoord x, wxCoord y); virtual bool OnData(wxCoord x, wxCoord y); virtual bool GetData(); diff --git a/src/gtk/dnd.cpp b/src/gtk/dnd.cpp index a22731b164..723995103e 100644 --- a/src/gtk/dnd.cpp +++ b/src/gtk/dnd.cpp @@ -188,22 +188,24 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget), this is only valid for the duration of this call */ drop_target->SetDragContext( context ); - bool ret = FALSE; + /* TODO: what should be the default behaviour? Copy or move? */ + wxDragResult result = wxDragMove; if (drop_target->m_firstMotion) { /* the first "drag_motion" event substitutes a "drag_enter" event */ - ret = drop_target->OnEnter( x, y ); + result = drop_target->OnEnter( x, y, result ); } else { /* give program a chance to react (i.e. to say no by returning FALSE) */ - ret = drop_target->OnMove( x, y ); + result = drop_target->OnDragOver( x, y, result ); } /* we don't yet handle which "actions" (i.e. copy or move) the target accepts. so far we simply accept the suggested action. TODO. */ + bool ret = result != wxDragNone; if (ret) gdk_drag_status( context, context->suggested_action, time ); @@ -367,23 +369,17 @@ wxDropTarget::wxDropTarget( wxDataObject *data ) m_dragTime = 0; } -bool wxDropTarget::OnEnter( int WXUNUSED(x), int WXUNUSED(y) ) +wxDragResult wxDropTarget::OnDragOver( wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y), + wxDragResult def ) { if (!m_dataObject) return FALSE; - return (GetMatchingPair() != (GdkAtom) 0); -} - -bool wxDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) ) -{ - if (!m_dataObject) - return FALSE; - - return (GetMatchingPair() != (GdkAtom) 0); + return (GetMatchingPair() != (GdkAtom) 0) ? def : wxDragNone; } -bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) ) +bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) ) { if (!m_dataObject) return FALSE; @@ -391,7 +387,7 @@ bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) ) return (GetMatchingPair() != (GdkAtom) 0); } -bool wxDropTarget::OnData( int WXUNUSED(x), int WXUNUSED(y) ) +bool wxDropTarget::OnData( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) ) { if (!m_dataObject) return FALSE; diff --git a/src/gtk1/dnd.cpp b/src/gtk1/dnd.cpp index a22731b164..723995103e 100644 --- a/src/gtk1/dnd.cpp +++ b/src/gtk1/dnd.cpp @@ -188,22 +188,24 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget), this is only valid for the duration of this call */ drop_target->SetDragContext( context ); - bool ret = FALSE; + /* TODO: what should be the default behaviour? Copy or move? */ + wxDragResult result = wxDragMove; if (drop_target->m_firstMotion) { /* the first "drag_motion" event substitutes a "drag_enter" event */ - ret = drop_target->OnEnter( x, y ); + result = drop_target->OnEnter( x, y, result ); } else { /* give program a chance to react (i.e. to say no by returning FALSE) */ - ret = drop_target->OnMove( x, y ); + result = drop_target->OnDragOver( x, y, result ); } /* we don't yet handle which "actions" (i.e. copy or move) the target accepts. so far we simply accept the suggested action. TODO. */ + bool ret = result != wxDragNone; if (ret) gdk_drag_status( context, context->suggested_action, time ); @@ -367,23 +369,17 @@ wxDropTarget::wxDropTarget( wxDataObject *data ) m_dragTime = 0; } -bool wxDropTarget::OnEnter( int WXUNUSED(x), int WXUNUSED(y) ) +wxDragResult wxDropTarget::OnDragOver( wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y), + wxDragResult def ) { if (!m_dataObject) return FALSE; - return (GetMatchingPair() != (GdkAtom) 0); -} - -bool wxDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) ) -{ - if (!m_dataObject) - return FALSE; - - return (GetMatchingPair() != (GdkAtom) 0); + return (GetMatchingPair() != (GdkAtom) 0) ? def : wxDragNone; } -bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) ) +bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) ) { if (!m_dataObject) return FALSE; @@ -391,7 +387,7 @@ bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) ) return (GetMatchingPair() != (GdkAtom) 0); } -bool wxDropTarget::OnData( int WXUNUSED(x), int WXUNUSED(y) ) +bool wxDropTarget::OnData( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) ) { if (!m_dataObject) return FALSE; diff --git a/src/msw/ole/droptgt.cpp b/src/msw/ole/droptgt.cpp index c9f5feb506..8ef6c9cdee 100644 --- a/src/msw/ole/droptgt.cpp +++ b/src/msw/ole/droptgt.cpp @@ -79,6 +79,13 @@ private: static inline DWORD GetDropEffect(DWORD flags); }; +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +static wxDragResult ConvertDragEffectToResult(DWORD dwEffect); +static DWORD ConvertDragResultToEffect(wxDragResult result); + // ============================================================================ // wxIDropTarget implementation // ============================================================================ @@ -138,16 +145,18 @@ STDMETHODIMP wxIDropTarget::DragEnter(IDataObject *pIDataSource, return S_OK; } - // TODO should check the point also? - - *pdwEffect = GetDropEffect(grfKeyState); - // get hold of the data object m_pIDataObject = pIDataSource; m_pIDataObject->AddRef(); // give some visual feedback - m_pTarget->OnEnter(); + *pdwEffect = ConvertDragResultToEffect( + m_pTarget->OnEnter(pt.x, pt.y, + ConvertDragEffectToResult( + GetDropEffect(grfKeyState) + ) + ) + ); return S_OK; } @@ -167,8 +176,19 @@ STDMETHODIMP wxIDropTarget::DragOver(DWORD grfKeyState, { // there are too many of them... wxLogDebug("IDropTarget::DragOver"); - *pdwEffect = m_pIDataObject == NULL ? DROPEFFECT_NONE - : GetDropEffect(grfKeyState); + wxDragResult result; + if ( m_pIDataObject ) { + result = ConvertDragEffectToResult(GetDropEffect(grfKeyState)); + } + else { + // can't accept data anyhow normally + result = wxDragNone; + } + + *pdwEffect = ConvertDragResultToEffect( + m_pTarget->OnDragOver(pt.x, pt.y, result) + ); + return S_OK; } @@ -435,5 +455,45 @@ bool wxFileDropTarget::OnData(wxCoord x, wxCoord y) ((wxFileDataObject *)m_dataObject)->GetFilenames()); } +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +static wxDragResult ConvertDragEffectToResult(DWORD dwEffect) +{ + switch ( dwEffect ) { + case DROPEFFECT_COPY: + return wxDragCopy; + + case DROPEFFECT_MOVE: + return wxDragMove; + + default: + wxFAIL_MSG(wxT("invalid value in ConvertDragEffectToResult")); + // fall through + + case DROPEFFECT_NONE: + return wxDragNone; + } +} + +static DWORD ConvertDragResultToEffect(wxDragResult result) +{ + switch ( result ) { + case wxDragCopy: + return DROPEFFECT_COPY; + + case wxDragMove: + return DROPEFFECT_MOVE; + + default: + wxFAIL_MSG(wxT("invalid value in ConvertDragResultToEffect")); + // fall through + + case wxDragNone: + return DROPEFFECT_NONE; + } +} + #endif // wxUSE_DRAG_AND_DROP -- 2.45.2