Commit 1653a66d authored by Erwan Tulou's avatar Erwan Tulou

skins2: drap&drop enhancement

Pass drap&drop coordinates over to visual controls.
This feature will be used to allow users to finely insert items in the
playtree control instead of just appending them at the end.
parent 48884d48
...@@ -82,6 +82,7 @@ SOURCES_skins2 = \ ...@@ -82,6 +82,7 @@ SOURCES_skins2 = \
events/evt_special.hpp \ events/evt_special.hpp \
events/evt_scroll.cpp \ events/evt_scroll.cpp \
events/evt_scroll.hpp \ events/evt_scroll.hpp \
events/evt_dragndrop.hpp \
\ \
parser/builder.cpp \ parser/builder.cpp \
parser/builder.hpp \ parser/builder.hpp \
......
/*****************************************************************************
* evt_dragndrop.hpp
*****************************************************************************
* Copyright (C) 2011 the VideoLAN team
* $Id$
*
* Author: Erwan Tulou <erwan10 At videolan Dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef EVT_DRAGNDROP_HPP
#define EVT_DRAGNDROP_HPP
#include "evt_generic.hpp"
#include <list>
/// Drag'n'Drop generic event
class EvtDrag: public EvtGeneric
{
public:
EvtDrag( intf_thread_t *pIntf ): EvtGeneric( pIntf ) { }
virtual ~EvtDrag() { }
virtual const string getAsString() const { return "drag"; }
};
class EvtDragEnter: public EvtDrag
{
public:
EvtDragEnter( intf_thread_t *pIntf ): EvtDrag( pIntf ) { }
virtual ~EvtDragEnter() { }
virtual const string getAsString() const { return "drag:enter"; }
};
class EvtDragLeave: public EvtDrag
{
public:
EvtDragLeave( intf_thread_t *pIntf ): EvtDrag( pIntf ) { }
virtual ~EvtDragLeave() { }
virtual const string getAsString() const { return "drag:leave"; }
};
class EvtDragOver: public EvtDrag
{
public:
EvtDragOver( intf_thread_t *pIntf, int x, int y )
: EvtDrag( pIntf ), m_xPos( x ), m_yPos( y ) { }
virtual ~EvtDragOver() { }
virtual const string getAsString() const { return "drag:over"; }
// Return the event coordinates
int getXPos() const { return m_xPos; }
int getYPos() const { return m_yPos; }
private:
int m_xPos;
int m_yPos;
};
class EvtDragDrop: public EvtDrag
{
public:
EvtDragDrop( intf_thread_t *pIntf, int x, int y, const list<string>& files )
: EvtDrag( pIntf ), m_files( files ), m_xPos( x ), m_yPos( y ) { }
virtual ~EvtDragDrop() { }
virtual const string getAsString() const { return "drag:drop"; }
// Return the event coordinates
int getXPos() const { return m_xPos; }
int getYPos() const { return m_yPos; }
const list<string>& getFiles() const { return m_files; }
private:
list<string> m_files;
int m_xPos;
int m_yPos;
};
#endif
...@@ -38,6 +38,10 @@ class EvtMouse; ...@@ -38,6 +38,10 @@ class EvtMouse;
class EvtKey; class EvtKey;
class EvtRefresh; class EvtRefresh;
class EvtScroll; class EvtScroll;
class EvtDragEnter;
class EvtDragLeave;
class EvtDragOver;
class EvtDragDrop;
class WindowManager; class WindowManager;
...@@ -73,6 +77,15 @@ public: ...@@ -73,6 +77,15 @@ public:
virtual void processEvent( EvtKey &rEvtKey ) { (void)rEvtKey; } virtual void processEvent( EvtKey &rEvtKey ) { (void)rEvtKey; }
virtual void processEvent( EvtScroll &rEvtScroll ) { (void)rEvtScroll; } virtual void processEvent( EvtScroll &rEvtScroll ) { (void)rEvtScroll; }
virtual void processEvent( EvtDragEnter &rEvtDragEnter )
{ (void)rEvtDragEnter; }
virtual void processEvent( EvtDragLeave &rEvtDragLeave )
{ (void)rEvtDragLeave; }
virtual void processEvent( EvtDragOver &rEvtDragOver )
{ (void)rEvtDragOver; }
virtual void processEvent( EvtDragDrop &rEvtDragDrop )
{ (void)rEvtDragDrop; }
virtual void processEvent( EvtRefresh &rEvtRefresh ); virtual void processEvent( EvtRefresh &rEvtRefresh );
/// Resize the window /// Resize the window
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "var_manager.hpp" #include "var_manager.hpp"
#include "../commands/cmd_on_top.hpp" #include "../commands/cmd_on_top.hpp"
#include "../commands/cmd_dialogs.hpp" #include "../commands/cmd_dialogs.hpp"
#include "../commands/cmd_add_item.hpp"
#include "../controls/ctrl_generic.hpp" #include "../controls/ctrl_generic.hpp"
#include "../events/evt_refresh.hpp" #include "../events/evt_refresh.hpp"
#include "../events/evt_enter.hpp" #include "../events/evt_enter.hpp"
...@@ -42,10 +43,12 @@ ...@@ -42,10 +43,12 @@
#include "../events/evt_key.hpp" #include "../events/evt_key.hpp"
#include "../events/evt_special.hpp" #include "../events/evt_special.hpp"
#include "../events/evt_scroll.hpp" #include "../events/evt_scroll.hpp"
#include "../events/evt_dragndrop.hpp"
#include "../utils/position.hpp" #include "../utils/position.hpp"
#include "../utils/ustring.hpp" #include "../utils/ustring.hpp"
#include <vlc_keys.h> #include <vlc_keys.h>
#include <list>
TopWindow::TopWindow( intf_thread_t *pIntf, int left, int top, TopWindow::TopWindow( intf_thread_t *pIntf, int left, int top,
...@@ -53,9 +56,11 @@ TopWindow::TopWindow( intf_thread_t *pIntf, int left, int top, ...@@ -53,9 +56,11 @@ TopWindow::TopWindow( intf_thread_t *pIntf, int left, int top,
bool dragDrop, bool playOnDrop, bool visible, bool dragDrop, bool playOnDrop, bool visible,
GenericWindow::WindowType_t type ): GenericWindow::WindowType_t type ):
GenericWindow( pIntf, left, top, dragDrop, playOnDrop, NULL, type ), GenericWindow( pIntf, left, top, dragDrop, playOnDrop, NULL, type ),
m_initialVisibility( visible ), m_rWindowManager( rWindowManager ), m_initialVisibility( visible ), m_playOnDrop( playOnDrop ),
m_rWindowManager( rWindowManager ),
m_pActiveLayout( NULL ), m_pLastHitControl( NULL ), m_pActiveLayout( NULL ), m_pLastHitControl( NULL ),
m_pCapturingControl( NULL ), m_pFocusControl( NULL ), m_currModifier( 0 ) m_pCapturingControl( NULL ), m_pFocusControl( NULL ),
m_pDragControl( NULL ), m_currModifier( 0 )
{ {
// Register as a moving window // Register as a moving window
m_rWindowManager.registerWindow( *this ); m_rWindowManager.registerWindow( *this );
...@@ -264,6 +269,66 @@ void TopWindow::processEvent( EvtScroll &rEvtScroll ) ...@@ -264,6 +269,66 @@ void TopWindow::processEvent( EvtScroll &rEvtScroll )
} }
} }
void TopWindow::processEvent( EvtDragDrop &rEvtDragDrop )
{
// Get the control hit by the mouse
int xPos = rEvtDragDrop.getXPos() - getLeft();
int yPos = rEvtDragDrop.getYPos() - getTop();
CtrlGeneric *pHitControl = findHitControl( xPos, yPos );
if( pHitControl && pHitControl->getType() == "tree" )
{
// Send a dragDrop event
EvtDragDrop evt( getIntf(), xPos, yPos, rEvtDragDrop.getFiles() );
pHitControl->handleEvent( evt );
}
else
{
list<string> files = rEvtDragDrop.getFiles();
list<string>::const_iterator it = files.begin();
for( bool first = true; it != files.end(); ++it, first = false )
{
bool playOnDrop = m_playOnDrop && first;
CmdAddItem( getIntf(), it->c_str(), playOnDrop ).execute();
}
}
m_pDragControl = NULL;
}
void TopWindow::processEvent( EvtDragOver &rEvtDragOver )
{
// Get the control hit by the mouse
int xPos = rEvtDragOver.getXPos() - getLeft();
int yPos = rEvtDragOver.getYPos() - getTop();
CtrlGeneric *pHitControl = findHitControl( xPos, yPos );
if( m_pDragControl && m_pDragControl != pHitControl )
{
EvtDragLeave evt( getIntf() );
m_pDragControl->handleEvent( evt );
}
m_pDragControl = pHitControl;
if( m_pDragControl )
{
// Send a dragOver event
EvtDragOver evt( getIntf(), xPos, yPos );
m_pDragControl->handleEvent( evt );
}
}
void TopWindow::processEvent( EvtDragLeave &rEvtDragLeave )
{
(void)rEvtDragLeave;
if( m_pDragControl )
{
EvtDragLeave evt( getIntf() );
m_pDragControl->handleEvent( evt );
m_pDragControl = NULL;
}
}
void TopWindow::forwardEvent( EvtGeneric &rEvt, CtrlGeneric &rCtrl ) void TopWindow::forwardEvent( EvtGeneric &rEvt, CtrlGeneric &rCtrl )
{ {
......
...@@ -56,6 +56,9 @@ public: ...@@ -56,6 +56,9 @@ public:
virtual void processEvent( EvtLeave &rEvtLeave ); virtual void processEvent( EvtLeave &rEvtLeave );
virtual void processEvent( EvtKey &rEvtKey ); virtual void processEvent( EvtKey &rEvtKey );
virtual void processEvent( EvtScroll &rEvtScroll ); virtual void processEvent( EvtScroll &rEvtScroll );
virtual void processEvent( EvtDragDrop &rEvtDragDrop );
virtual void processEvent( EvtDragOver &rEvtDragOver );
virtual void processEvent( EvtDragLeave &rEvtDragLeave );
/// Forward an event to a control /// Forward an event to a control
virtual void forwardEvent( EvtGeneric &rEvt, CtrlGeneric &rCtrl ); virtual void forwardEvent( EvtGeneric &rEvt, CtrlGeneric &rCtrl );
...@@ -102,6 +105,8 @@ private: ...@@ -102,6 +105,8 @@ private:
/// Initial visibility status /// Initial visibility status
bool m_initialVisibility; bool m_initialVisibility;
/// indicator if playback is requested on drag&drop
bool m_playOnDrop;
/// Window manager /// Window manager
WindowManager &m_rWindowManager; WindowManager &m_rWindowManager;
/// Current active layout of the window /// Current active layout of the window
...@@ -112,6 +117,8 @@ private: ...@@ -112,6 +117,8 @@ private:
CtrlGeneric *m_pCapturingControl; CtrlGeneric *m_pCapturingControl;
/// Control that has the focus /// Control that has the focus
CtrlGeneric *m_pFocusControl; CtrlGeneric *m_pFocusControl;
/// Control over which drag&drop is hovering
CtrlGeneric *m_pDragControl;
/// Current key modifier (also used for mouse) /// Current key modifier (also used for mouse)
int m_currModifier; int m_currModifier;
......
...@@ -27,11 +27,14 @@ ...@@ -27,11 +27,14 @@
#include <windows.h> #include <windows.h>
#include "win32_dragdrop.hpp" #include "win32_dragdrop.hpp"
#include "../commands/cmd_add_item.hpp" #include "../commands/cmd_add_item.hpp"
#include "../events/evt_dragndrop.hpp"
#include <list>
Win32DragDrop::Win32DragDrop( intf_thread_t *pIntf, bool playOnDrop ): Win32DragDrop::Win32DragDrop( intf_thread_t *pIntf,
SkinObject( pIntf ), IDropTarget(), m_references( 1 ), bool playOnDrop, GenericWindow* pWin )
m_playOnDrop( playOnDrop ) : SkinObject( pIntf ), IDropTarget(), m_references( 1 ),
m_playOnDrop( playOnDrop ), m_pWin( pWin)
{ {
} }
...@@ -89,6 +92,10 @@ STDMETHODIMP Win32DragDrop::DragEnter( LPDATAOBJECT pDataObj, ...@@ -89,6 +92,10 @@ STDMETHODIMP Win32DragDrop::DragEnter( LPDATAOBJECT pDataObj,
*pdwEffect = DROPEFFECT_NONE; *pdwEffect = DROPEFFECT_NONE;
} }
// transmit DragEnter event
EvtDragEnter evt( getIntf() );
m_pWin->processEvent( evt );
return S_OK; return S_OK;
} }
...@@ -96,13 +103,20 @@ STDMETHODIMP Win32DragDrop::DragEnter( LPDATAOBJECT pDataObj, ...@@ -96,13 +103,20 @@ STDMETHODIMP Win32DragDrop::DragEnter( LPDATAOBJECT pDataObj,
STDMETHODIMP Win32DragDrop::DragOver( DWORD grfKeyState, POINTL pt, STDMETHODIMP Win32DragDrop::DragOver( DWORD grfKeyState, POINTL pt,
DWORD *pdwEffect ) DWORD *pdwEffect )
{ {
// For visual feedback // transmit DragOver event
EvtDragOver evt( getIntf(), pt.x, pt.y );
m_pWin->processEvent( evt );
return S_OK; return S_OK;
} }
STDMETHODIMP Win32DragDrop::DragLeave() STDMETHODIMP Win32DragDrop::DragLeave()
{ {
// transmit DragLeave event
EvtDragLeave evt( getIntf() );
m_pWin->processEvent( evt );
// Remove visual feedback // Remove visual feedback
return S_OK; return S_OK;
} }
...@@ -129,7 +143,7 @@ STDMETHODIMP Win32DragDrop::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState, ...@@ -129,7 +143,7 @@ STDMETHODIMP Win32DragDrop::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState,
HDROP HDrop = (HDROP)GlobalLock( HFiles ); HDROP HDrop = (HDROP)GlobalLock( HFiles );
// Notify VLC of the drop // Notify VLC of the drop
HandleDrop( HDrop ); HandleDrop( HDrop, pt.x, pt.y );
// Release the pointer to the memory // Release the pointer to the memory
GlobalUnlock( HFiles ); GlobalUnlock( HFiles );
...@@ -144,12 +158,13 @@ STDMETHODIMP Win32DragDrop::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState, ...@@ -144,12 +158,13 @@ STDMETHODIMP Win32DragDrop::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState,
} }
void Win32DragDrop::HandleDrop( HDROP HDrop ) void Win32DragDrop::HandleDrop( HDROP HDrop, int x, int y )
{ {
list<string> files;
// Get the number of dropped files // Get the number of dropped files
int nbFiles = DragQueryFileW( HDrop, 0xFFFFFFFF, NULL, 0 ); int nbFiles = DragQueryFileW( HDrop, 0xFFFFFFFF, NULL, 0 );
// For each dropped file
for( int i = 0; i < nbFiles; i++ ) for( int i = 0; i < nbFiles; i++ )
{ {
// Get the name of the file // Get the name of the file
...@@ -157,14 +172,15 @@ void Win32DragDrop::HandleDrop( HDROP HDrop ) ...@@ -157,14 +172,15 @@ void Win32DragDrop::HandleDrop( HDROP HDrop )
wchar_t *psz_fileName = new WCHAR[nameLength]; wchar_t *psz_fileName = new WCHAR[nameLength];
DragQueryFileW( HDrop, i, psz_fileName, nameLength ); DragQueryFileW( HDrop, i, psz_fileName, nameLength );
// Add the file files.push_back( sFromWide(psz_fileName) );
CmdAddItem cmd(getIntf(),sFromWide(psz_fileName),m_playOnDrop);
cmd.execute();
delete[] psz_fileName; delete[] psz_fileName;
} }
DragFinish( HDrop ); DragFinish( HDrop );
// transmit DragDrop event
EvtDragDrop evt( getIntf(), x, y, files );
m_pWin->processEvent( evt );
} }
......
...@@ -28,12 +28,13 @@ ...@@ -28,12 +28,13 @@
#include <shellapi.h> #include <shellapi.h>
#include <ole2.h> #include <ole2.h>
#include "../src/skin_common.hpp" #include "../src/skin_common.hpp"
#include "../src/generic_window.hpp"
class Win32DragDrop: public SkinObject, public IDropTarget class Win32DragDrop: public SkinObject, public IDropTarget
{ {
public: public:
Win32DragDrop( intf_thread_t *pIntf, bool playOnDrop ); Win32DragDrop( intf_thread_t *pIntf, bool playOnDrop, GenericWindow* pWin );
virtual ~Win32DragDrop() { } virtual ~Win32DragDrop() { }
protected: protected:
...@@ -55,9 +56,11 @@ private: ...@@ -55,9 +56,11 @@ private:
unsigned long m_references; unsigned long m_references;
/// Indicates whether the file(s) must be played immediately /// Indicates whether the file(s) must be played immediately
bool m_playOnDrop; bool m_playOnDrop;
///
GenericWindow* m_pWin;
/// Helper function /// Helper function
void HandleDrop( HDROP HDrop ); void HandleDrop( HDROP HDrop, int x, int y );
}; };
......
...@@ -118,8 +118,8 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow, ...@@ -118,8 +118,8 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
// Drag & drop // Drag & drop
if( m_dragDrop ) if( m_dragDrop )
{ {
m_pDropTarget = (LPDROPTARGET) new Win32DragDrop( getIntf(), m_pDropTarget = (LPDROPTARGET)
playOnDrop ); new Win32DragDrop( getIntf(), playOnDrop, &rWindow );
// Register the window as a drop target // Register the window as a drop target
RegisterDragDrop( m_hWnd, m_pDropTarget ); RegisterDragDrop( m_hWnd, m_pDropTarget );
} }
......
...@@ -31,15 +31,16 @@ ...@@ -31,15 +31,16 @@
#include "x11_display.hpp" #include "x11_display.hpp"
#include "x11_factory.hpp" #include "x11_factory.hpp"
#include "../commands/cmd_add_item.hpp" #include "../commands/cmd_add_item.hpp"
#include "../events/evt_dragndrop.hpp"
#include <string> #include <string>
#include <list> #include <list>
X11DragDrop::X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay, X11DragDrop::X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay,
Window win, bool playOnDrop ): Window win, bool playOnDrop, GenericWindow *pWin ):
SkinObject( pIntf ), m_rDisplay( rDisplay ), m_wnd( win ), SkinObject( pIntf ), m_rDisplay( rDisplay ), m_wnd( win ),
m_playOnDrop( playOnDrop ) m_playOnDrop( playOnDrop ), m_pWin( pWin ), m_xPos( -1 ), m_yPos( -1 )
{ {
} }
...@@ -47,6 +48,7 @@ X11DragDrop::X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay, ...@@ -47,6 +48,7 @@ X11DragDrop::X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay,
void X11DragDrop::dndEnter( ldata_t data ) void X11DragDrop::dndEnter( ldata_t data )
{ {
Window src = data[0]; Window src = data[0];
m_xPos = m_yPos = -1;
// Retrieve available data types // Retrieve available data types
list<string> dataTypes; list<string> dataTypes;
...@@ -84,22 +86,31 @@ void X11DragDrop::dndEnter( ldata_t data ) ...@@ -84,22 +86,31 @@ void X11DragDrop::dndEnter( ldata_t data )
list<string>::iterator it; list<string>::iterator it;
for( it = dataTypes.begin(); it != dataTypes.end(); ++it ) for( it = dataTypes.begin(); it != dataTypes.end(); ++it )
{ {
if( *it == "text/plain" || *it == "STRING" ) if( *it == "text/uri-list" ||
*it == "text/plain" ||
*it == "STRING" )
{ {
m_target = XInternAtom( XDISPLAY, (*it).c_str(), 0 ); m_target = XInternAtom( XDISPLAY, (*it).c_str(), 0 );
break; break;
} }
} }
// transmit DragEnter event
EvtDragEnter evt( getIntf() );
m_pWin->processEvent( evt );
} }
void X11DragDrop::dndPosition( ldata_t data ) void X11DragDrop::dndPosition( ldata_t data )
{ {
Window src = data[0]; Window src = data[0];
Time time = data[2]; //Time time = data[3];
m_xPos = data[2] >> 16;
m_yPos = data[2] & 0xffff;
Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 ); Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 );
Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 ); //Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 );
Atom targetAtom = XInternAtom( XDISPLAY, "text/uri-list", 0 );
Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 ); Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 );
Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 ); Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
...@@ -108,7 +119,7 @@ void X11DragDrop::dndPosition( ldata_t data ) ...@@ -108,7 +119,7 @@ void X11DragDrop::dndPosition( ldata_t data )
// Convert the selection into the given target // Convert the selection into the given target
// NEEDED or it doesn't work! // NEEDED or it doesn't work!
XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src, XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src,
time ); CurrentTime );
actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 ); actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
typeAtom = XInternAtom( XDISPLAY, "XdndStatus", 0 ); typeAtom = XInternAtom( XDISPLAY, "XdndStatus", 0 );
...@@ -122,31 +133,37 @@ void X11DragDrop::dndPosition( ldata_t data ) ...@@ -122,31 +133,37 @@ void X11DragDrop::dndPosition( ldata_t data )
event.xclient.data.l[0] = m_wnd; event.xclient.data.l[0] = m_wnd;
// Accept the drop (1), or not (0). // Accept the drop (1), or not (0).
event.xclient.data.l[1] = m_target != None ? 1 : 0; event.xclient.data.l[1] = m_target != None ? 1 : 0;
OSFactory *pOsFactory = X11Factory::instance( getIntf() );
int w = pOsFactory->getScreenWidth();
int h = pOsFactory->getScreenHeight();
event.xclient.data.l[2] = 0; event.xclient.data.l[2] = 0;
event.xclient.data.l[3] = (w << 16) | h; event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = actionAtom; event.xclient.data.l[4] = actionAtom;
// Tell the source whether we accept the drop // Tell the source whether we accept the drop
XSendEvent( XDISPLAY, src, False, 0, &event ); XSendEvent( XDISPLAY, src, False, 0, &event );
// transmit DragOver event
EvtDragOver evt( getIntf(), m_xPos, m_yPos );
m_pWin->processEvent( evt );
} }
void X11DragDrop::dndLeave( ldata_t data ) void X11DragDrop::dndLeave( ldata_t data )
{ {
(void)data; (void)data;
// transmit DragLeave event
EvtDragLeave evt( getIntf() );
m_pWin->processEvent( evt );
} }
void X11DragDrop::dndDrop( ldata_t data ) void X11DragDrop::dndDrop( ldata_t data )
{ {
list<string> files;
Window src = data[0]; Window src = data[0];
Time time = data[2]; Time time = data[2];
Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 ); Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 );
Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 ); Atom targetAtom = XInternAtom( XDISPLAY, "text/uri-list", 0 );
Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 ); Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 );
Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 ); Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
...@@ -164,12 +181,10 @@ void X11DragDrop::dndDrop( ldata_t data ) ...@@ -164,12 +181,10 @@ void X11DragDrop::dndDrop( ldata_t data )
XGetWindowProperty( XDISPLAY, src, propAtom, 0, 1024, False, XGetWindowProperty( XDISPLAY, src, propAtom, 0, 1024, False,
AnyPropertyType, &type, &format, &nitems, &nbytes, AnyPropertyType, &type, &format, &nitems, &nbytes,
(unsigned char**)&buffer ); (unsigned char**)&buffer );
if( buffer != NULL ) if( buffer != NULL )
{ {
char* psz_dup = strdup( buffer ); char* psz_dup = strdup( buffer );
char* psz_new = psz_dup; char* psz_new = psz_dup;
bool first = true;
while( psz_new && *psz_new ) while( psz_new && *psz_new )
{ {
int skip = 0; int skip = 0;
...@@ -185,9 +200,7 @@ void X11DragDrop::dndDrop( ldata_t data ) ...@@ -185,9 +200,7 @@ void X11DragDrop::dndDrop( ldata_t data )
} }
if( *psz_new ) if( *psz_new )
{ {
bool playOnDrop = m_playOnDrop && first; files.push_back( psz_new );
CmdAddItem( getIntf(), psz_new, playOnDrop ).execute();
first = false;
} }
psz_new += strlen( psz_new ) + skip; psz_new += strlen( psz_new ) + skip;
...@@ -207,6 +220,10 @@ void X11DragDrop::dndDrop( ldata_t data ) ...@@ -207,6 +220,10 @@ void X11DragDrop::dndDrop( ldata_t data )
event.xclient.data.l[1] = 1; // drop accepted event.xclient.data.l[1] = 1; // drop accepted
event.xclient.data.l[2] = actionAtom; event.xclient.data.l[2] = actionAtom;
XSendEvent( XDISPLAY, src, False, 0, &event ); XSendEvent( XDISPLAY, src, False, 0, &event );
// transmit DragDrop event
EvtDragDrop evt( getIntf(), m_xPos, m_yPos, files );
m_pWin->processEvent( evt );
} }
#endif #endif
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include "../src/skin_common.hpp" #include "../src/skin_common.hpp"
#include "../src/generic_window.hpp"
class X11Display; class X11Display;
...@@ -37,7 +38,7 @@ public: ...@@ -37,7 +38,7 @@ public:
typedef long ldata_t[5]; typedef long ldata_t[5];
X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay, Window win, X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay, Window win,
bool playOnDrop ); bool playOnDrop, GenericWindow *pWin );
virtual ~X11DragDrop() { } virtual ~X11DragDrop() { }
void dndEnter( ldata_t data ); void dndEnter( ldata_t data );
...@@ -54,6 +55,11 @@ private: ...@@ -54,6 +55,11 @@ private:
bool m_playOnDrop; bool m_playOnDrop;
/// Target type /// Target type
Atom m_target; Atom m_target;
/// Generic Window
GenericWindow *m_pWin;
/// (x,y) mouse coordinates
int m_xPos;
int m_yPos;
}; };
......
...@@ -41,7 +41,7 @@ X11Window::X11Window( intf_thread_t *pIntf, GenericWindow &rWindow, ...@@ -41,7 +41,7 @@ X11Window::X11Window( intf_thread_t *pIntf, GenericWindow &rWindow,
X11Display &rDisplay, bool dragDrop, bool playOnDrop, X11Display &rDisplay, bool dragDrop, bool playOnDrop,
X11Window *pParentWindow, GenericWindow::WindowType_t type ): X11Window *pParentWindow, GenericWindow::WindowType_t type ):
OSWindow( pIntf ), m_rDisplay( rDisplay ), m_pParent( pParentWindow ), OSWindow( pIntf ), m_rDisplay( rDisplay ), m_pParent( pParentWindow ),
m_dragDrop( dragDrop ), m_type ( type ) m_dragDrop( dragDrop ), m_pDropTarget( NULL ), m_type ( type )
{ {
XSetWindowAttributes attr; XSetWindowAttributes attr;
unsigned long valuemask; unsigned long valuemask;
...@@ -150,7 +150,7 @@ X11Window::X11Window( intf_thread_t *pIntf, GenericWindow &rWindow, ...@@ -150,7 +150,7 @@ X11Window::X11Window( intf_thread_t *pIntf, GenericWindow &rWindow,
{ {
// Create a Dnd object for this window // Create a Dnd object for this window
m_pDropTarget = new X11DragDrop( getIntf(), m_rDisplay, m_wnd, m_pDropTarget = new X11DragDrop( getIntf(), m_rDisplay, m_wnd,
playOnDrop ); playOnDrop, &rWindow );
// Register the window as a drop target // Register the window as a drop target
Atom xdndAtom = XInternAtom( XDISPLAY, "XdndAware", False ); Atom xdndAtom = XInternAtom( XDISPLAY, "XdndAware", False );
...@@ -229,10 +229,8 @@ X11Window::~X11Window() ...@@ -229,10 +229,8 @@ X11Window::~X11Window()
pFactory->m_windowMap[m_wnd] = NULL; pFactory->m_windowMap[m_wnd] = NULL;
pFactory->m_dndMap[m_wnd] = NULL; pFactory->m_dndMap[m_wnd] = NULL;
if( m_dragDrop ) delete m_pDropTarget;
{
delete m_pDropTarget;
}
XDestroyWindow( XDISPLAY, m_wnd ); XDestroyWindow( XDISPLAY, m_wnd );
XSync( XDISPLAY, False ); XSync( XDISPLAY, False );
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment