mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
1723 lines
50 KiB
C++
1723 lines
50 KiB
C++
|
#include "main.h"
|
||
|
#include "api__gen_ml.h"
|
||
|
#include <windowsx.h>
|
||
|
#include <time.h>
|
||
|
#include <rpc.h>
|
||
|
#include "../winamp/gen.h"
|
||
|
#include "resource.h"
|
||
|
#include "../nu/ns_wc.h"
|
||
|
#include "config.h"
|
||
|
#include "../winamp/ipc_pe.h"
|
||
|
#include "../winamp/wa_dlg.h"
|
||
|
|
||
|
#include "ml.h"
|
||
|
#include "ml_ipc.h"
|
||
|
#include "sendto.h"
|
||
|
#include "../gen_hotkeys/wa_hotkeys.h"
|
||
|
#include "MediaLibraryCOM.h"
|
||
|
#include "../nu/CCVersion.h"
|
||
|
#include "../nu/AutoWide.h"
|
||
|
#include "../nu/AutoChar.h"
|
||
|
|
||
|
#include "./navigation.h"
|
||
|
|
||
|
#include "./ml_imagelist.h"
|
||
|
#include "./ml_imagefilter.h"
|
||
|
#include "./imagefilters.h" // default filters
|
||
|
|
||
|
#include <shlwapi.h>
|
||
|
#include "./ml_ipc_0313.h"
|
||
|
#include "./skinning.h"
|
||
|
#include "./ml_ratingcolumn.h"
|
||
|
#include "./ml_cloudcolumn.h"
|
||
|
#include "./colors.h"
|
||
|
#include "./stockobjects.h"
|
||
|
#include "./service.h"
|
||
|
#include "./skinnedbutton.h"
|
||
|
#include "../Winamp/wasabicfg.h"
|
||
|
#ifdef _DEBUG
|
||
|
#define BETA
|
||
|
#endif
|
||
|
|
||
|
// messages
|
||
|
#define WMML_FIRST (WM_APP + 0)
|
||
|
#define WMML_UPDATEVIEW (WMML_FIRST + 1)
|
||
|
#define WMML_SHOWCONTAINER (WMML_FIRST + 10)
|
||
|
|
||
|
#define BLOCK_ACCELTOGGLE_PROP TEXT("BLOCK_ACCELTOGGLE")
|
||
|
|
||
|
// timers
|
||
|
#define TIMER_UPDATEVIEW_ID 1970
|
||
|
#define TIMER_UPDATEVIEW_DELAY 7
|
||
|
#define TIMER_NAVAUTOSCROLL_ID 1971
|
||
|
#define TIMER_NAVAUTOSCROLL_DELAY 80
|
||
|
#define TIMER_NAVAUTOEXPAND_ID 1972
|
||
|
#define TIMER_NAVAUTOEXPAND_DELAY 500
|
||
|
#define TIMER_UNBLOCKACCELTOGGLE_ID 1973
|
||
|
#define TIMER_UNBLOCKACCELTOGGLE_DELAY 200
|
||
|
|
||
|
#define IDC_CURRENTVIEW 0x1001
|
||
|
#define IDC_NAVIGATION 0x03FD // (this is the same that old versions used)
|
||
|
|
||
|
|
||
|
#define MEDIALIBRARY_HELP_URL L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library"
|
||
|
|
||
|
SendToMenu *main_sendtomenu;
|
||
|
HMENU main_sendto_hmenu;
|
||
|
int main_sendto_mode;
|
||
|
|
||
|
extern "C" HWND g_ownerwnd;
|
||
|
|
||
|
static int ldiv_clickoffs, ldiv_paintleftborder;
|
||
|
static WNDPROC ldiv_oldWndProc;
|
||
|
static WNDPROC add_oldWndProc;
|
||
|
|
||
|
HNAVITEM g_treedrag_lastSel;
|
||
|
static HNAVITEM m_query_moving_dragplace;
|
||
|
static HNAVITEM m_query_moving_item, m_query_moving_lastdest;
|
||
|
static int m_query_moving_dragplaceisbelow;
|
||
|
static int m_query_moving;
|
||
|
static int m_query_moving_type;
|
||
|
|
||
|
HWND m_curview_hwnd = NULL;
|
||
|
|
||
|
HNAVCTRL hNavigation = NULL; // navigation control
|
||
|
HMLIMGLST hmlilRating = NULL; // default rating images
|
||
|
HMLIMGLST hmlilCloud = NULL; // default cloud images
|
||
|
UINT ratingGlobalStyle = RATING_DEFAULT_STYLE;
|
||
|
|
||
|
static HMLIMGLST hmlilNavigation = NULL; // default navigation image list
|
||
|
HMLIMGFLTRMNGR hmlifMngr = NULL; /// default image filters
|
||
|
|
||
|
static HRGN g_rgnUpdate = NULL;
|
||
|
static INT divider_pos;
|
||
|
|
||
|
static BOOL firstShow = TRUE;
|
||
|
static BOOL m_nav_autoscroll = FALSE;
|
||
|
static HNAVITEM m_nav_autoexpand_item = NULL;
|
||
|
|
||
|
static HIMAGELIST m_nav_dragitem_imagelist = NULL;
|
||
|
|
||
|
void OpenMediaLibraryPreferences();
|
||
|
|
||
|
typedef struct _LAYOUT
|
||
|
{
|
||
|
INT id;
|
||
|
HWND hwnd;
|
||
|
INT x;
|
||
|
INT y;
|
||
|
INT cx;
|
||
|
INT cy;
|
||
|
DWORD flags;
|
||
|
HRGN rgn;
|
||
|
}LAYOUT, PLAYOUT;
|
||
|
|
||
|
#define SETLAYOUTPOS(_layout, _x, _y, _cx, _cy) { _layout->x=_x; _layout->y=_y;_layout->cx=_cx;_layout->cy=_cy;_layout->rgn=NULL; }
|
||
|
|
||
|
static void LayoutWindows( HWND hwnd, INT divX, BOOL fRedraw )
|
||
|
{
|
||
|
static BOOL useDefer = ( GetVersion() < 0x80000000 );
|
||
|
static INT controls[] = { IDC_BTN_LIB, IDC_NAVIGATION, IDC_VDELIM, IDC_CURRENTVIEW, IDC_NO_VIEW };
|
||
|
RECT rc, ri, roTree;
|
||
|
LAYOUT layout[ sizeof( controls ) / sizeof( controls[ 0 ] ) ], *pl;
|
||
|
|
||
|
INT divCX = 0, btnY;
|
||
|
|
||
|
GetClientRect( hwnd, &rc );
|
||
|
if ( rc.bottom == rc.top || rc.left == rc.right )
|
||
|
return;
|
||
|
|
||
|
if ( rc.bottom > WASABI_API_APP->getScaleY( 2 ) )
|
||
|
rc.bottom -= WASABI_API_APP->getScaleY( 2 );
|
||
|
|
||
|
HRGN rgn = CreateRectRgn( 0, 0, 0, 0 );
|
||
|
|
||
|
if ( divX > rc.right - WASABI_API_APP->getScaleY( 41 ) )
|
||
|
divX = rc.right - WASABI_API_APP->getScaleY( 9 );
|
||
|
|
||
|
if ( divX < WASABI_API_APP->getScaleY( 32 ) )
|
||
|
divX = 0;
|
||
|
else if ( divX > ( rc.right - rc.left ) )
|
||
|
divX = ( rc.right - rc.left );
|
||
|
|
||
|
pl = layout;
|
||
|
btnY = rc.bottom; // in case button is broken
|
||
|
|
||
|
InvalidateRgn( hwnd, NULL, TRUE );
|
||
|
|
||
|
for ( int i = 0; i < sizeof( controls ) / sizeof( controls[ 0 ] ); i++ )
|
||
|
{
|
||
|
pl->id = controls[ i ];
|
||
|
switch ( pl->id )
|
||
|
{
|
||
|
case IDC_NAVIGATION: pl->hwnd = NavCtrlI_GetHWND( hNavigation ); break;
|
||
|
case IDC_CURRENTVIEW: pl->hwnd = m_curview_hwnd; break;
|
||
|
default: pl->hwnd = GetDlgItem( hwnd, pl->id ); break;
|
||
|
}
|
||
|
|
||
|
if ( !pl->hwnd )
|
||
|
continue;
|
||
|
|
||
|
pl->rgn = NULL;
|
||
|
GetWindowRect( pl->hwnd, &ri );
|
||
|
MapWindowPoints( HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2 );
|
||
|
|
||
|
pl->flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS;
|
||
|
|
||
|
switch ( pl->id )
|
||
|
{
|
||
|
case IDC_BTN_LIB:
|
||
|
{
|
||
|
wchar_t buffer[ 128 ] = { 0 };
|
||
|
GetWindowTextW( pl->hwnd, buffer, ARRAYSIZE( buffer ) );
|
||
|
LRESULT idealSize = MLSkinnedButton_GetIdealSize( pl->hwnd, buffer );
|
||
|
btnY = WASABI_API_APP->getScaleY( HIWORD( idealSize ) );
|
||
|
SETLAYOUTPOS( pl, rc.left, rc.bottom - btnY, rc.left + divX, btnY );
|
||
|
break;
|
||
|
}
|
||
|
case IDC_NAVIGATION:
|
||
|
GetClientRect( pl->hwnd, &roTree );
|
||
|
NavCtrlI_MapPointsTo( hNavigation, hwnd, (LPPOINT)&roTree, 2 );
|
||
|
SETLAYOUTPOS( pl, rc.left, rc.top, rc.left + divX, rc.bottom - btnY - WASABI_API_APP->getScaleY( 3 ) );
|
||
|
ldiv_paintleftborder = ( pl->cx > 0 );
|
||
|
break;
|
||
|
case IDC_VDELIM:
|
||
|
divCX = ( ri.right - ri.left );
|
||
|
SETLAYOUTPOS( pl, divX + WASABI_API_APP->getScaleX( 1 ), rc.top, divCX, max( 0, rc.bottom - rc.top ) );
|
||
|
break;
|
||
|
case IDC_CURRENTVIEW: // current view;
|
||
|
SETLAYOUTPOS( pl, divX + divCX, rc.top, max( 0, rc.right - pl->x - WASABI_API_APP->getScaleX( 2 ) ), max( 0, rc.bottom - rc.top ) );
|
||
|
if ( !SendMessage( pl->hwnd, WM_USER + 0x200, 0, 0 ) ) pl->flags &= ~( SWP_NOREDRAW );
|
||
|
break;
|
||
|
case IDC_NO_VIEW:
|
||
|
SETLAYOUTPOS( pl, divX + divCX + 20, rc.top, max( 0, rc.right - pl->x - WASABI_API_APP->getScaleX( 2 ) - 20 ), max( 0, rc.bottom - rc.top ) );
|
||
|
if ( !SendMessage( pl->hwnd, WM_USER + 0x200, 0, 0 ) ) pl->flags &= ~( SWP_NOREDRAW );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( pl->x == ri.left && pl->y == ri.top )
|
||
|
pl->flags |= SWP_NOMOVE;
|
||
|
|
||
|
if ( pl->cx == ( ri.right - ri.left ) && pl->cy == ( ri.bottom - ri.top ) )
|
||
|
pl->flags |= SWP_NOSIZE;
|
||
|
|
||
|
if ( ( SWP_NOMOVE | SWP_NOSIZE ) != ( ( SWP_NOMOVE | SWP_NOSIZE ) & pl->flags ) )
|
||
|
pl++;
|
||
|
else if ( IsWindowVisible( pl->hwnd ) )
|
||
|
{
|
||
|
ValidateRect( hwnd, &ri );
|
||
|
if ( GetUpdateRect( pl->hwnd, NULL, FALSE ) )
|
||
|
{
|
||
|
GetUpdateRgn( pl->hwnd, rgn, FALSE );
|
||
|
OffsetRgn( rgn, pl->x, pl->y );
|
||
|
InvalidateRgn( hwnd, rgn, FALSE );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pl != layout )
|
||
|
{
|
||
|
LAYOUT *pc;
|
||
|
HDWP hdwp = ( useDefer ) ? BeginDeferWindowPos( (INT)( pl - layout ) ) : NULL;
|
||
|
for ( pc = layout; pc < pl && ( !useDefer || hdwp ); pc++ )
|
||
|
{
|
||
|
if ( IDC_CURRENTVIEW == pc->id && ( SWP_NOREDRAW & pc->flags ) && IsWindowVisible( pc->hwnd ) )
|
||
|
{
|
||
|
if ( !pc->rgn )
|
||
|
pc->rgn = CreateRectRgn( 0, 0, pc->cx, pc->cy );
|
||
|
|
||
|
GetWindowRect( pc->hwnd, &ri );
|
||
|
NavCtrlI_MapPointsFrom( hNavigation, HWND_DESKTOP, (LPPOINT)&ri, 1 );
|
||
|
SendMessage( pc->hwnd, WM_USER + 0x201, MAKEWPARAM( pc->x - ri.left, pc->y - ri.top ), (LPARAM)pc->rgn );
|
||
|
}
|
||
|
if ( useDefer )
|
||
|
hdwp = DeferWindowPos( hdwp, pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags );
|
||
|
else
|
||
|
SetWindowPos( pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags );
|
||
|
}
|
||
|
|
||
|
if ( hdwp )
|
||
|
EndDeferWindowPos( hdwp );
|
||
|
|
||
|
for ( pc = layout; pc < pl; pc++ )
|
||
|
{
|
||
|
if ( IDC_NAVIGATION == pc->id )
|
||
|
{
|
||
|
GetWindowRect( pc->hwnd, &ri );
|
||
|
OffsetRect( &ri, -ri.left, -ri.top );
|
||
|
pc->rgn = CreateRectRgnIndirect( &ri );
|
||
|
|
||
|
GetClientRect( pc->hwnd, &ri );
|
||
|
|
||
|
NavCtrlI_MapPointsTo( hNavigation, hwnd, (LPPOINT)&ri, 1 );
|
||
|
IntersectRect( &ri, &roTree, &ri );
|
||
|
SetRectRgn( rgn, ri.left, ri.top, ri.right, ri.bottom );
|
||
|
CombineRgn( pc->rgn, pc->rgn, rgn, RGN_DIFF );
|
||
|
if ( GetUpdateRect( pc->hwnd, NULL, FALSE ) )
|
||
|
{
|
||
|
GetUpdateRgn( pc->hwnd, rgn, FALSE );
|
||
|
CombineRgn( pc->rgn, pc->rgn, rgn, RGN_OR );
|
||
|
}
|
||
|
}
|
||
|
else if ( IDC_CURRENTVIEW == pc->id && pc->rgn )
|
||
|
SendMessage( pc->hwnd, WM_USER + 0x201, 0, 0L );
|
||
|
|
||
|
if ( IsWindowVisible( pc->hwnd ) )
|
||
|
{
|
||
|
GetWindowRect( pc->hwnd, &ri );
|
||
|
MapWindowPoints( HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2 );
|
||
|
ValidateRect( hwnd, &ri );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fRedraw )
|
||
|
{
|
||
|
HRGN rgnTmp = CreateRectRgn( 0, 0, 0, 0 );
|
||
|
GetUpdateRgn( hwnd, rgn, FALSE );
|
||
|
for ( pc = layout; pc < pl; pc++ )
|
||
|
{
|
||
|
if ( SWP_NOREDRAW & pc->flags )
|
||
|
{
|
||
|
if ( pc->rgn )
|
||
|
OffsetRgn( pc->rgn, pc->x, pc->y );
|
||
|
else
|
||
|
SetRectRgn( rgnTmp, pc->x, pc->y, pc->x + pc->cx, pc->y + pc->cy );
|
||
|
|
||
|
CombineRgn( rgn, rgn, ( pc->rgn ) ? pc->rgn : rgnTmp, RGN_OR );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DeleteObject( rgnTmp );
|
||
|
RedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN );
|
||
|
}
|
||
|
else if ( g_rgnUpdate )
|
||
|
{
|
||
|
GetUpdateRgn( hwnd, g_rgnUpdate, FALSE );
|
||
|
ValidateRect( hwnd, NULL );
|
||
|
for ( pc = layout; pc < pl; pc++ )
|
||
|
{
|
||
|
if ( SWP_NOREDRAW & pc->flags )
|
||
|
{
|
||
|
if ( pc->rgn )
|
||
|
OffsetRgn( pc->rgn, pc->x, pc->y );
|
||
|
else
|
||
|
SetRectRgn( rgn, pc->x, pc->y, pc->x + pc->cx, pc->y + pc->cy );
|
||
|
|
||
|
CombineRgn( g_rgnUpdate, g_rgnUpdate, ( pc->rgn ) ? pc->rgn : rgn, RGN_OR );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for ( pc = layout; pc < pl; pc++ )
|
||
|
if ( pc->rgn )
|
||
|
DeleteObject( pc->rgn );
|
||
|
}
|
||
|
|
||
|
if ( rgn )
|
||
|
DeleteObject( rgn );
|
||
|
}
|
||
|
|
||
|
// a default right-pane view to show if a plugin failed to return us an HWND
|
||
|
static INT_PTR CALLBACK view_Error( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||
|
{
|
||
|
if ( uMsg == WM_INITDIALOG )
|
||
|
{
|
||
|
ShowWindow( GetDlgItem( g_hwnd, IDC_NO_VIEW ), SW_SHOW );
|
||
|
}
|
||
|
|
||
|
return WADlg_handleDialogMsgs( hwndDlg, uMsg, wParam, lParam );
|
||
|
}
|
||
|
|
||
|
static void CreateCurrentView( HWND hwndDlg )
|
||
|
{
|
||
|
HNAVITEM hItem;
|
||
|
DLGPROC proc;
|
||
|
proc = view_Error;
|
||
|
|
||
|
hItem = NavCtrlI_GetSelection( hNavigation );
|
||
|
if ( hItem )
|
||
|
{
|
||
|
INT itemId = NavItemI_GetId( hItem );
|
||
|
|
||
|
#if 0
|
||
|
#ifdef BETA
|
||
|
wchar_t pszText[ 32 ] = { 0 };
|
||
|
if ( NavItemI_GetInvariantText( hItem, pszText, 32 ) && !lstrcmpW( pszText, L"winamp_labs" ) )
|
||
|
{
|
||
|
OmService *om_service;
|
||
|
OmService::CreateInstance( SERVICE_LABS, L"Winamp Labs", &om_service );
|
||
|
|
||
|
if ( AGAVE_OBJ_BROWSER )
|
||
|
{
|
||
|
HWND hView = 0;
|
||
|
HRESULT hr = AGAVE_OBJ_BROWSER->CreateView( om_service, (HWND)hwndDlg, 0, 0, &hView );
|
||
|
om_service->Release();
|
||
|
if ( SUCCEEDED( hr ) )
|
||
|
{
|
||
|
m_curview_hwnd = hView;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
#endif
|
||
|
m_curview_hwnd = (HWND)plugin_SendMessage( ML_MSG_TREE_ONCREATEVIEW, (INT_PTR)itemId, (INT_PTR)hwndDlg, 0 );
|
||
|
}
|
||
|
|
||
|
if ( !IsWindow( m_curview_hwnd ) )
|
||
|
m_curview_hwnd = WASABI_API_CREATEDIALOGPARAMW( IDD_VIEW_EMPTY, hwndDlg, proc, 0 );
|
||
|
else
|
||
|
ShowWindow( GetDlgItem( g_hwnd, IDC_NO_VIEW ), SW_HIDE );
|
||
|
|
||
|
if ( IsWindow( m_curview_hwnd ) )
|
||
|
{
|
||
|
SetWindowPos( m_curview_hwnd, NavCtrlI_GetHWND( hNavigation ), 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW );
|
||
|
LayoutWindows( hwndDlg, divider_pos, FALSE );
|
||
|
// moved 08/12/09 from start of block to here along with SkinnedWnd::OnSkinChanged(..) change to hopefully resolve bold font issues
|
||
|
MLSkinnedWnd_SkinChanged( m_curview_hwnd, TRUE, FALSE );
|
||
|
ShowWindow( m_curview_hwnd, SW_SHOWNORMAL );
|
||
|
RedrawWindow( m_curview_hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
|
||
|
PostMessage( m_curview_hwnd, WMML_UPDATEVIEW, 0, 0 ); //refresh view
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void DisplayItemDragImage( HNAVITEM hItem, LPCWSTR pszTip, HWND hwndOwner, POINT *ppt ) // ppt in hwndOwner coordinates
|
||
|
{
|
||
|
if ( !hwndOwner )
|
||
|
return;
|
||
|
|
||
|
if ( m_nav_dragitem_imagelist )
|
||
|
{
|
||
|
ImageList_DragLeave( hwndOwner );
|
||
|
ImageList_EndDrag();
|
||
|
ImageList_Destroy( m_nav_dragitem_imagelist );
|
||
|
}
|
||
|
|
||
|
m_nav_dragitem_imagelist = NavItemI_CreateDragImage( hItem, pszTip );
|
||
|
|
||
|
if ( m_nav_dragitem_imagelist )
|
||
|
{
|
||
|
INT cx, cy;
|
||
|
ImageList_GetIconSize( m_nav_dragitem_imagelist, &cx, &cy );
|
||
|
if ( ImageList_BeginDrag( m_nav_dragitem_imagelist, 0, cx / 2, cy / 2 ) )
|
||
|
{
|
||
|
NavCtrlI_Update( hNavigation );
|
||
|
ImageList_DragEnter( hwndOwner, ppt->x, ppt->y );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID CALLBACK CreateViewTimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
|
||
|
{
|
||
|
if ( idEvent == TIMER_UPDATEVIEW_ID )
|
||
|
{
|
||
|
KillTimer( hwnd, TIMER_UPDATEVIEW_ID );
|
||
|
CreateCurrentView( hwnd );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void CALLBACK OnNavCtrl_Selected( HNAVCTRL hMngr, HNAVITEM hItemOld, HNAVITEM hItemNew )
|
||
|
{
|
||
|
KillTimer( g_hwnd, TIMER_UPDATEVIEW_ID );
|
||
|
if ( IsWindow( m_curview_hwnd ) )
|
||
|
{
|
||
|
RedrawWindow( g_hwnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN );
|
||
|
SendMessageW( g_hwnd, WM_SETREDRAW, FALSE, 0L ); // freeze window
|
||
|
ShowWindow( m_curview_hwnd, SW_HIDE );
|
||
|
SendMessageW( g_hwnd, WM_SETREDRAW, TRUE, 0L );
|
||
|
DestroyWindow( m_curview_hwnd );
|
||
|
|
||
|
m_curview_hwnd = NULL;
|
||
|
}
|
||
|
// 07/05/2010 DRO - changed to use a callback proc as ml_disc was managing to trigger
|
||
|
// the same timer message multiple times on (at least) older XP machines which was
|
||
|
// causing multiple ml view dialogs to be created but hidden behind the currently
|
||
|
// opened view - intermittent issue i've been seeing for a year on my XP machine.
|
||
|
SetTimer( g_hwnd, TIMER_UPDATEVIEW_ID, TIMER_UPDATEVIEW_DELAY, CreateViewTimerProc );
|
||
|
}
|
||
|
|
||
|
static BOOL CALLBACK OnNavCtrl_Click( HNAVCTRL hMngr, HNAVITEM hItem, INT actionId )
|
||
|
{
|
||
|
if ( hItem )
|
||
|
{
|
||
|
INT mlAction = -1;
|
||
|
|
||
|
switch ( actionId )
|
||
|
{
|
||
|
case ACTION_CLICKL_I: mlAction = ML_ACTION_LCLICK; break;
|
||
|
case ACTION_CLICKR_I: mlAction = ML_ACTION_RCLICK; break;
|
||
|
case ACTION_ENTER_I: mlAction = ML_ACTION_ENTER; break;
|
||
|
case ACTION_DBLCLICKL_I: mlAction = ML_ACTION_DBLCLICK; break;
|
||
|
case ACTION_DBLCLICKR_I: break;
|
||
|
}
|
||
|
|
||
|
if ( -1 != mlAction )
|
||
|
{
|
||
|
BOOL ret = (BOOL)plugin_SendMessage( ML_MSG_TREE_ONCLICK,
|
||
|
NavItemI_GetId( hItem ),
|
||
|
mlAction,
|
||
|
(INT_PTR)GetParent( NavCtrlI_GetHWND( hMngr ) ) );
|
||
|
|
||
|
if ( mlAction != ML_ACTION_LCLICK )
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
static BOOL CALLBACK OnNavCtrl_KeyDown( HNAVCTRL hMngr, HNAVITEM hItem, NMTVKEYDOWN *ptvkd )
|
||
|
{
|
||
|
return ( hItem ) ? (BOOL)plugin_SendMessage( ML_MSG_TREE_ONKEYDOWN,
|
||
|
NavItemI_GetId( hItem ),
|
||
|
(INT_PTR)ptvkd,
|
||
|
(INT_PTR)NavCtrlI_GetHWND( hMngr ) ) : FALSE;
|
||
|
}
|
||
|
|
||
|
static BOOL CALLBACK OnNavCtrl_BeginTitleEdit( HNAVCTRL hMngr, HNAVITEM hItem )
|
||
|
{
|
||
|
return !(BOOL)plugin_SendMessage( ML_MSG_NAVIGATION_ONBEGINTITLEEDIT, (INT_PTR)hItem, 0, 0 );
|
||
|
}
|
||
|
|
||
|
static BOOL CALLBACK OnNavCtrl_EndTitleEdit( HNAVCTRL hMngr, HNAVITEM hItem, LPCWSTR pszNewTitle )
|
||
|
{
|
||
|
return (BOOL)plugin_SendMessage( ML_MSG_NAVIGATION_ONENDTITLEEDIT, (INT_PTR)hItem, (INT_PTR)pszNewTitle, 0 );
|
||
|
}
|
||
|
|
||
|
static void CALLBACK OnNavItem_Delete( HNAVCTRL hMngr, HNAVITEM hItem )
|
||
|
{
|
||
|
plugin_SendMessage( ML_MSG_NAVIGATION_ONDELETE, (INT_PTR)hItem, 0, 0 );
|
||
|
}
|
||
|
|
||
|
static void CALLBACK OnNavCtrl_Destroy( HNAVCTRL hMngr )
|
||
|
{
|
||
|
plugin_SendMessage( ML_MSG_NAVIGATION_ONDESTROY, 0, 0, 0 );
|
||
|
}
|
||
|
|
||
|
static INT CALLBACK OnNavItem_CustomDraw( HNAVCTRL hMngr, HNAVITEM hItem, NAVITEMDRAW_I *pnicd, LPARAM lParam )
|
||
|
{
|
||
|
INT result = (INT)plugin_SendMessage( ML_MSG_NAVIGATION_ONCUSTOMDRAW, (INT_PTR)hItem, (INT_PTR)pnicd, (INT_PTR)lParam );
|
||
|
|
||
|
if ( NICDRF_NOTMINE == result )
|
||
|
result = NICDRF_DODEFAULT_I;
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static INT CALLBACK OnNavItem_SetCursor( HNAVCTRL hMngr, HNAVITEM hItem, LPARAM lParam )
|
||
|
{
|
||
|
INT result = (INT)plugin_SendMessage( ML_MSG_NAVIGATION_ONSETCURSOR, (INT_PTR)hItem, (INT_PTR)0, (INT_PTR)lParam );
|
||
|
|
||
|
return ( result > 0 );
|
||
|
}
|
||
|
|
||
|
static void CALLBACK OnNavItem_HitTest( HNAVCTRL hMngr, POINT pt, UINT *pHitFlags, HNAVITEM *phItem, LPARAM lParam )
|
||
|
{
|
||
|
NAVHITTEST ht;
|
||
|
|
||
|
ht.flags = *pHitFlags;
|
||
|
ht.pt = pt;
|
||
|
ht.hItem = *phItem;
|
||
|
|
||
|
if ( 0 != plugin_SendMessage( ML_MSG_NAVIGATION_ONHITTEST, (INT_PTR)*phItem, (INT_PTR)&ht, (INT_PTR)lParam ) )
|
||
|
{
|
||
|
*pHitFlags = ht.flags;
|
||
|
*phItem = ht.hItem;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void CALLBACK OnNavCtrl_BeginDrag( HNAVCTRL hMngr, HNAVITEM hItem, POINT pt )
|
||
|
{
|
||
|
#ifdef BETA
|
||
|
wchar_t pszText[ 32 ] = { 0 };
|
||
|
if ( ( !( sneak & 4 ) ) && NavItemI_GetInvariantText( hItem, pszText, 32 ) && !lstrcmpW( pszText, L"winamp_labs" ) )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
if ( plugin_SendMessage( ML_MSG_TREE_ONDRAG, NavItemI_GetId( hItem ), (INT_PTR)&pt, (INT_PTR)&m_query_moving_type ) < 1 )
|
||
|
{
|
||
|
HNAVITEM hParent;
|
||
|
hParent = NavItemI_GetParent( hItem );
|
||
|
m_query_moving_type = ( NULL == hParent || NIS_ALLOWCHILDMOVE_I == NavItemI_GetStyle( hParent, NIS_ALLOWCHILDMOVE_I ) ) ?
|
||
|
ML_TYPE_TREEITEM : ML_TYPE_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
m_query_moving = 1;
|
||
|
m_query_moving_item = hItem;
|
||
|
m_query_moving_dragplace = NULL;
|
||
|
m_query_moving_lastdest = NULL;
|
||
|
m_query_moving_dragplaceisbelow = FALSE;
|
||
|
|
||
|
HWND hwndDlg = GetParent( NavCtrlI_GetHWND( hMngr ) );
|
||
|
NavCtrlI_MapPointsTo( hMngr, hwndDlg, &pt, 1 );
|
||
|
DisplayItemDragImage( hItem, NULL, hwndDlg, &pt );
|
||
|
SetCapture( g_hwnd );
|
||
|
}
|
||
|
|
||
|
static INT CALLBACK OnNavCtrl_GetImageIndex( HNAVCTRL hMngr, HNAVITEM hItem, INT imageType )
|
||
|
{
|
||
|
if ( NavItemI_HasChildren( hItem ) )
|
||
|
{
|
||
|
INT_PTR tag;
|
||
|
tag = ( NavItemI_HasChildrenReal( hItem ) ) ?
|
||
|
( ( NavItemI_IsExpanded( hItem ) ) ? MLTREEIMAGE_BRANCH_EXPANDED : MLTREEIMAGE_BRANCH_COLLAPSED ) :
|
||
|
MLTREEIMAGE_BRANCH_NOCHILD;
|
||
|
INT mlilIndex = MLImageListI_GetIndexFromTag( NavCtrlI_GetImageList( hMngr ), tag );
|
||
|
|
||
|
return ( -1 != mlilIndex ) ? mlilIndex : 0;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void OnWindowPosChanged( HWND hwnd, WINDOWPOS *pwp )
|
||
|
{
|
||
|
if ( SWP_NOSIZE != ( ( SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW ) & pwp->flags ) )
|
||
|
{
|
||
|
LayoutWindows( hwnd, divider_pos, ( 0 == ( SWP_NOREDRAW & pwp->flags ) ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HWND wa3wnd_fixwnd( HWND h )
|
||
|
{
|
||
|
if ( IsChild( h, g_hwnd ) )
|
||
|
return h; // if the library window is a child of this window, don't touch it
|
||
|
|
||
|
if ( IsChild( h, g_PEWindow ) )
|
||
|
return g_PEWindow; // if the playlist window is a child of this window, treat it as the playlist window
|
||
|
|
||
|
HWND hParent = (HWND)SENDWAIPC( plugin.hwndParent, IPC_GETDIALOGBOXPARENT, 0 );
|
||
|
if ( plugin.hwndParent != hParent && h == hParent )
|
||
|
h = plugin.hwndParent;
|
||
|
|
||
|
//DWORD pid;
|
||
|
//DWORD threadID = GetWindowThreadProcessId(h, &pid);
|
||
|
//if (pid != GetCurrentProcessId() || threadID != GetCurrentThreadId()) return h; // if other process, dont mangle
|
||
|
//char buf[64] = {0};
|
||
|
//GetClassName(h, buf, sizeof(buf) - 1);
|
||
|
//if (!strcmp(buf, "BaseWindow_RootWnd")) return plugin.hwndParent; // if a wa3 window, treat as main window
|
||
|
return h;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void CALLBACK OnDividerMoved( HWND hdiv, INT nPos, LPARAM param )
|
||
|
{
|
||
|
HWND hwndParent;
|
||
|
divider_pos = nPos;
|
||
|
hwndParent = GetParent( hdiv );
|
||
|
LayoutWindows( hwndParent, nPos, TRUE );
|
||
|
}
|
||
|
|
||
|
static void Navigation_DropHelper( HWND hwndDlg, HWND hwndNav, HNAVITEM hItemHit, UINT hitFlags, POINT pt )
|
||
|
{
|
||
|
if ( hItemHit && ( ( NAVHT_ONITEMINDENT_I | NAVHT_ONITEMRIGHT_I | NAVHT_ONITEM_I | NAVHT_ONITEMBUTTON_I ) & hitFlags ) )
|
||
|
{
|
||
|
RECT rc;
|
||
|
GetClientRect( hwndNav, &rc );
|
||
|
if ( !m_nav_autoscroll && ( rc.left <= pt.x && rc.right >= pt.x ) )
|
||
|
{
|
||
|
INT sbCommand;
|
||
|
if ( rc.top <= pt.y && pt.y < ( rc.top + 24 ) )
|
||
|
sbCommand = 1;
|
||
|
else if ( ( rc.bottom - 24 ) < pt.y && pt.y <= rc.bottom )
|
||
|
sbCommand = 2;
|
||
|
else
|
||
|
sbCommand = 0;
|
||
|
|
||
|
if ( sbCommand )
|
||
|
{
|
||
|
SCROLLINFO si = { 0 };
|
||
|
si.cbSize = sizeof( SCROLLINFO );
|
||
|
si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
|
||
|
if ( !GetScrollInfo( hwndNav, SB_VERT, &si ) )
|
||
|
ZeroMemory( &si, sizeof( SCROLLINFO ) );
|
||
|
|
||
|
if ( ( 1 == sbCommand && si.nMin < si.nPos ) || ( 2 == sbCommand && si.nMax >= (INT)( si.nPos + si.nPage ) ) )
|
||
|
{
|
||
|
if ( SetTimer( hwndDlg, TIMER_NAVAUTOSCROLL_ID, TIMER_NAVAUTOSCROLL_DELAY, NULL ) )
|
||
|
m_nav_autoscroll = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ( NAVHT_ONITEMBUTTON_I & hitFlags ) && m_nav_autoexpand_item != hItemHit && !NavItemI_IsExpanded( hItemHit ) )
|
||
|
{
|
||
|
KillTimer( hwndDlg, TIMER_NAVAUTOEXPAND_ID );
|
||
|
if ( SetTimer( hwndDlg, TIMER_NAVAUTOEXPAND_ID, TIMER_NAVAUTOEXPAND_DELAY, NULL ) )
|
||
|
m_nav_autoexpand_item = hItemHit;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int handleDragDropMove( HWND hwndDlg, int type, POINT p, int do_cursors )
|
||
|
{
|
||
|
BOOL valid = FALSE;
|
||
|
HWND h = WindowFromPoint( p );
|
||
|
HNAVITEM hItemPrevHilited = g_treedrag_lastSel;
|
||
|
g_treedrag_lastSel = NULL;
|
||
|
|
||
|
if ( h )
|
||
|
{
|
||
|
h = wa3wnd_fixwnd( h );
|
||
|
|
||
|
if ( IsChild( plugin.hwndParent, h ) )
|
||
|
h = plugin.hwndParent;
|
||
|
else if ( g_PEWindow && IsChild( g_PEWindow, h ) )
|
||
|
h = g_PEWindow;
|
||
|
else
|
||
|
{
|
||
|
HWND vid = (HWND)SendMessage( plugin.hwndParent, WM_WA_IPC, IPC_GETWND_VIDEO, IPC_GETWND );
|
||
|
if ( vid )
|
||
|
{
|
||
|
if ( h == vid || IsChild( vid, h ) )
|
||
|
h = plugin.hwndParent;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( h && ( h == plugin.hwndParent || h == g_PEWindow ) )
|
||
|
{
|
||
|
valid = ( type == ML_TYPE_ITEMRECORDLISTW || type == ML_TYPE_ITEMRECORDLIST ||
|
||
|
type == ML_TYPE_FILENAMES || type == ML_TYPE_STREAMNAMES ||
|
||
|
type == ML_TYPE_CDTRACKS ||
|
||
|
type == ML_TYPE_FILENAMESW || type == ML_TYPE_STREAMNAMESW );
|
||
|
}
|
||
|
else if ( h == NavCtrlI_GetHWND( hNavigation ) )
|
||
|
{
|
||
|
HNAVITEM hItemHit, hItemSel;
|
||
|
UINT hitFlags;
|
||
|
POINT pt = p;
|
||
|
MapWindowPoints( HWND_DESKTOP, h, &pt, 1 );
|
||
|
|
||
|
hItemHit = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
|
||
|
hItemSel = NavCtrlI_GetSelection( hNavigation );
|
||
|
|
||
|
Navigation_DropHelper( hwndDlg, h, hItemHit, hitFlags, pt );
|
||
|
if ( hItemHit && hItemHit != hItemSel && ( !m_query_moving_item || NavItemI_GetParent( m_query_moving_item ) != hItemHit ) )
|
||
|
{
|
||
|
valid = ( plugin_SendMessage( ML_MSG_TREE_ONDROPTARGET, NavItemI_GetId( hItemHit ), type, NULL ) > 0 );
|
||
|
if ( valid )
|
||
|
g_treedrag_lastSel = hItemHit;
|
||
|
}
|
||
|
}
|
||
|
else if ( IsWindow( m_curview_hwnd ) && IsWindow( h ) && ( h == m_curview_hwnd || IsChild( m_curview_hwnd, h ) ) )
|
||
|
{
|
||
|
mlDropItemStruct dis = { 0, };
|
||
|
dis.type = type;
|
||
|
dis.p = p;
|
||
|
while ( 1 )
|
||
|
{
|
||
|
SendMessage( h, WM_ML_CHILDIPC, (WPARAM)&dis, ML_CHILDIPC_DROPITEM );
|
||
|
|
||
|
if ( dis.result || h == m_curview_hwnd )
|
||
|
break;
|
||
|
|
||
|
h = GetParent( h ); // traverse up the tree
|
||
|
}
|
||
|
|
||
|
valid = dis.result > 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( g_treedrag_lastSel != hItemPrevHilited )
|
||
|
{
|
||
|
ImageList_DragShowNolock( FALSE );
|
||
|
if ( hItemPrevHilited )
|
||
|
NavItemI_SetState( hItemPrevHilited, 0, NIS_DROPHILITED_I );
|
||
|
|
||
|
if ( g_treedrag_lastSel )
|
||
|
NavItemI_SetState( g_treedrag_lastSel, NIS_DROPHILITED_I, NIS_DROPHILITED_I );
|
||
|
|
||
|
NavCtrlI_Update( hNavigation );
|
||
|
ImageList_DragShowNolock( TRUE );
|
||
|
}
|
||
|
|
||
|
if ( do_cursors )
|
||
|
SetCursor( ( valid ) ? hDragNDropCursor : LoadCursor( NULL, IDC_NO ) );
|
||
|
|
||
|
return valid;
|
||
|
}
|
||
|
|
||
|
static void CancelNavigationMove( void )
|
||
|
{
|
||
|
m_query_moving_dragplace = NULL;
|
||
|
ImageList_DragShowNolock( FALSE );
|
||
|
NavCtrlI_SetInsertMark( hNavigation, NULL, FALSE );
|
||
|
NavCtrlI_Update( hNavigation );
|
||
|
ImageList_DragShowNolock( TRUE );
|
||
|
}
|
||
|
|
||
|
static void OnInitMenuPopUp( HMENU menu );
|
||
|
static void OnDisplayChange( HWND hwndDlg, UINT imgDepth, UINT hRes, UINT vRes );
|
||
|
static int OnInitDialog( HWND hwndDlg );
|
||
|
static void OnDestroy( HWND hwndDlg );
|
||
|
static void OnClose( HWND hwndDlg );
|
||
|
static void OnSize( HWND hwndDlg, UINT type, int cx, int cy );
|
||
|
static void OnShowWindow( HWND hwndDlg, BOOL fShow );
|
||
|
LRESULT OnMediaLibraryIPC( HWND hwndDlg, WPARAM wParam, LPARAM lParam );
|
||
|
static void OnGetMaxMinInfo( MINMAXINFO *info );
|
||
|
static void OnBtnLibraryClick( HWND hwndBtn );
|
||
|
|
||
|
static HWND hwndTweak = NULL;
|
||
|
static BOOL CALLBACK RatingTweak_OnApplyChanges( UINT fStyle, BOOL bClosing )
|
||
|
{
|
||
|
ratingGlobalStyle = fStyle;
|
||
|
g_config->WriteInt( L"rating_style", ratingGlobalStyle );
|
||
|
|
||
|
MLRatingColumnI_Update();
|
||
|
|
||
|
if ( IsWindow( m_curview_hwnd ) )
|
||
|
PostMessage( m_curview_hwnd, WM_DISPLAYCHANGE, 0, MAKELPARAM( 0, 0 ) );
|
||
|
|
||
|
if ( bClosing )
|
||
|
hwndTweak = NULL;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static void OnTimer_NavAutoScroll( HWND hwndDlg )
|
||
|
{
|
||
|
RECT rc;
|
||
|
POINT pt;
|
||
|
HWND hwndNav = NavCtrlI_GetHWND( hNavigation );
|
||
|
INT command = 0;
|
||
|
|
||
|
KillTimer( hwndDlg, TIMER_NAVAUTOSCROLL_ID );
|
||
|
|
||
|
if ( !hwndNav || !IsWindowVisible( hwndNav ) )
|
||
|
{
|
||
|
m_nav_autoscroll = FALSE;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
GetCursorPos( &pt );
|
||
|
NavCtrlI_MapPointsFrom( hNavigation, HWND_DESKTOP, &pt, 1 );
|
||
|
|
||
|
GetClientRect( hwndNav, &rc );
|
||
|
|
||
|
if ( rc.left <= pt.x && rc.right >= pt.x )
|
||
|
{
|
||
|
if ( rc.top <= pt.y && pt.y < ( rc.top + 24 ) )
|
||
|
command = 1;
|
||
|
else if ( ( rc.bottom - 24 ) < pt.y && pt.y <= rc.bottom )
|
||
|
command = 2;
|
||
|
}
|
||
|
|
||
|
if ( command )
|
||
|
{
|
||
|
SCROLLINFO si = { 0 };
|
||
|
si.cbSize = sizeof( SCROLLINFO );
|
||
|
si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
|
||
|
if ( !GetScrollInfo( hwndNav, SB_VERT, &si ) )
|
||
|
ZeroMemory( &si, sizeof( SCROLLINFO ) );
|
||
|
|
||
|
if ( ( 1 == command && si.nMin == si.nPos ) || ( 2 == command && si.nMax < (INT)( si.nPos + si.nPage ) ) )
|
||
|
command = 0;
|
||
|
else
|
||
|
{
|
||
|
ImageList_DragShowNolock( FALSE );
|
||
|
SendMessageW( hwndNav, WM_VSCROLL, MAKEWPARAM( ( 1 == command ) ? SB_LINEUP : SB_LINEDOWN, 0 ), NULL );
|
||
|
NavCtrlI_Update( hNavigation );
|
||
|
ImageList_DragShowNolock( TRUE );
|
||
|
SetTimer( hwndDlg, TIMER_NAVAUTOSCROLL_ID, TIMER_NAVAUTOSCROLL_DELAY, NULL );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !command )
|
||
|
m_nav_autoscroll = FALSE;
|
||
|
}
|
||
|
|
||
|
static void OnTimer_NavAutoExpand( HWND hwndDlg )
|
||
|
{
|
||
|
POINT pt;
|
||
|
HWND hwndNav = NavCtrlI_GetHWND( hNavigation );
|
||
|
HNAVITEM hItem;
|
||
|
UINT hitFlags;
|
||
|
|
||
|
KillTimer( hwndDlg, TIMER_NAVAUTOEXPAND_ID );
|
||
|
|
||
|
if ( !hwndNav || !IsWindowVisible( hwndNav ) )
|
||
|
return;
|
||
|
|
||
|
GetCursorPos( &pt );
|
||
|
NavCtrlI_MapPointsFrom( hNavigation, HWND_DESKTOP, &pt, 1 );
|
||
|
|
||
|
hItem = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
|
||
|
|
||
|
if ( NAVHT_ONITEMBUTTON_I & hitFlags && hItem == m_nav_autoexpand_item )
|
||
|
{
|
||
|
ImageList_DragShowNolock( FALSE );
|
||
|
NavCtrlI_SetInsertMark( hNavigation, NULL, FALSE );
|
||
|
NavItemI_Expand( hItem, NAVITEM_EXPAND_I );
|
||
|
NavCtrlI_Update( hNavigation );
|
||
|
ImageList_DragShowNolock( TRUE );
|
||
|
}
|
||
|
m_nav_autoexpand_item = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void OnTimer( HWND hwndDlg, UINT_PTR idTimer )
|
||
|
{
|
||
|
switch ( idTimer )
|
||
|
{
|
||
|
case TIMER_NAVAUTOSCROLL_ID: OnTimer_NavAutoScroll( hwndDlg ); break;
|
||
|
case TIMER_NAVAUTOEXPAND_ID: OnTimer_NavAutoExpand( hwndDlg ); break;
|
||
|
case TIMER_UNBLOCKACCELTOGGLE_ID:
|
||
|
KillTimer( hwndDlg, idTimer );
|
||
|
RemoveProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static HMLIMGLST CreateNavigationImages( HMLIMGFLTRMNGR filterManager )
|
||
|
{
|
||
|
MLIMAGESOURCE_I is = { 0 };
|
||
|
static INT resourceId[] = { IDB_TREEITEM_DEFAULT, IDB_TREEITEM_COLLAPSED, IDB_TREEITEM_EXPANDED, IDB_TREEITEM_NOCHILD };
|
||
|
static INT_PTR imageTag[] = { MLTREEIMAGE_DEFAULT, MLTREEIMAGE_BRANCH_COLLAPSED, MLTREEIMAGE_BRANCH_EXPANDED, MLTREEIMAGE_BRANCH_NOCHILD };
|
||
|
HMLIMGLST hmlil = MLImageListI_Create( 16, 16, 24, 30, 2, 3, filterManager );
|
||
|
|
||
|
if ( !hmlil )
|
||
|
return NULL;
|
||
|
|
||
|
is.bpp = 24;
|
||
|
is.hInst = plugin.hDllInstance;
|
||
|
is.type = SRC_TYPE_BMP_I;
|
||
|
is.flags = ISF_FORCE_BPP_I;
|
||
|
for ( INT index = 0; index < sizeof( resourceId ) / sizeof( resourceId[ 0 ] ); index++ )
|
||
|
{
|
||
|
is.lpszName = MAKEINTRESOURCEW( resourceId[ index ] );
|
||
|
MLImageListI_Add( hmlil, &is, MLIF_FILTER1_UID, imageTag[ index ] );
|
||
|
}
|
||
|
return hmlil;
|
||
|
}
|
||
|
|
||
|
static void OnMouseMove( HWND hwndDlg, POINT pt, UINT flags )
|
||
|
{
|
||
|
RECT rc;
|
||
|
if ( !m_query_moving ) return;
|
||
|
|
||
|
MapWindowPoints( hwndDlg, HWND_DESKTOP, &pt, 1 );
|
||
|
|
||
|
GetWindowRect( hwndDlg, &rc );
|
||
|
ImageList_DragMove( pt.x - rc.left, pt.y - rc.top );
|
||
|
|
||
|
HWND hWndHit = WindowFromPoint( pt );
|
||
|
|
||
|
if ( hWndHit == NavCtrlI_GetHWND( hNavigation ) )
|
||
|
{
|
||
|
POINT ptMy = pt;
|
||
|
UINT hitFlags;
|
||
|
HNAVITEM hItem;
|
||
|
|
||
|
MapWindowPoints( HWND_DESKTOP, hWndHit, &ptMy, 1 );
|
||
|
|
||
|
hItem = NavCtrlI_HitTest( hNavigation, &ptMy, &hitFlags );
|
||
|
|
||
|
if ( !hItem )
|
||
|
{
|
||
|
HNAVITEM hItemLast;
|
||
|
hItemLast = NavCtrlI_GetLastVisible( hNavigation );
|
||
|
if ( hItemLast )
|
||
|
{
|
||
|
RECT ri;
|
||
|
if ( NavItemI_GetRect( hItemLast, &ri, FALSE ) && ri.bottom < ptMy.y )
|
||
|
{
|
||
|
HNAVITEM hMovingParent, hLastParent;
|
||
|
hMovingParent = NavItemI_GetParent( m_query_moving_item );
|
||
|
while ( NULL != ( hLastParent = NavItemI_GetParent( hItemLast ) ) && hLastParent != hMovingParent ) hItemLast = hLastParent;
|
||
|
if ( hMovingParent == hLastParent )
|
||
|
{
|
||
|
hItem = hItemLast;
|
||
|
hitFlags = NAVHT_ONITEM_I;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ( NAVHT_ONITEMINDENT_I | NAVHT_ONITEMRIGHT_I | NAVHT_ONITEM_I | NAVHT_ONITEMBUTTON_I ) & hitFlags )
|
||
|
{
|
||
|
HNAVITEM tempItem;
|
||
|
|
||
|
Navigation_DropHelper( hwndDlg, hWndHit, hItem, hitFlags, ptMy );
|
||
|
|
||
|
if ( ML_TYPE_UNKNOWN == m_query_moving_type )
|
||
|
{
|
||
|
SetCursor( LoadCursor( NULL, IDC_NO ) );
|
||
|
return;
|
||
|
}
|
||
|
tempItem = hItem;
|
||
|
while ( tempItem && tempItem != m_query_moving_item ) tempItem = NavItemI_GetParent( tempItem );
|
||
|
if ( tempItem == m_query_moving_item )
|
||
|
hItem = m_query_moving_item;
|
||
|
|
||
|
if ( hItem )
|
||
|
{
|
||
|
BOOL hitBelow;
|
||
|
|
||
|
if ( NavItemI_GetParent( hItem ) != NavItemI_GetParent( m_query_moving_item ) )
|
||
|
{
|
||
|
// TODO: I think regular drag-n-drop goes here?
|
||
|
//SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)));
|
||
|
CancelNavigationMove();
|
||
|
m_query_moving_lastdest = NULL;
|
||
|
mlDropItemStruct dropItem;
|
||
|
ZeroMemory( &dropItem, sizeof( mlDropItemStruct ) );
|
||
|
dropItem.p = pt;
|
||
|
dropItem.type = m_query_moving_type;
|
||
|
OnMediaLibraryIPC( hwndDlg, (WPARAM)&dropItem, ML_IPC_HANDLEDRAG );
|
||
|
//handleDragDropMove(hwndDlg, m_query_moving_type, pt, 1);
|
||
|
//goto outside_window;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( g_treedrag_lastSel )
|
||
|
{
|
||
|
NavItemI_SetState( g_treedrag_lastSel, 0, NIS_DROPHILITED_I );
|
||
|
g_treedrag_lastSel = NULL;
|
||
|
}
|
||
|
|
||
|
NavItemI_GetRect( hItem, &rc, FALSE );
|
||
|
hitBelow = ( ptMy.y > ( rc.bottom - ( rc.bottom - rc.top ) / 2 ) );
|
||
|
|
||
|
SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) );
|
||
|
|
||
|
m_query_moving_lastdest = hItem;
|
||
|
|
||
|
if ( m_query_moving_dragplace != hItem || m_query_moving_dragplaceisbelow != hitBelow )
|
||
|
{
|
||
|
m_query_moving_dragplace = hItem;
|
||
|
m_query_moving_dragplaceisbelow = hitBelow;
|
||
|
ImageList_DragShowNolock( FALSE );
|
||
|
NavCtrlI_SetInsertMark( hNavigation, hItem, hitBelow );
|
||
|
NavCtrlI_Update( hNavigation );
|
||
|
ImageList_DragShowNolock( TRUE );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int type = ML_TYPE_TREEITEM;
|
||
|
bool canDrag;
|
||
|
|
||
|
CancelNavigationMove();
|
||
|
|
||
|
canDrag = ( m_query_moving_item &&
|
||
|
( plugin_SendMessage( ML_MSG_TREE_ONDRAG, NavItemI_GetId( m_query_moving_item ), (INT_PTR)&pt, (INT_PTR)&type ) < 0 ) );
|
||
|
|
||
|
if ( !canDrag )
|
||
|
{
|
||
|
mlDropItemStruct dropItem;
|
||
|
ZeroMemory( &dropItem, sizeof( mlDropItemStruct ) );
|
||
|
dropItem.p = pt;
|
||
|
dropItem.type = type;
|
||
|
OnMediaLibraryIPC( hwndDlg, (WPARAM)&dropItem, ML_IPC_HANDLEDRAG );
|
||
|
|
||
|
//pluginHandleIpcMessage(hwndDlg, ML_IPC_HANDLEDRAG, (WPARAM)&m);
|
||
|
//SetCursor(dropItem.result > 0 ? hDragNDropCursor : LoadCursor(NULL, IDC_NO));
|
||
|
//SetCursor(LoadCursor(NULL, IDC_NO));
|
||
|
}
|
||
|
|
||
|
m_query_moving_dragplace = NULL;
|
||
|
m_query_moving_lastdest = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void OnLButtonUp( HWND hwndDlg, POINT pt, UINT flags )
|
||
|
{
|
||
|
HWND hwndHit;
|
||
|
|
||
|
if ( !m_query_moving ) return;
|
||
|
|
||
|
SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) );
|
||
|
|
||
|
ImageList_DragLeave( hwndDlg );
|
||
|
ImageList_EndDrag();
|
||
|
|
||
|
if ( m_nav_dragitem_imagelist )
|
||
|
{
|
||
|
ImageList_Destroy( m_nav_dragitem_imagelist );
|
||
|
m_nav_dragitem_imagelist = NULL;
|
||
|
}
|
||
|
|
||
|
MapWindowPoints( hwndDlg, HWND_DESKTOP, &pt, 1 );
|
||
|
|
||
|
hwndHit = WindowFromPoint( pt );
|
||
|
|
||
|
if ( ML_TYPE_UNKNOWN != m_query_moving_type && hwndHit && m_query_moving_item )
|
||
|
{
|
||
|
if ( m_query_moving_dragplace )
|
||
|
{
|
||
|
//move item in the tree
|
||
|
|
||
|
if ( ML_TYPE_TREEITEM == m_query_moving_type && m_query_moving_item != m_query_moving_lastdest )
|
||
|
{
|
||
|
WORD orderOld;
|
||
|
orderOld = NavItemI_GetOrder( m_query_moving_item );
|
||
|
if ( NavItemI_Move( m_query_moving_item, m_query_moving_lastdest, m_query_moving_dragplaceisbelow ) )
|
||
|
{
|
||
|
plugin_SendMessage( ML_MSG_NAVIGATION_ONMOVE, (INT_PTR)m_query_moving_item, orderOld, NavItemI_GetOrder( m_query_moving_item ) );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HNAVITEM whereinsert;
|
||
|
whereinsert = m_query_moving_lastdest;
|
||
|
|
||
|
if ( !m_query_moving_dragplaceisbelow )
|
||
|
{
|
||
|
BOOL fTest;
|
||
|
fTest = ( whereinsert == m_query_moving_item );
|
||
|
whereinsert = NavItemI_GetPrevious( whereinsert );
|
||
|
|
||
|
if ( !whereinsert && !fTest )
|
||
|
whereinsert = NavItemI_GetParent( m_query_moving_lastdest );
|
||
|
}
|
||
|
|
||
|
if ( whereinsert && m_query_moving_item != whereinsert )
|
||
|
plugin_SendMessage( ML_MSG_TREE_ONDROP, NavItemI_GetId( m_query_moving_item ), (INT_PTR)&pt, NavItemI_GetId( whereinsert ) );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
plugin_SendMessage( ML_MSG_TREE_ONDROP, NavItemI_GetId( m_query_moving_item ), (INT_PTR)&pt, 0 );
|
||
|
}
|
||
|
m_query_moving = 0;
|
||
|
|
||
|
if ( g_treedrag_lastSel )
|
||
|
{
|
||
|
NavItemI_SetState( g_treedrag_lastSel, 0, NIS_DROPHILITED_I );
|
||
|
g_treedrag_lastSel = NULL;
|
||
|
}
|
||
|
|
||
|
if ( m_query_moving_dragplace )
|
||
|
CancelNavigationMove();
|
||
|
|
||
|
ReleaseCapture();
|
||
|
}
|
||
|
|
||
|
|
||
|
void listbuild( wchar_t **buf, int &buf_size, int &buf_pos, const wchar_t *tbuf )
|
||
|
{
|
||
|
if ( !*buf )
|
||
|
{
|
||
|
*buf = (wchar_t *)calloc( 4096, sizeof( wchar_t ) );
|
||
|
if ( *buf )
|
||
|
{
|
||
|
buf_size = 4096;
|
||
|
buf_pos = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buf_size = buf_pos = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int newsize = buf_pos + lstrlenW( tbuf ) + 1;
|
||
|
if ( newsize < buf_size )
|
||
|
{
|
||
|
size_t old_buf_size = buf_size;
|
||
|
buf_size = newsize + 4096;
|
||
|
wchar_t *data = (wchar_t *)realloc( *buf, ( buf_size + 1 ) * sizeof( wchar_t ) );
|
||
|
if ( data )
|
||
|
{
|
||
|
*buf = data;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data = (wchar_t *)malloc( ( buf_size + 1 ) * sizeof( wchar_t ) );
|
||
|
if ( data )
|
||
|
{
|
||
|
memcpy( data, *buf, sizeof( wchar_t ) * old_buf_size );
|
||
|
free( *buf );
|
||
|
*buf = data;
|
||
|
}
|
||
|
else
|
||
|
buf_size = old_buf_size;
|
||
|
}
|
||
|
}
|
||
|
StringCchCopyW( *buf + buf_pos, buf_size, tbuf );
|
||
|
buf_pos = newsize;
|
||
|
}
|
||
|
|
||
|
/*wchar_t * getSelectedList()
|
||
|
{
|
||
|
wchar_t* path=NULL;
|
||
|
int buf_pos=0, buf_size=0;
|
||
|
int download=-1;
|
||
|
while (GetDownload(download))
|
||
|
{
|
||
|
if(listContents[download]->f)
|
||
|
listbuild(&path,buf_size,buf_pos,listContents[download]->f->path);
|
||
|
}
|
||
|
if(path) path[buf_pos] = 0;
|
||
|
return path;
|
||
|
}*/
|
||
|
|
||
|
static void OnDragDrop( HWND hwndDlg, HDROP hdrop )
|
||
|
{
|
||
|
UINT hitFlags = NAVHT_NOWHERE_I;
|
||
|
POINT pt = { 0 };
|
||
|
DragQueryPoint( hdrop, &pt );
|
||
|
|
||
|
HNAVITEM hItemHit = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
|
||
|
if ( hItemHit )
|
||
|
{
|
||
|
if ( plugin_SendMessage( ML_MSG_TREE_ONDROPTARGET, NavItemI_GetId( hItemHit ), ML_TYPE_FILENAMESW, NULL ) > 0 )
|
||
|
{
|
||
|
wchar_t temp[ MAX_PATH ] = { 0 };
|
||
|
int y = DragQueryFileW( hdrop, 0xffffffff, temp, 1024 );
|
||
|
if ( y > 0 )
|
||
|
{
|
||
|
wchar_t *paths = NULL;
|
||
|
int buf_pos = 0, buf_size = 0;
|
||
|
for ( int x = 0; x < y; x++ )
|
||
|
{
|
||
|
if ( DragQueryFileW( hdrop, x, temp, MAX_PATH ) )
|
||
|
{
|
||
|
listbuild( &paths, buf_size, buf_pos, temp );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( paths )
|
||
|
{
|
||
|
paths[ buf_pos ] = 0;
|
||
|
plugin_SendMessage( ML_MSG_TREE_ONDROPTARGET, NavItemI_GetId( hItemHit ), ML_TYPE_FILENAMESW, (INT_PTR)paths );
|
||
|
|
||
|
if ( IsWindow( m_curview_hwnd ) )
|
||
|
SendMessage( m_curview_hwnd, WM_APP + 1, 0, 0 ); //update current view
|
||
|
|
||
|
free( paths );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DragFinish( hdrop );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void MlView_ShowWindow( HWND hwnd, BOOL fShow, UINT nStatus )
|
||
|
{
|
||
|
if ( SW_PARENTOPENING == nStatus )
|
||
|
{
|
||
|
BOOL fStored = ( 0 != g_config->ReadInt( L"visible", 1 ) );
|
||
|
if ( fShow != fStored )
|
||
|
{
|
||
|
PostMessageW( hwnd, WMML_SHOWCONTAINER, ( 0 == fStored ) ? SW_HIDE : SW_SHOWNA, 0 );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ShowWindow( hwnd, ( FALSE != fShow ) ? SW_SHOWNA : SW_HIDE );
|
||
|
|
||
|
if ( 0 == nStatus )
|
||
|
{
|
||
|
if ( NULL != g_config )
|
||
|
g_config->WriteInt( L"visible", ( FALSE != fShow ) );
|
||
|
|
||
|
UINT menuFlags = ( FALSE != fShow ) ? MF_CHECKED : MF_UNCHECKED;
|
||
|
menuFlags |= MF_BYCOMMAND;
|
||
|
|
||
|
INT szMenu[] = { 0, 4, };
|
||
|
for ( INT i = 0; i < ARRAYSIZE( szMenu ); i++ )
|
||
|
{
|
||
|
HMENU hMenu = (HMENU)SendMessage( plugin.hwndParent, WM_WA_IPC, szMenu[ i ], IPC_GET_HMENU );
|
||
|
if ( NULL != hMenu )
|
||
|
CheckMenuItem( hMenu, WA_MENUITEM_ID, menuFlags );
|
||
|
}
|
||
|
|
||
|
MLVisibleChanged( FALSE != fShow );
|
||
|
|
||
|
if ( FALSE != fShow )
|
||
|
{
|
||
|
SendMessageW( g_ownerwnd, 0x0127/*WM_CHANGEUISTATE*/, MAKEWPARAM( 1/*UIS_SET*/, 3/*(UISF_HIDEACCEL | UISF_HIDEFOCUS)*/ ), 0L );
|
||
|
HWND hRoot = GetAncestor( g_ownerwnd, GA_ROOT );
|
||
|
if ( NULL != hRoot )
|
||
|
SetForegroundWindow( hRoot );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static LRESULT MlView_OnContainerNotify( HWND hwnd, NMHDR *pnmh )
|
||
|
{
|
||
|
switch ( pnmh->code )
|
||
|
{
|
||
|
case EWN_SHOWWINDOW:
|
||
|
MlView_ShowWindow( hwnd, ( (EMBEDSHOW *)pnmh )->fShow, ( (EMBEDSHOW *)pnmh )->nStatus );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static LRESULT MlView_OnNotify( HWND hwnd, INT controlId, NMHDR *pnmh )
|
||
|
{
|
||
|
if ( pnmh->hwndFrom == g_ownerwnd )
|
||
|
{
|
||
|
return MlView_OnContainerNotify( hwnd, pnmh );
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static LRESULT MlView_OnContextMenu( HWND hwnd, HWND hOwner, POINTS pts )
|
||
|
{
|
||
|
HWND hNav = NavCtrlI_GetHWND( hNavigation );
|
||
|
|
||
|
if ( NULL != hNav && hOwner == hNav )
|
||
|
{
|
||
|
HNAVITEM hItem;
|
||
|
POINT pt;
|
||
|
POINTSTOPOINT( pt, pts );
|
||
|
|
||
|
if ( -1 == pt.x || -1 == pt.y )
|
||
|
{
|
||
|
hItem = NavCtrlI_GetSelection( hNavigation );
|
||
|
if ( NULL != hItem )
|
||
|
{
|
||
|
RECT itemRect;
|
||
|
if ( NavItemI_GetRect( hItem, &itemRect, FALSE ) )
|
||
|
{
|
||
|
pt.x = itemRect.left + 1;
|
||
|
pt.y = itemRect.top + 1;
|
||
|
MapWindowPoints( hNav, HWND_DESKTOP, &pt, 1 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UINT hitFlags;
|
||
|
MapWindowPoints( HWND_DESKTOP, hNav, &pt, 1 );
|
||
|
hItem = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
|
||
|
pt.x = pts.x;
|
||
|
pt.y = pts.y;
|
||
|
}
|
||
|
|
||
|
if ( NULL == hItem ) return 0;
|
||
|
|
||
|
UINT itemState = NavItemI_GetState( hItem, NIS_DROPHILITED_I | NIS_SELECTED_I );
|
||
|
|
||
|
if ( 0 == ( ( NIS_DROPHILITED_I | NIS_SELECTED_I ) & itemState ) )
|
||
|
NavItemI_SetState( hItem, NIS_DROPHILITED_I, NIS_DROPHILITED_I );
|
||
|
|
||
|
INT_PTR result = plugin_SendMessage( ML_MSG_NAVIGATION_CONTEXTMENU,
|
||
|
(INT_PTR)hItem,
|
||
|
(INT_PTR)hNav,
|
||
|
MAKELONG( pt.x, pt.y ) );
|
||
|
|
||
|
if ( 0 == ( ( NIS_DROPHILITED_I | NIS_SELECTED_I ) & itemState ) )
|
||
|
NavItemI_SetState( hItem, 0, NIS_DROPHILITED_I );
|
||
|
|
||
|
return ( 0 != result );
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static BOOL
|
||
|
MlView_OnHelp( HWND hwnd, HELPINFO *helpInfo )
|
||
|
{
|
||
|
// TODO review this for handling Shift+F1 as view specific help?
|
||
|
// make sure we're only doing it for the expect help actions
|
||
|
// i.e. not Ctrl+F1 which opens the global about dialog
|
||
|
if ( ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) )
|
||
|
return FALSE;
|
||
|
|
||
|
// for view specific handling, we use Shift+F1
|
||
|
if ( NULL != helpInfo && HELPINFO_WINDOW == helpInfo->iContextType && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) )
|
||
|
{
|
||
|
HWND navigationWindow;
|
||
|
navigationWindow = NavCtrlI_GetHWND( hNavigation );
|
||
|
|
||
|
if ( navigationWindow == helpInfo->hItemHandle )
|
||
|
{
|
||
|
HNAVITEM selectedItem;
|
||
|
selectedItem = NavCtrlI_GetSelection( hNavigation );
|
||
|
if ( NULL != selectedItem && 0 != plugin_SendMessage( ML_MSG_NAVIGATION_HELP, (INT_PTR)selectedItem, (INT_PTR)navigationWindow, MAKELONG( helpInfo->MousePos.x, helpInfo->MousePos.y ) ) )
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
// otherwise we treat it as a generic help request
|
||
|
return MediaLibrary_OpenHelpUrl( MEDIALIBRARY_HELP_URL );
|
||
|
}
|
||
|
|
||
|
INT_PTR CALLBACK dialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||
|
{
|
||
|
|
||
|
switch ( uMsg )
|
||
|
{
|
||
|
case WM_MOUSEMOVE:
|
||
|
case WM_LBUTTONUP:
|
||
|
{
|
||
|
POINT pt = { GET_X_LPARAM( lParam ),GET_Y_LPARAM( lParam ) };
|
||
|
if ( WM_MOUSEMOVE == uMsg )
|
||
|
OnMouseMove( hwndDlg, pt, (UINT)wParam );
|
||
|
else if ( WM_LBUTTONUP == uMsg )
|
||
|
OnLButtonUp( hwndDlg, pt, (UINT)wParam );
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch ( LOWORD( wParam ) )
|
||
|
{
|
||
|
case IDC_BTN_LIB: if ( BN_CLICKED == HIWORD( wParam ) ) OnBtnLibraryClick( (HWND)lParam ); break;
|
||
|
case IDM_LIBRARY_CONFIG: OpenMediaLibraryPreferences(); break;
|
||
|
case IDM_LIBRARY_HELP: MediaLibrary_OpenHelpUrl( MEDIALIBRARY_HELP_URL ); break;
|
||
|
case ID_TOGGLE_LIBRARY:
|
||
|
if ( 0 == GetProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP ) )
|
||
|
{
|
||
|
toggleVisible( 0 );
|
||
|
SetProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP, (HANDLE)(INT_PTR)1 );
|
||
|
SetTimer( hwndDlg, TIMER_UNBLOCKACCELTOGGLE_ID, TIMER_UNBLOCKACCELTOGGLE_DELAY, NULL );
|
||
|
}
|
||
|
break;
|
||
|
case ID_WINDOW_CLOSE:
|
||
|
if ( IsVisible() )
|
||
|
toggleVisible( 0 );
|
||
|
break;
|
||
|
case ID_SHOW_RATINGTWEAK:
|
||
|
if ( !IsWindow( hwndTweak ) )
|
||
|
hwndTweak = MLRatingColumnI_TweakDialog( hwndDlg, ratingGlobalStyle, RatingTweak_OnApplyChanges, TRUE );
|
||
|
else SetWindowPos( hwndTweak, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW );
|
||
|
break;
|
||
|
case ID_GO_TO_VIEW_SEARCHBAR:
|
||
|
SendMessage( m_curview_hwnd, WM_ML_CHILDIPC, 0, ML_CHILDIPC_GO_TO_SEARCHBAR );
|
||
|
break;
|
||
|
case ID_REFRESH_SEARCH:
|
||
|
SendMessage( m_curview_hwnd, WM_ML_CHILDIPC, 0, ML_CHILDIPC_REFRESH_SEARCH );
|
||
|
break;
|
||
|
case ID_NEW_PLAYLIST:
|
||
|
{
|
||
|
// only process if not in an edit control
|
||
|
// (as shift+insert is a legacy OS paste shortcut)
|
||
|
wchar_t szClass[ 32 ] = { 0 };
|
||
|
HWND hFocus = GetFocus();
|
||
|
if ( GetClassNameW( hFocus, szClass, sizeof( szClass ) / sizeof( szClass[ 0 ] ) ) &&
|
||
|
CSTR_EQUAL != CompareStringW( CSTR_INVARIANT, NORM_IGNORECASE, szClass, -1, WC_EDITW, -1 ) )
|
||
|
{
|
||
|
#define ID_MLFILE_NEWPLAYLIST 40359
|
||
|
SendMessageW( plugin.hwndParent, WM_COMMAND, MAKEWPARAM( ID_MLFILE_NEWPLAYLIST, 0 ), 0 );
|
||
|
}
|
||
|
else SendMessageW( hFocus, WM_PASTE, 0, 0L );
|
||
|
}
|
||
|
break;
|
||
|
case ID_SHOW_HELP:
|
||
|
// do nothing, just need to still F1 from Winamp
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
case WM_NOTIFY:
|
||
|
{
|
||
|
LRESULT result;
|
||
|
result = 0;
|
||
|
if ( !NavCtrlI_ProcessNotifications( hNavigation, (LPNMHDR)lParam, &result ) )
|
||
|
result = MlView_OnNotify( hwndDlg, (INT)wParam, (NMHDR *)lParam );
|
||
|
|
||
|
SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONGX86)(LONG_PTR)result );
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
case WM_CAPTURECHANGED:
|
||
|
{
|
||
|
POINT pt = { MAXLONG,MAXLONG };
|
||
|
OnLButtonUp( hwndDlg, pt, 0 );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case WM_DROPFILES: OnDragDrop( hwndDlg, (HDROP)wParam ); break;
|
||
|
case WM_INITMENUPOPUP: OnInitMenuPopUp( (HMENU)wParam ); return TRUE;
|
||
|
case WM_DISPLAYCHANGE: OnDisplayChange( hwndDlg, (UINT)wParam, LOWORD( lParam ), HIWORD( lParam ) ); return TRUE;
|
||
|
case WM_INITDIALOG: return OnInitDialog( hwndDlg );
|
||
|
case WM_DESTROY: OnDestroy( hwndDlg ); break;
|
||
|
case WM_WINDOWPOSCHANGED: OnWindowPosChanged( hwndDlg, (WINDOWPOS *)lParam ); return TRUE;
|
||
|
case WM_CLOSE: OnClose( hwndDlg ); break;
|
||
|
case WM_GETMINMAXINFO: OnGetMaxMinInfo( (LPMINMAXINFO)lParam ); return TRUE;
|
||
|
case WM_TIMER: OnTimer( hwndDlg, (UINT_PTR)wParam ); return TRUE;
|
||
|
case WM_ML_IPC:
|
||
|
return OnMediaLibraryIPC( hwndDlg, wParam, lParam );
|
||
|
case WM_USER + 0x200: SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, TRUE ); return TRUE;
|
||
|
case WM_USER + 0x201: g_rgnUpdate = (HRGN)lParam; return TRUE;// parent supports region updates. lParam is a HRGN to set HRGN coordinate mapped to parent client area (this message sent prior to WM_WINDOWPOSCHANGED.
|
||
|
case WM_SHOWWINDOW:
|
||
|
{
|
||
|
if ( wParam ) PostMessage( hwndDlg, WM_USER + 31, wParam, 0 );
|
||
|
else OnShowWindow( hwndDlg, (BOOL)wParam );
|
||
|
return TRUE;
|
||
|
}
|
||
|
case WM_USER + 30:
|
||
|
{
|
||
|
SetWindowRedraw( hwndDlg, FALSE );
|
||
|
DestroyWindow( m_curview_hwnd );
|
||
|
SetWindowRedraw( hwndDlg, TRUE );
|
||
|
CreateCurrentView( hwndDlg );
|
||
|
break;
|
||
|
}
|
||
|
case WM_USER + 31:
|
||
|
// double-pump this to work around slower plugins loading up
|
||
|
if ( !lParam )
|
||
|
PostMessage( hwndDlg, WM_USER + 31, wParam, 1 );
|
||
|
else
|
||
|
{
|
||
|
OnShowWindow( hwndDlg, (BOOL)wParam );
|
||
|
NavItemI_EnsureVisible( NavCtrlI_GetSelection( hNavigation ) );
|
||
|
}
|
||
|
break;
|
||
|
case WM_CONTEXTMENU: MSGRESULT( hwndDlg, MlView_OnContextMenu( hwndDlg, (HWND)wParam, MAKEPOINTS( lParam ) ) );
|
||
|
case WM_HELP: MSGRESULT( hwndDlg, MlView_OnHelp( hwndDlg, (HELPINFO *)lParam ) );
|
||
|
case WMML_SHOWCONTAINER: ShowWindow( g_ownerwnd, (INT)wParam ); return TRUE;
|
||
|
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void OnInitMenuPopUp( HMENU menu )
|
||
|
{
|
||
|
if ( main_sendtomenu || !main_sendto_hmenu || menu != main_sendto_hmenu )
|
||
|
return;
|
||
|
|
||
|
main_sendtomenu = new SendToMenu();
|
||
|
main_sendtomenu->buildmenu( menu, main_sendto_mode, 0 );
|
||
|
}
|
||
|
|
||
|
void OnDisplayChange( HWND hwndDlg, UINT imgDepth, UINT hRes, UINT vRes )
|
||
|
{
|
||
|
ResetColors( TRUE ); // must be first
|
||
|
MlStockObjects_Reset();
|
||
|
|
||
|
ratingGlobalStyle = g_config->ReadInt( L"rating_style", RATING_DEFAULT_STYLE );
|
||
|
MLRatingColumnI_Update();
|
||
|
|
||
|
if ( IsWindow( m_curview_hwnd ) )
|
||
|
{
|
||
|
RECT rc;
|
||
|
GetClientRect( m_curview_hwnd, &rc );
|
||
|
RedrawWindow( m_curview_hwnd, &rc, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN | RDW_ERASENOW/* | RDW_UPDATENOW*/ );
|
||
|
MLSkinnedWnd_SkinChanged( m_curview_hwnd, TRUE, TRUE );
|
||
|
SendNotifyMessageW( m_curview_hwnd, WM_DISPLAYCHANGE, imgDepth, MAKELPARAM( hRes, vRes ) );
|
||
|
}
|
||
|
|
||
|
NavCtrlI_UpdateLook( hNavigation );
|
||
|
MLSkinnedWnd_SkinChanged( GetDlgItem( hwndDlg, IDC_BTN_LIB ), TRUE, TRUE );
|
||
|
MLSkinnedWnd_SkinChanged( GetDlgItem( hwndDlg, IDC_VDELIM ), TRUE, TRUE );
|
||
|
MLSkinnedWnd_SkinChanged( GetDlgItem( hwndDlg, IDC_NO_VIEW ), TRUE, TRUE );
|
||
|
LayoutWindows( hwndDlg, divider_pos, TRUE );
|
||
|
}
|
||
|
|
||
|
#include "mldwm.h"
|
||
|
|
||
|
int OnInitDialog( HWND hwndDlg )
|
||
|
{
|
||
|
firstShow = TRUE;
|
||
|
MlStockObjects_Init();
|
||
|
|
||
|
if ( S_OK == MlDwm_LoadLibrary() )
|
||
|
{
|
||
|
DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED;
|
||
|
BOOL allow = FALSE;
|
||
|
MlDwm_SetWindowAttribute( GetParent( hwndDlg ), DWMWA_NCRENDERING_POLICY, &ncrp, sizeof( ncrp ) );
|
||
|
MlDwm_SetWindowAttribute( GetParent( hwndDlg ), DWMWA_ALLOW_NCPAINT, &allow, sizeof( allow ) );
|
||
|
}
|
||
|
|
||
|
MLSkinWindow2( hwndDlg, hwndDlg, SKINNEDWND_TYPE_DIALOG, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS );
|
||
|
HWND hctrl = GetDlgItem( hwndDlg, IDC_BTN_LIB );
|
||
|
MLSkinWindow2( hwndDlg, hctrl, SKINNEDWND_TYPE_BUTTON, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS );
|
||
|
|
||
|
hctrl = GetDlgItem( hwndDlg, IDC_VDELIM );
|
||
|
MLSkinWindow2( hwndDlg, hctrl, SKINNEDWND_TYPE_DIVIDER, SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWDIV_VERT );
|
||
|
MLSkinnedDivider_SetCallback( hctrl, OnDividerMoved, NULL );
|
||
|
|
||
|
hctrl = GetDlgItem( hwndDlg, IDC_NO_VIEW );
|
||
|
MLSkinWindow2( hwndDlg, hctrl, SKINNEDWND_TYPE_STATIC, SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWDIV_VERT );
|
||
|
|
||
|
if ( !hmlifMngr ) // Initialize Image Filter manager
|
||
|
{
|
||
|
hmlifMngr = MLImageFilterI_CreateManager( 8, 4 );
|
||
|
if ( hmlifMngr )
|
||
|
{
|
||
|
RegisterImageFilters( hmlifMngr );
|
||
|
SkinnedButton::RegisterImageFilter( hmlifMngr );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !hNavigation )
|
||
|
{
|
||
|
hNavigation = NavCtrlI_Create( hwndDlg );
|
||
|
if ( hNavigation )
|
||
|
{
|
||
|
if ( !hmlilNavigation ) hmlilNavigation = CreateNavigationImages( hmlifMngr );
|
||
|
NavCtrlI_SetConfig( hNavigation, g_config );
|
||
|
NavCtrlI_SetImageList( hNavigation, hmlilNavigation );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_Selected, CALLBACK_ONSELECTED_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_Click, CALLBACK_ONCLICK_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_KeyDown, CALLBACK_ONKEYDOWN_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_BeginDrag, CALLBACK_ONBEGINDRAG_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_GetImageIndex, CALLBACK_ONGETIMAGEINDEX_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_BeginTitleEdit, CALLBACK_ONBEGINTITLEEDIT_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_EndTitleEdit, CALLBACK_ONENDTITLEEDIT_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavItem_Delete, CALLBACK_ONITEMDELETE_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavItem_CustomDraw, CALLBACK_ONITEMDRAW_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavItem_SetCursor, CALLBACK_ONSETCURSOR_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavItem_HitTest, CALLBACK_ONHITTEST_I );
|
||
|
NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_Destroy, CALLBACK_ONDESTROY_I );
|
||
|
hctrl = NavCtrlI_GetHWND( hNavigation );
|
||
|
SetWindowLongPtr( hctrl, GWLP_ID, IDC_NAVIGATION );
|
||
|
SetWindowLongPtr( hctrl, GWL_STYLE, GetWindowLongPtr( hctrl, GWL_STYLE ) | WS_GROUP );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( hNavigation )
|
||
|
SetWindowPos( GetDlgItem( hwndDlg, IDC_BTN_LIB ), NavCtrlI_GetHWND( hNavigation ), 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );
|
||
|
|
||
|
divider_pos = g_config->ReadInt( L"ldivpos", 135 );
|
||
|
|
||
|
if ( !hmlilRating )
|
||
|
{
|
||
|
hmlilRating = MLImageListI_Create( 44, 12, MLILC_COLOR24_I, 1, 1, 4, hmlifMngr );
|
||
|
if ( hmlilRating )
|
||
|
{
|
||
|
MLIMAGESOURCE_I is = { 0 };
|
||
|
is.hInst = plugin.hDllInstance;
|
||
|
is.lpszName = MAKEINTRESOURCEW( IDB_RATING );
|
||
|
is.type = SRC_TYPE_PNG_I;
|
||
|
MLImageListI_Add( hmlilRating, &is, MLIF_FILTER1_UID, 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ratingGlobalStyle = g_config->ReadInt( L"rating_style", RATING_DEFAULT_STYLE );
|
||
|
|
||
|
MLRatingColumnI_Initialize();
|
||
|
|
||
|
#ifdef CLOUD
|
||
|
if ( !hmlilCloud )
|
||
|
{
|
||
|
hmlilCloud = MLImageListI_Create( 16, 16, MLILC_COLOR24_I, 1, 1, 4, hmlifMngr );
|
||
|
if ( hmlilCloud )
|
||
|
{
|
||
|
MLIMAGESOURCE_I is = { 0 };
|
||
|
is.hInst = plugin.hDllInstance;
|
||
|
is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_IS_IN );
|
||
|
is.type = SRC_TYPE_PNG_I;
|
||
|
MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
|
||
|
|
||
|
is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_PARTIAL );
|
||
|
MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
|
||
|
|
||
|
is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_UNAVAIL );
|
||
|
MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
|
||
|
|
||
|
is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_UPLOAD );
|
||
|
MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
|
||
|
|
||
|
is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_UPLOADING );
|
||
|
MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MLCloudColumnI_Initialize();
|
||
|
#endif
|
||
|
|
||
|
OnDisplayChange( hwndDlg, 0, 0, 0 );
|
||
|
|
||
|
HACCEL hAccel = WASABI_API_LOADACCELERATORSW( IDR_ACCELERATOR_GLOBAL );
|
||
|
if ( hAccel )
|
||
|
WASABI_API_APP->app_addAccelerators( hwndDlg, &hAccel, 1, TRANSLATE_MODE_GLOBAL );
|
||
|
|
||
|
hAccel = WASABI_API_LOADACCELERATORSW( IDR_ACCELERATOR_MAIN );
|
||
|
if ( hAccel )
|
||
|
WASABI_API_APP->app_addAccelerators( hwndDlg, &hAccel, 1, TRANSLATE_MODE_CHILD );
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static void OnDestroy( HWND hwndDlg )
|
||
|
{
|
||
|
HNAVITEM hItem = NavCtrlI_GetSelection( hNavigation );
|
||
|
if ( hItem )
|
||
|
{
|
||
|
wchar_t name[ 1024 ] = { 0 };
|
||
|
if ( NavItemI_GetFullName( hItem, name, 1024 ) )
|
||
|
g_config->WriteString( "last_view", AutoChar( name, CP_UTF8 ) );
|
||
|
}
|
||
|
|
||
|
g_config->WriteInt( L"ldivpos", divider_pos );
|
||
|
|
||
|
NavCtrlI_Destroy( hNavigation );
|
||
|
hNavigation = NULL;
|
||
|
MLImageListI_Destroy( hmlilNavigation );
|
||
|
hmlilNavigation = NULL;
|
||
|
MLImageFilterI_DestroyManager( hmlifMngr );
|
||
|
hmlifMngr = NULL;
|
||
|
MLImageListI_Destroy( hmlilRating );
|
||
|
hmlilRating = NULL;
|
||
|
MLImageListI_Destroy( hmlilCloud );
|
||
|
hmlilCloud = NULL;
|
||
|
|
||
|
RemoveProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP );
|
||
|
|
||
|
MlStockObjects_Free();
|
||
|
}
|
||
|
|
||
|
static void OnClose( HWND hwndDlg )
|
||
|
{
|
||
|
toggleVisible( 1 );
|
||
|
}
|
||
|
|
||
|
static void OnShowWindow( HWND hwndDlg, BOOL fShow )
|
||
|
{
|
||
|
if ( firstShow && fShow )
|
||
|
{
|
||
|
firstShow = FALSE;
|
||
|
|
||
|
MLVisibleChanged( TRUE );
|
||
|
// setting things to a more user friendly default than just the Local Media view
|
||
|
char *lastTitleA = g_config->ReadString( "last_view", "Local Media/Audio" );
|
||
|
|
||
|
HNAVITEM hDefItem = NULL;
|
||
|
if ( lastTitleA && *lastTitleA )
|
||
|
{
|
||
|
wchar_t textW[ 2048 ] = { 0 };
|
||
|
if ( MultiByteToWideCharSZ( CP_UTF8, 0, lastTitleA, -1, textW, 2048 ) )
|
||
|
hDefItem = NavCtrlI_FindItemByFullName( hNavigation, LOCALE_INVARIANT, NICF_INVARIANT_I | NICF_DISPLAY_I | NICF_IGNORECASE_I, textW, -1, TRUE );
|
||
|
}
|
||
|
|
||
|
if ( !hDefItem )
|
||
|
hDefItem = NavCtrlI_GetRoot( hNavigation );
|
||
|
|
||
|
NavItemI_Select( hDefItem );
|
||
|
NavCtrlI_Show( hNavigation, SW_SHOWNA );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LRESULT OnMediaLibraryIPC( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
|
||
|
{
|
||
|
SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONGX86)(LONG_PTR)pluginHandleIpcMessage( hwndDlg, (INT)lParam, (INT_PTR)wParam ) );
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void OnGetMaxMinInfo( MINMAXINFO *info )
|
||
|
{
|
||
|
info->ptMinTrackSize.x = 300;
|
||
|
info->ptMinTrackSize.y = 200;
|
||
|
}
|
||
|
|
||
|
void OnBtnLibraryClick( HWND hwndBtn )
|
||
|
{
|
||
|
RECT r;
|
||
|
GetWindowRect( hwndBtn, &r );
|
||
|
SendMessageW( hwndBtn, BM_SETSTATE, TRUE, 0L );
|
||
|
|
||
|
MediaLibrary_TrackPopup( GetSubMenu( g_context_menus, 0 ),
|
||
|
TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN | TPM_VERNEGANIMATION,
|
||
|
r.left, r.top,
|
||
|
GetParent( hwndBtn ) );
|
||
|
|
||
|
SendMessageW( hwndBtn, BM_SETSTATE, FALSE, 0L );
|
||
|
UpdateWindow( hwndBtn );
|
||
|
Sleep( 100 );
|
||
|
MSG msg;
|
||
|
while ( PeekMessageW( &msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ); //eat return
|
||
|
}
|