Commit 8a50a0bd authored by Olivier Teulière's avatar Olivier Teulière

* ./modules/gui/win32/dragdrop.cpp: we can now drag and drop video

   files on the interface or on the playlist (Closes: #10).
 * ./modules/gui/win32/playlist.cpp: factorized a lot of code.
 * ./modules/gui/win32/*: reorganized some code here and there.
parent e4d0eaae
......@@ -19,8 +19,8 @@ BORLAND_win32 = \
modules/gui/win32/win32.bpf \
\
modules/gui/win32/about.cpp \
modules/gui/win32/control.cpp \
modules/gui/win32/disc.cpp \
modules/gui/win32/dragdrop.cpp \
modules/gui/win32/mainframe.cpp \
modules/gui/win32/menu.cpp \
modules/gui/win32/messages.cpp \
......@@ -39,8 +39,8 @@ BORLAND_win32 = \
modules/gui/win32/preferences.dfm \
\
modules/gui/win32/about.h \
modules/gui/win32/control.h \
modules/gui/win32/disc.h \
modules/gui/win32/dragdrop.h \
modules/gui/win32/mainframe.h \
modules/gui/win32/menu.h \
modules/gui/win32/messages.h \
......
/*****************************************************************************
* control.cpp: functions to handle stream control buttons.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vcl.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "win32_common.h"
extern intf_thread_t *p_intfGlobal;
/****************************************************************************
* Control functions: this is where the functions are defined
****************************************************************************
* These functions are used by toolbuttons callbacks
****************************************************************************/
bool ControlBack( TObject *Sender )
{
/* FIXME: TODO */
return false;
}
bool ControlStop( TObject *Sender )
{
playlist_t * p_playlist = (playlist_t *)
vlc_object_find( p_intfGlobal, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return false;
}
playlist_Stop( p_playlist );
vlc_object_release( p_playlist );
return true;
}
bool ControlPlay( TObject *Sender )
{
playlist_t * p_playlist = (playlist_t *)
vlc_object_find( p_intfGlobal, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
p_intfGlobal->p_sys->p_window->OpenFileActionExecute( Sender );
return false;
}
vlc_mutex_lock( &p_playlist->object_lock );
if( p_playlist->i_size )
{
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play( p_playlist );
vlc_object_release( p_playlist );
}
else
{
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
p_intfGlobal->p_sys->p_window->OpenFileActionExecute( Sender );
}
return true;
}
bool ControlPause( TObject *Sender )
{
if( p_intfGlobal->p_sys->p_input != NULL )
{
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_PAUSE );
}
return true;
}
bool ControlSlow( TObject *Sender )
{
if( p_intfGlobal->p_sys->p_input != NULL )
{
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_SLOWER );
}
return true;
}
bool ControlFast( TObject *Sender )
{
if( p_intfGlobal->p_sys->p_input != NULL )
{
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_FASTER );
}
return true;
}
......@@ -63,14 +63,6 @@ void __fastcall TDiscDlg::BitBtnCancelClick( TObject *Sender )
void __fastcall TDiscDlg::BitBtnOkClick( TObject *Sender )
{
AnsiString Device, Source, Method, Title, Chapter;
playlist_t * p_playlist;
p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
Hide();
......@@ -78,13 +70,9 @@ void __fastcall TDiscDlg::BitBtnOkClick( TObject *Sender )
/* Check which method was activated */
if( RadioGroupType->ItemIndex == 0 )
{
Method = "dvd";
}
else
{
Method = "vcd";
}
/* Select title and chapter */
Title.sprintf( "%d", SpinEditTitle->Value );
......@@ -92,13 +80,9 @@ void __fastcall TDiscDlg::BitBtnOkClick( TObject *Sender )
/* Build source name and add it to playlist */
Source = Method + ":" + Device + "@" + Title + "," + Chapter;
playlist_Add( p_playlist, Source.c_str(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
/* update the display */
p_intf->p_sys->p_playwin->UpdateGrid( p_playlist );
vlc_object_release( p_playlist );
p_intf->p_sys->p_playwin->Add( Source, PLAYLIST_APPEND | PLAYLIST_GO,
PLAYLIST_END );
}
//---------------------------------------------------------------------------
void __fastcall TDiscDlg::RadioGroupTypeClick( TObject *Sender )
......
/*****************************************************************************
* dragdrop.cpp: drag and drop management
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vcl.h>
#pragma hdrstop
#include "dragdrop.h"
//---------------------------------------------------------------------------
__fastcall TDropTarget::TDropTarget( HWND HForm ) : IDropTarget()
{
FormHandle = HForm;
References = 1;
}
//---------------------------------------------------------------------------
__fastcall TDropTarget::~TDropTarget()
{
}
//---------------------------------------------------------------------------
/* helper routine to notify Form of drop on target */
void __fastcall TDropTarget::HandleDrop( HDROP HDrop )
{
SendMessage( FormHandle, WM_OLEDROP, (WPARAM)HDrop, 0 );
}
//---------------------------------------------------------------------------
STDMETHODIMP TDropTarget::QueryInterface( REFIID iid, void FAR* FAR* ppv )
{
/* tell other objects about our capabilities */
if( iid == IID_IUnknown || iid == IID_IDropTarget )
{
*ppv = this;
AddRef();
return S_OK;
}
*ppv = NULL;
return ResultFromScode( E_NOINTERFACE );
}
//---------------------------------------------------------------------------
STDMETHODIMP_(ULONG) TDropTarget::AddRef()
{
return ++References;
}
//---------------------------------------------------------------------------
STDMETHODIMP_(ULONG) TDropTarget::Release()
{
if( --References == 0 )
{
delete this;
return 0;
}
return References;
}
//---------------------------------------------------------------------------
/* Indicates whether a drop can be accepted, and, if so,
* the effect of the drop */
STDMETHODIMP TDropTarget::DragEnter( LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, DWORD *pdwEffect )
{
FORMATETC fmtetc;
fmtetc.cfFormat = CF_HDROP;
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
/* Check that the drag source provides CF_HDROP,
* which is the only format we accept */
if( pDataObj->QueryGetData( &fmtetc ) == S_OK )
*pdwEffect = DROPEFFECT_COPY;
else
*pdwEffect = DROPEFFECT_NONE;
return S_OK;
}
//---------------------------------------------------------------------------
/* for visual feedback */
STDMETHODIMP TDropTarget::DragOver( DWORD grfKeyState, POINTL pt,
DWORD *pdwEffect )
{
return S_OK;
}
//---------------------------------------------------------------------------
/* remove visual feedback */
STDMETHODIMP TDropTarget::DragLeave()
{
return S_OK;
}
//---------------------------------------------------------------------------
/* something has been dropped */
STDMETHODIMP TDropTarget::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, DWORD *pdwEffect )
{
/* user has dropped on us -- get the CF_HDROP data from drag source */
FORMATETC fmtetc;
fmtetc.cfFormat = CF_HDROP;
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
STGMEDIUM medium;
HRESULT hr = pDataObj->GetData( &fmtetc, &medium );
if( !FAILED(hr) )
{
/* grab a pointer to the data */
HGLOBAL HFiles = medium.hGlobal;
HDROP HDrop = (HDROP)GlobalLock( HFiles );
/* call the helper routine which will notify the Form of the drop */
HandleDrop( HDrop );
/* release the pointer to the memory */
GlobalUnlock( HFiles );
ReleaseStgMedium( &medium );
}
else
{
*pdwEffect = DROPEFFECT_NONE;
return hr;
}
return S_OK;
}
/*****************************************************************************
* control.h: prototypes for control functions.
* dragdrop.h: drag and drop management
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
......@@ -20,10 +20,40 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
bool ControlBack ( TObject *Sender );
bool ControlStop ( TObject *Sender );
bool ControlPlay ( TObject *Sender );
bool ControlPause( TObject *Sender );
bool ControlSlow ( TObject *Sender );
bool ControlFast ( TObject *Sender );
#ifndef dragdropH
#define dragdropH
//---------------------------------------------------------------------------
#include <ole2.h>
#define WM_OLEDROP WM_USER + 1
//---------------------------------------------------------------------------
class TDropTarget : public IDropTarget
{
public:
__fastcall TDropTarget( HWND HForm );
__fastcall ~TDropTarget();
protected:
/* IUnknown methods */
STDMETHOD(QueryInterface)( REFIID riid, void FAR* FAR* ppvObj );
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
/* IDropTarget methods */
STDMETHOD(DragEnter)( LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, DWORD *pdwEffect );
STDMETHOD(DragOver)( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
STDMETHOD(DragLeave)();
STDMETHOD(Drop)( LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, DWORD *pdwEffect );
private:
unsigned long References;
HWND FormHandle;
/* helper function */
void __fastcall HandleDrop( HDROP HDrop );
};
//---------------------------------------------------------------------------
#endif
......@@ -27,9 +27,9 @@
#include <vlc/intf.h>
#include <vlc/vout.h>
#include "dragdrop.h"
#include "mainframe.h"
#include "menu.h"
#include "control.h"
#include "disc.h"
#include "network.h"
#include "about.h"
......@@ -42,7 +42,6 @@
#include "netutils.h"
//---------------------------------------------------------------------------
//#pragma package(smart_init)
#pragma link "CSPIN"
#pragma resource "*.dfm"
......@@ -66,8 +65,18 @@ __fastcall TMainFrameDlg::TMainFrameDlg(
Caption = VOUT_TITLE " (Win32 interface)";
StringListPref = new TStringList();
Translate( this );
/* drag and drop stuff */
/* initialize the OLE library */
OleInitialize( NULL );
/* TDropTarget will send the WM_OLEDROP message to the form */
lpDropTarget = (LPDROPTARGET)new TDropTarget( this->Handle );
CoLockObjectExternal( lpDropTarget, true, true );
/* register the form as a drop target */
RegisterDragDrop( this->Handle, lpDropTarget );
}
//---------------------------------------------------------------------------
__fastcall TMainFrameDlg::~TMainFrameDlg()
......@@ -96,8 +105,6 @@ void __fastcall TMainFrameDlg::TrackBarChange( TObject *Sender )
* the stream. It is called whenever the slider changes its value.
* The lock has to be taken before the function is called */
// vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
if( p_intf->p_sys->p_input != NULL )
{
#define p_area p_intf->p_sys->p_input->stream.p_selected_area
......@@ -109,8 +116,6 @@ void __fastcall TMainFrameDlg::TrackBarChange( TObject *Sender )
( p_area->i_size * Value ) / (off_t)SLIDER_MAX_VALUE );
#undef p_area
}
// vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FormClose( TObject *Sender,
......@@ -120,6 +125,14 @@ void __fastcall TMainFrameDlg::FormClose( TObject *Sender,
p_intf->p_vlc->b_die = VLC_TRUE;
vlc_mutex_unlock( &p_intf->change_lock );
/* remove the form from the list of drop targets */
RevokeDragDrop( this->Handle );
lpDropTarget->Release();
CoLockObjectExternal( lpDropTarget, false, true );
/* uninitialize the OLE library */
OleUninitialize();
/* we don't destroy the form immediatly */
Action = caHide;
}
......@@ -131,28 +144,13 @@ void __fastcall TMainFrameDlg::FormClose( TObject *Sender,
****************************************************************************/
void __fastcall TMainFrameDlg::OpenFileActionExecute( TObject *Sender )
{
AnsiString FileName;
playlist_t * p_playlist;
p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
if( OpenDialog1->Execute() )
{
/* add the new file to the interface playlist */
FileName = OpenDialog1->FileName;
playlist_Add( p_playlist, (char*)FileName.c_str(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
/* update the plugin display */
p_intf->p_sys->p_playwin->UpdateGrid( p_playlist );
p_intf->p_sys->p_playwin->Add( OpenDialog1->FileName,
PLAYLIST_APPEND | PLAYLIST_GO,
PLAYLIST_END );
};
vlc_object_release( p_playlist );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::OpenDiscActionExecute( TObject *Sender )
......@@ -206,16 +204,7 @@ void __fastcall TMainFrameDlg::PlaylistActionExecute( TObject *Sender )
}
else
{
playlist_t * p_playlist;
p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
p_playwin->UpdateGrid( p_playlist );
vlc_object_release( p_playlist );
p_playwin->UpdateGrid();
p_playwin->Show();
}
}
......@@ -239,32 +228,32 @@ void __fastcall TMainFrameDlg::AboutActionExecute( TObject *Sender )
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::BackActionExecute( TObject *Sender )
{
ControlBack( Sender );
/* TODO */
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PlayActionExecute( TObject *Sender )
{
ControlPlay( Sender );
p_intf->p_sys->p_playwin->Play();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PauseActionExecute( TObject *Sender )
{
ControlPause( Sender );
p_intf->p_sys->p_playwin->Pause();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::StopActionExecute( TObject *Sender )
{
ControlStop( Sender );
p_intf->p_sys->p_playwin->Stop();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::SlowActionExecute( TObject *Sender )
{
ControlSlow( Sender );
p_intf->p_sys->p_playwin->Slow();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FastActionExecute( TObject *Sender )
{
ControlFast( Sender );
p_intf->p_sys->p_playwin->Fast();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PreviousActionExecute(TObject *Sender)
......@@ -330,9 +319,41 @@ void __fastcall TMainFrameDlg::EjectActionExecute( TObject *Sender )
//--------------------------------------------------------------------------
/*****************************************************************************
* External drop handling
*****************************************************************************/
void __fastcall TMainFrameDlg::OnDrop( TMessage &Msg )
{
/* find the number of files dropped */
int num_files = DragQueryFile( (HDROP)Msg.WParam, 0xFFFFFFFF,
(LPSTR)NULL, NULL );
/* append each file to the playlist */
for( int i = 0; i < num_files; i++ )
{
/* find the length of the filename */
int name_length = DragQueryFile( (HDROP)Msg.WParam, i, NULL, NULL ) + 1;
/* get the filename */
char *FileName = new char[name_length];
DragQueryFile( (HDROP)Msg.WParam, i, FileName, name_length );
/* add the new file to the playlist */
p_intf->p_sys->p_playwin->Add( FileName, PLAYLIST_APPEND | PLAYLIST_GO,
PLAYLIST_END );
delete[] FileName;
}
DragFinish( (HDROP)Msg.WParam );
Msg.Result = 0;
}
//--------------------------------------------------------------------------
/*****************************************************************************
* Menu and popup callbacks
****************************************************************************/
*****************************************************************************/
void __fastcall TMainFrameDlg::MenuHideinterfaceClick( TObject *Sender )
{
this->SendToBack();
......
......@@ -37,6 +37,14 @@
#include <ExtCtrls.hpp>
#include "CSPIN.h"
#include <ActnList.hpp>
#include <oleidl.h> /* for drag and drop */
/*****************************************************************************
* This message is sent to the controls registered as drop targets
*****************************************************************************/
#define WM_OLEDROP WM_USER + 1
//---------------------------------------------------------------------------
class TMainFrameDlg : public TForm
{
......@@ -193,6 +201,11 @@ __published: // IDE-managed Components
void __fastcall NextChapterActionExecute( TObject *Sender );
private: // User declarations
intf_thread_t *p_intf;
/* drag and drop handling */
LPDROPTARGET lpDropTarget;
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER( WM_OLEDROP, TMessage, OnDrop )
END_MESSAGE_MAP( TForm )
public: // User declarations
TStringList *StringListPref; /* stores config dialogs */
__fastcall TMainFrameDlg( TComponent* Owner, intf_thread_t *_p_intf );
......@@ -209,6 +222,7 @@ public: // User declarations
void __fastcall PopupAudioClick( TObject *Sender );
void __fastcall PopupSubtitleClick( TObject *Sender );
void __fastcall PopupNavigationClick( TObject *Sender );
void __fastcall OnDrop( TMessage &Msg );
};
//---------------------------------------------------------------------------
#endif
......@@ -32,8 +32,8 @@
void __fastcall Translate( TForm *Form )
{
#if 0
Form->Hint = N_( Form->Hint );
Form->Caption = N_( Form->Caption );
Form->Hint = _( Form->Hint );
Form->Caption = _( Form->Caption );
int i;
for( i = 0; i < Form->ComponentCount; i++ )
......@@ -49,12 +49,12 @@ void __fastcall Translate( TForm *Form )
if( Component->InheritsFrom( __classid( TControl ) ) )
{
TControl *Object = (TControl *) Component;
Object->Hint = N_( Object->Hint );
Object->Hint = _( Object->Hint );
}
else if( Component->InheritsFrom( __classid( TMenuItem ) ) )
{
TMenuItem *Object = (TMenuItem *) Component;
Object->Hint = N_( Object->Hint );
Object->Hint = _( Object->Hint );
}
}
......@@ -64,47 +64,47 @@ void __fastcall Translate( TForm *Form )
if( Component->InheritsFrom( __classid( TMenuItem ) ) )
{
TMenuItem *Object = (TMenuItem *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TLabel ) ) )
{
TLabel *Object = (TLabel *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TButton ) ) )
{
TButton *Object = (TButton *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TToolButton ) ) )
{
TToolButton *Object = (TToolButton *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TRadioButton ) ) )
{
TRadioButton *Object = (TRadioButton *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TCheckBox ) ) )
{
TCheckBox *Object = (TCheckBox *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TRadioGroup ) ) )
{
TRadioGroup *Object = (TRadioGroup *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TGroupBox ) ) )
{
TGroupBox *Object = (TGroupBox *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}
else if( Component->InheritsFrom( __classid( TTabSheet ) ) )
{
TTabSheet *Object = (TTabSheet *) Component;
Object->Caption = N_( Object->Caption );
Object->Caption = _( Object->Caption );
}