⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrllibraryalbumview.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// CtrlLibraryAlbumView.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza 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.
//
// Shareaza 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 Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Library.h"
#include "SharedFile.h"
#include "AlbumFolder.h"
#include "Schema.h"
#include "SchemaCache.h"
#include "ShellIcons.h"
#include "CoolInterface.h"
#include "CtrlLibraryAlbumView.h"
#include "CtrlLibraryTree.h"
#include "CtrlLibraryFrame.h"
#include "CtrlLibraryTip.h"
#include "DlgFilePropertiesSheet.h"
#include "Skin.h"
#include "XML.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNCREATE(CLibraryAlbumView, CLibraryFileView)

BEGIN_MESSAGE_MAP(CLibraryAlbumView, CLibraryFileView)
	//{{AFX_MSG_MAP(CLibraryAlbumView)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_WM_MOUSEWHEEL()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONDOWN()
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

LPCTSTR		CLibraryAlbumView::m_pStaticStyle;
COLORREF	CLibraryAlbumView::m_crRows[2];


/////////////////////////////////////////////////////////////////////////////
// CLibraryAlbumView construction

CLibraryAlbumView::CLibraryAlbumView()
{
	m_nCommandID = ID_LIBRARY_VIEW_ALBUM;
}

CLibraryAlbumView::~CLibraryAlbumView()
{
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryAlbumView create and destroy

BOOL CLibraryAlbumView::PreCreateWindow(CREATESTRUCT& cs) 
{
	cs.style |= WS_VSCROLL;
	return CLibraryFileView::PreCreateWindow( cs );
}

int CLibraryAlbumView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CLibraryFileView::OnCreate( lpCreateStruct ) == -1 ) return -1;
	
	m_pList			= NULL;
	m_nCount		= 0;
	m_nBuffer		= 0;
	m_nScroll		= 0;
	
	m_nSelected		= 0;
	m_pFocus		= NULL;
	m_pFirst		= NULL;
	m_bDrag			= FALSE;
	
	CBitmap bmStar;
	bmStar.LoadBitmap( IDB_SMALL_STAR );
	m_pStars.Create( 12, 12, ILC_COLOR16|ILC_MASK, 6, 0 );
	m_pStars.Add( &bmStar, RGB( 0, 255, 0 ) );
	
	return 0;
}

void CLibraryAlbumView::OnDestroy() 
{
	Clear();
	CLibraryFileView::OnDestroy();
	m_pStars.DeleteImageList();
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryAlbumView view operations

void CLibraryAlbumView::Update()
{
	CLibraryTreeItem* pFolders = GetFolderSelection();
	
	m_pStaticStyle = m_pStyle;
	m_pStyle = NULL;
	
	if ( pFolders != NULL && pFolders->m_pVirtual != NULL &&
		 pFolders->m_pSelNext == NULL )
	{
		CAlbumFolder* pFolder = pFolders->m_pVirtual;
		
		if ( pFolder->m_sSchemaURI == CSchema::uriMusicAlbum )
		{
			m_pStyle = CSchema::uriMusicAlbum;
		}
		else if ( pFolder->m_sSchemaURI == CSchema::uriMusicArtist )
		{
			m_pStyle = CSchema::uriMusicArtist;
		}
	}
	
	CSchema* pSchema	= SchemaCache.Get( Settings.Library.FilterURI );
	DWORD nCookie		= GetFolderCookie();
	BOOL bChanged		= m_pStyle != m_pStaticStyle;
	
	if ( Settings.Library.ShowVirtual ) pSchema = NULL;
	
	CLibraryAlbumTrack** pList = m_pList + m_nCount - 1;
	
	for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
	{
		CLibraryAlbumTrack* pTrack	= *pList;
		CLibraryFile* pFile			= Library.LookupFile( pTrack->m_nIndex );
		
		if ( pFile != NULL && pFile->m_nSelectCookie == nCookie &&
			 pFile->IsAvailable() &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			bChanged |= pTrack->Update( pFile );
			pFile->m_nListCookie = nCookie;
		}
		else
		{
			if ( pTrack == m_pFocus ) m_pFocus = NULL;
			if ( pTrack == m_pFirst ) m_pFirst = NULL;
			if ( pTrack->m_bSelected ) Select( pTrack, TS_FALSE );
			delete pTrack;
			MoveMemory( pList, pList + 1, 4 * ( m_nCount - nItem ) );
			m_nCount--;
			bChanged = TRUE;
		}
	}
	
	if ( bChanged )
	{
		CRect rcClient;
		GetClientRect( &rcClient );
		int nMax	= m_nCount * m_szTrack.cy;
		m_nScroll	= max( 0, min( m_nScroll, nMax - rcClient.Height() + 1 ) );
	}
	
	for ( POSITION pos = LibraryMaps.GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = LibraryMaps.GetNextFile( pos );
		
		if ( pFile->m_nSelectCookie == nCookie &&
 			 pFile->m_nListCookie != nCookie &&
			 pFile->IsAvailable() &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			CLibraryAlbumTrack* pTrack = new CLibraryAlbumTrack( pFile );
			
			if ( m_nCount == m_nBuffer )
			{
				m_nBuffer += 64;
				CLibraryAlbumTrack** pList = new CLibraryAlbumTrack*[ m_nBuffer ];
				if ( m_nCount ) CopyMemory( pList, m_pList, 4 * m_nCount );
				if ( m_pList ) delete [] m_pList;
				m_pList = pList;
			}
			
			m_pList[ m_nCount++ ] = pTrack;
			pFile->m_nListCookie = nCookie;
			bChanged = TRUE;
		}
	}
	
	if ( bChanged )
	{
		m_pStaticStyle = m_pStyle;
		qsort( m_pList, m_nCount, 4, SortList );
		UpdateScroll();
	}
}

BOOL CLibraryAlbumView::Select(DWORD nObject)
{
	CRect rcClient, rcItem;
	
	CLibraryAlbumTrack** pList = m_pList + m_nCount - 1;
	
	for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
	{
		CLibraryAlbumTrack* pTrack = *pList;
		if ( pTrack->m_nIndex == nObject ) break;
	}
	
	if ( nItem == 0 ) return FALSE;
	
	m_pFocus = *pList;
	DeselectAll( m_pFocus );
	Select( m_pFocus );
	Invalidate();
	
	GetClientRect( &rcClient );
	GetItemRect( m_pFocus, &rcItem );
	
	if ( rcItem.top < rcClient.top )
	{
		ScrollBy( rcItem.top - rcClient.top );
	}
	else if ( rcItem.bottom > rcClient.bottom )
	{
		ScrollBy( rcItem.bottom - rcClient.bottom );
	}
	
	return TRUE;
}

DWORD CLibraryAlbumView::HitTestIndex(const CPoint& point) const
{
	CLibraryAlbumTrack* pTrack = HitTest( point );
	return ( pTrack ) ? pTrack->m_nIndex : 0;
}

int CLibraryAlbumView::SortList(LPCVOID pA, LPCVOID pB)
{
	CLibraryAlbumTrack* ppA = *(CLibraryAlbumTrack**)pA;
	CLibraryAlbumTrack* ppB = *(CLibraryAlbumTrack**)pB;
	
	if ( m_pStaticStyle == CSchema::uriMusicAlbum )
	{
		if ( ppA->m_nTrack != ppB->m_nTrack )
		{
			return ( ppA->m_nTrack < ppB->m_nTrack ) ? -1 : 1;
		}
		else
		{
			return _tcsicoll( ppA->m_sTitle, ppB->m_sTitle );
		}
	}
	else if ( m_pStaticStyle == CSchema::uriMusicArtist )
	{
		int nCompare = _tcsicoll( ppA->m_sAlbum, ppB->m_sAlbum );
		
		if ( nCompare )
		{
			return nCompare;
		}
		else
		{
			return _tcsicoll( ppA->m_sTitle, ppB->m_sTitle );
		}
	}
	else
	{
		int nCompare = _tcsicoll( ppA->m_sArtist, ppB->m_sArtist );
		
		if ( nCompare )
		{
			return nCompare;
		}
		else if ( nCompare = _tcsicoll( ppA->m_sAlbum, ppB->m_sAlbum ) )
		{
			return nCompare;
		}
		else
		{
			return _tcsicoll( ppA->m_sTitle, ppB->m_sTitle );
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryAlbumView item list management operations

void CLibraryAlbumView::Clear()
{
	for ( int nItem = 0 ; nItem < m_nCount ; nItem++ )
	{
		delete m_pList[ nItem ];
	}
	
	if ( m_pList ) delete [] m_pList;
	
	m_pList		= NULL;
	m_nCount	= 0;
	m_nBuffer	= 0;
	m_nScroll	= 0;
	m_nSelected	= 0;
	m_pFocus	= NULL;
	m_pFirst	= NULL;
	
	SelClear();
	m_pSelTrack.RemoveAll();
}

int CLibraryAlbumView::GetTrackIndex(CLibraryAlbumTrack* pTrack) const
{
	CLibraryAlbumTrack** pList = m_pList;
	
	for ( int nItem = 0 ; nItem < m_nCount ; nItem++, pList++ )
	{
		if ( *pList == pTrack ) return nItem;
	}
	
	return -1;
}

BOOL CLibraryAlbumView::Select(CLibraryAlbumTrack* pTrack, TRISTATE bSelect)
{
	switch ( bSelect )
	{
	case TS_UNKNOWN:
		pTrack->m_bSelected = ! pTrack->m_bSelected;
		break;
	case TS_FALSE:
		if ( pTrack->m_bSelected == FALSE ) return FALSE;
		pTrack->m_bSelected = FALSE;
		break;
	case TS_TRUE:
		if ( pTrack->m_bSelected == TRUE ) return FALSE;
		pTrack->m_bSelected = TRUE;
		break;
	}
	
	if ( pTrack->m_bSelected )
	{
		if ( m_pSelTrack.Find( pTrack ) == NULL )
		{
			m_nSelected++;
			SelAdd( pTrack->m_nIndex );
			m_pSelTrack.AddTail( pTrack );
		}
	}
	else
	{
		if ( POSITION pos = m_pSelTrack.Find( pTrack ) )
		{
			m_nSelected--;
			SelRemove( pTrack->m_nIndex );
			m_pSelTrack.RemoveAt( pos );
		}
	}
	
	return TRUE;
}

BOOL CLibraryAlbumView::DeselectAll(CLibraryAlbumTrack* pTrack)
{
	CLibraryAlbumTrack** pList = m_pList + m_nCount - 1;
	BOOL bChanged = FALSE;
	
	for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
	{
		if ( *pList != pTrack )
		{
			if ( (*pList)->m_bSelected ) bChanged = Select( *pList, TS_FALSE );
		}
	}
	
	return bChanged;
}

BOOL CLibraryAlbumView::SelectTo(CLibraryAlbumTrack* pTrack)
{
	BOOL bChanged = FALSE;
	
	if ( pTrack )
	{
		m_pFocus = pTrack;
		
		int nFirst	= GetTrackIndex( m_pFirst );
		int nFocus	= GetTrackIndex( m_pFocus );
		
		if ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 )
		{
			bChanged = Select( m_pFocus, TS_UNKNOWN );
		}
		else if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 )
		{
			bChanged = DeselectAll();
			
			if ( nFirst >= 0 && nFocus >= 0 )
			{
				if ( nFirst <= nFocus )
				{
					for ( ; nFirst <= nFocus ; nFirst++ ) Select( m_pList[ nFirst ], TS_TRUE );
				}
				else
				{
					for ( ; nFocus <= nFirst ; nFocus++ ) Select( m_pList[ nFocus ], TS_TRUE );
				}
				
				bChanged = TRUE;
			}
			else
			{
				bChanged |= Select( m_pFocus, TS_TRUE );
			}
		}
		else
		{
			if ( m_pFocus->m_bSelected == FALSE ) bChanged = DeselectAll( m_pFocus );
			bChanged |= Select( m_pFocus );
		}
		
		if ( m_nSelected == 1 && m_pFocus->m_bSelected ) m_pFirst = m_pFocus;
		
		CRect rcClient, rcItem;
		
		GetClientRect( &rcClient );
		GetItemRect( m_pFocus, &rcItem );
		
		if ( rcItem.top < rcClient.top )
		{
			ScrollBy( rcItem.top - rcClient.top );
		}
		else if ( rcItem.bottom > rcClient.bottom )
		{
			ScrollBy( rcItem.bottom - rcClient.bottom );
		}
	}
	else if (	( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0 &&
				( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) == 0 )
	{
		bChanged = DeselectAll();
	}
	
	if ( m_nSelected == 0 ) m_pFirst = NULL;
	
	return bChanged;
}

void CLibraryAlbumView::SelectTo(int nDelta)
{
	if ( m_nCount == 0 ) return;
	
	int nFocus = GetTrackIndex( m_pFocus );
	
	if ( nFocus < 0 )
	{
		nFocus = 0;
	}
	else
	{
		nFocus += nDelta;
		if ( nFocus < 0 ) nFocus = 0;
		if ( nFocus >= m_nCount ) nFocus = m_nCount - 1;
	}
	
	if ( SelectTo( m_pList[ nFocus ] ) ) Invalidate();
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryAlbumView message handlers

void CLibraryAlbumView::OnSize(UINT nType, int cx, int cy) 
{
	CLibraryFileView::OnSize( nType, cx, cy );
	
	m_szTrack.cx = cx;
	m_szTrack.cy = 22;
	m_nRows = cy / m_szTrack.cy;
}

void CLibraryAlbumView::UpdateScroll()
{
	SCROLLINFO pInfo;
	CRect rc;
	
	GetClientRect( &rc );
	
	pInfo.cbSize	= sizeof(pInfo);
	pInfo.fMask		= SIF_ALL & ~SIF_TRACKPOS;
	pInfo.nMin		= 0;
	pInfo.nMax		= m_nCount * m_szTrack.cy;
	pInfo.nPage		= rc.Height();
	pInfo.nPos		= m_nScroll = max( 0, min( m_nScroll, pInfo.nMax - (int)pInfo.nPage + 1 ) );
	
	SetScrollInfo( SB_VERT, &pInfo, TRUE );
	
	Invalidate();
}

void CLibraryAlbumView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	CRect rc;
	GetClientRect( &rc );
	
	SetFocus();
	
	switch ( nSBCode )
	{
	case SB_BOTTOM:
		ScrollTo( 0xFFFFFF );
		break;
	case SB_LINEDOWN:
		ScrollBy( m_szTrack.cy );
		break;
	case SB_LINEUP:
		ScrollBy( -m_szTrack.cy );
		break;
	case SB_PAGEDOWN:
		ScrollBy( rc.Height() );
		break;
	case SB_PAGEUP:
		ScrollBy( -rc.Height() );
		break;
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		{
			SCROLLINFO pScroll = { sizeof(SCROLLINFO), SIF_TRACKPOS };
			GetScrollInfo( SB_VERT, &pScroll );
			ScrollTo( pScroll.nTrackPos );
		}
		break;
	case SB_TOP:
		ScrollTo( 0 );
		break;
	}
}

BOOL CLibraryAlbumView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	ScrollBy( zDelta * -m_szTrack.cy / WHEEL_DELTA * 5 );
	return CLibraryFileView::OnMouseWheel( nFlags, zDelta, pt );
}

void CLibraryAlbumView::ScrollBy(int nDelta)
{
	ScrollTo( max( 0, m_nScroll + nDelta ) );
}

void CLibraryAlbumView::ScrollTo(int nPosition)
{
	if ( nPosition == m_nScroll ) return;
	m_nScroll = nPosition;
	
	UpdateScroll();
	RedrawWindow( NULL, NULL, RDW_INVALIDATE );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -