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

📄 ctrllibrarytileview.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// CtrlLibraryTileView.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 "LibraryFolders.h"
#include "AlbumFolder.h"
#include "Schema.h"
#include "CtrlLibraryFrame.h"
#include "CtrlLibraryTree.h"
#include "CtrlLibraryTileView.h"
#include "DlgFolderProperties.h"
#include "CoolInterface.h"
#include "ShellIcons.h"
#include "Skin.h"

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

BEGIN_MESSAGE_MAP(CLibraryTileView, CLibraryView)
	//{{AFX_MSG_MAP(CLibraryTileView)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_WM_VSCROLL()
	ON_WM_MOUSEWHEEL()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_CONTEXTMENU()
	ON_WM_CHAR()
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_ALBUM_OPEN, OnUpdateLibraryAlbumOpen)
	ON_COMMAND(ID_LIBRARY_ALBUM_OPEN, OnLibraryAlbumOpen)
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_ALBUM_DELETE, OnUpdateLibraryAlbumDelete)
	ON_COMMAND(ID_LIBRARY_ALBUM_DELETE, OnLibraryAlbumDelete)
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_ALBUM_PROPERTIES, OnUpdateLibraryAlbumProperties)
	ON_COMMAND(ID_LIBRARY_ALBUM_PROPERTIES, OnLibraryAlbumProperties)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CLibraryTileView construction

CLibraryTileView::CLibraryTileView()
{
	m_nCommandID	= ID_LIBRARY_VIEW_TILE;
	m_pszToolBar	= _T("CLibraryTileView");
}

CLibraryTileView::~CLibraryTileView()
{
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTileView create and destroy

BOOL CLibraryTileView::PreCreateWindow(CREATESTRUCT& cs) 
{
	return CLibraryView::PreCreateWindow( cs );
}

int CLibraryTileView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CLibraryView::OnCreate( lpCreateStruct ) == -1 ) return -1;
	
	m_szBlock.cx	= 252;
	m_szBlock.cy	= 56;
	m_nColumns		= 1;
	m_nRows			= 0;
	
	m_pList			= NULL;
	m_nCount		= 0;
	m_nBuffer		= 0;
	m_nScroll		= 0;
	m_nSelected		= 0;
	m_pFocus		= NULL;
	m_pFirst		= NULL;
	m_bDrag			= FALSE;
	
	return 0;
}

void CLibraryTileView::OnDestroy() 
{
	Clear();
	CLibraryView::OnDestroy();
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTileView view operations

BOOL CLibraryTileView::CheckAvailable(CLibraryTreeItem* pSel)
{
	m_bAvailable = FALSE;
	
	if ( pSel != NULL && pSel->m_pSelNext == NULL && pSel->m_pVirtual != NULL )
	{
		m_bAvailable = ( pSel->m_pVirtual->GetFileCount() == 0 );
	}
	
	return m_bAvailable;
}

void CLibraryTileView::Update()
{
	CLibraryTreeItem* pFolders	= GetFolderSelection();
	CAlbumFolder* pFolder		= NULL;

	if ( pFolders == NULL || pFolders->m_pVirtual == NULL )
	{
		pFolder = Library.GetAlbumRoot();
	}
	else
	{
		if (	pFolders == NULL || pFolders->m_pSelNext != NULL ||
				pFolders->m_pVirtual == NULL ||
				pFolders->m_pVirtual->GetFileCount() > 0 )
		{
			if ( m_nCount > 0 )
			{
				Clear();
				Invalidate();
			}

			return;
		}

		pFolder = pFolders->m_pVirtual;
	}

	DWORD nCookie = GetFolderCookie();
	BOOL bChanged = FALSE;

	CLibraryTileItem** pList = m_pList + m_nCount - 1;

	for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
	{
		CLibraryTileItem* pTile	= *pList;

		if ( pFolder->CheckFolder( pTile->m_pFolder ) )
		{
			bChanged |= pTile->Update();
			pTile->m_pFolder->m_nListCookie = nCookie;
		}
		else
		{
			if ( pTile->m_bSelected ) Select( pTile, TS_FALSE );
			if ( pTile == m_pFocus ) m_pFocus = NULL;
			if ( pTile == m_pFirst ) m_pFirst = NULL;
			
			delete pTile;
			MoveMemory( pList, pList + 1, 4 * ( m_nCount - nItem ) );
			m_nCount--;

			bChanged = TRUE;
		}
	}

	if ( bChanged )
	{
		CRect rcClient;
		GetClientRect( &rcClient );
		int nMax	= ( ( m_nCount + m_nColumns - 1 ) / m_nColumns ) * m_szBlock.cy;
		m_nScroll	= max( 0, min( m_nScroll, nMax - rcClient.Height() + 1 ) );
	}

	for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; )
	{
		CAlbumFolder* pChild = pFolder->GetNextFolder( pos );
		
		if ( pChild->m_nListCookie != nCookie )
		{
			CLibraryTileItem* pTile = new CLibraryTileItem( pChild );
			
			if ( m_nCount == m_nBuffer )
			{
				m_nBuffer += 64;
				CLibraryTileItem** pList = new CLibraryTileItem*[ 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++ ] = pTile;
			pChild->m_nListCookie = nCookie;
			bChanged = TRUE;
		}
	}

	if ( bChanged )
	{
		qsort( m_pList, m_nCount, 4, SortList );
		UpdateScroll();
	}
}

BOOL CLibraryTileView::Select(DWORD nObject)
{
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTileView item list management operations

void CLibraryTileView::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;

	m_pSelTile.RemoveAll();
	SelClear();
}

int CLibraryTileView::GetTileIndex(CLibraryTileItem* pTile) const
{
	CLibraryTileItem** pList = m_pList;

	for ( int nItem = 0 ; nItem < m_nCount ; nItem++, pList++ )
	{
		if ( *pList == pTile ) return nItem;
	}

	return -1;
}

BOOL CLibraryTileView::Select(CLibraryTileItem* pTile, TRISTATE bSelect)
{
	switch ( bSelect )
	{
	case TS_UNKNOWN:
		pTile->m_bSelected = ! pTile->m_bSelected;
		break;
	case TS_FALSE:
		if ( pTile->m_bSelected == FALSE ) return FALSE;
		pTile->m_bSelected = FALSE;
		break;
	case TS_TRUE:
		if ( pTile->m_bSelected == TRUE ) return FALSE;
		pTile->m_bSelected = TRUE;
		break;
	}

	if ( pTile->m_bSelected )
	{
		m_nSelected++;
		m_pSelTile.AddTail( pTile );
		SelAdd( (DWORD)pTile->m_pFolder );
	}
	else
	{
		m_nSelected--;
		if ( POSITION pos = m_pSelTile.Find( pTile ) )
		{
			m_pSelTile.RemoveAt( pos );
			SelRemove( (DWORD)pTile->m_pFolder );
		}
	}

	return TRUE;
}

BOOL CLibraryTileView::DeselectAll(CLibraryTileItem* pTile)
{
	CLibraryTileItem** pList = m_pList + m_nCount - 1;
	BOOL bChanged = FALSE;

	for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
	{
		if ( *pList != pTile )
		{
			if ( (*pList)->m_bSelected ) bChanged = Select( *pList, TS_FALSE );
		}
	}

	return bChanged;
}

BOOL CLibraryTileView::SelectTo(CLibraryTileItem* pTile)
{
	BOOL bChanged = FALSE;

	if ( pTile )
	{
		m_pFocus = pTile;

		int nFirst	= GetTileIndex( m_pFirst );
		int nFocus	= GetTileIndex( 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;

		Highlight( m_pFocus );
	}
	else if (	( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0 &&
				( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) == 0 )
	{
		bChanged = DeselectAll();
	}

	if ( m_nSelected == 0 ) m_pFirst = NULL;

	return bChanged;
}

void CLibraryTileView::SelectTo(int nDelta)
{
	if ( m_nCount == 0 ) return;

	int nFocus = GetTileIndex( 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();
}

void CLibraryTileView::Highlight(CLibraryTileItem* pItem)
{
	CRect rcClient, rcItem;

	GetClientRect( &rcClient );
	GetItemRect( pItem, &rcItem );

	if ( rcItem.top < rcClient.top )
	{
		ScrollBy( rcItem.top - rcClient.top );
	}
	else if ( rcItem.bottom > rcClient.bottom )
	{
		ScrollBy( rcItem.bottom - rcClient.bottom );
	}
}

int CLibraryTileView::SortList(LPCVOID pA, LPCVOID pB)
{
	CLibraryTileItem* ppA = *(CLibraryTileItem**)pA;
	CLibraryTileItem* ppB = *(CLibraryTileItem**)pB;
	return _tcsicoll( ppA->m_sTitle, ppB->m_sTitle );
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTileView message handlers

void CLibraryTileView::OnSize(UINT nType, int cx, int cy) 
{
	CLibraryView::OnSize( nType, cx, cy );
	
	m_nColumns	= cx / m_szBlock.cx;
	m_nRows		= cy / m_szBlock.cy + 1;
	
	m_nColumns = max( m_nColumns, 1 );
	
	UpdateScroll();
}

void CLibraryTileView::UpdateScroll()
{
	if ( m_nColumns == 0 ) return;

	SCROLLINFO pInfo;
	CRect rc;

	GetClientRect( &rc );

	pInfo.cbSize	= sizeof(pInfo);
	pInfo.fMask		= SIF_ALL & ~SIF_TRACKPOS;
	pInfo.nMin		= 0;
	pInfo.nMax		= ( ( m_nCount + m_nColumns - 1 ) / m_nColumns ) * m_szBlock.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 CLibraryTileView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	CRect rc;
	GetClientRect( &rc );

	SetFocus();

	switch ( nSBCode )
	{
	case SB_BOTTOM:
		ScrollTo( 0xFFFFFF );
		break;
	case SB_LINEDOWN:
		ScrollBy( 32 );
		break;
	case SB_LINEUP:
		ScrollBy( -32 );
		break;
	case SB_PAGEDOWN:
		ScrollBy( rc.Height() );
		break;
	case SB_PAGEUP:
		ScrollBy( -rc.Height() );
		break;
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		ScrollTo( nPos );
		break;
	case SB_TOP:
		ScrollTo( 0 );
		break;
	}
}

BOOL CLibraryTileView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	ScrollBy( zDelta * -m_szBlock.cy / WHEEL_DELTA / 2 );
	return TRUE;
}

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

void CLibraryTileView::ScrollTo(int nPosition)
{
	if ( nPosition == m_nScroll ) return;
	m_nScroll = nPosition;

	UpdateScroll();
	RedrawWindow( NULL, NULL, RDW_INVALIDATE );
}

void CLibraryTileView::OnPaint() 
{
	CPaintDC dc( this );
	
	CDC* pBuffer = CoolInterface.GetBuffer( dc, m_szBlock );
	CRect rcBuffer( 0, 0, m_szBlock.cx, m_szBlock.cy );
	
	CFont* pOldFont = (CFont*)pBuffer->SelectObject( &CoolInterface.m_fntNormal );
	pBuffer->SetBkMode( OPAQUE );
	pBuffer->SetBkColor( CoolInterface.m_crWindow );
	pBuffer->SetTextColor( CoolInterface.m_crText );
	
	CDC dcMem;
	dcMem.CreateCompatibleDC( &dc );
	
	CRect rcClient;
	GetClientRect( &rcClient );
	CPoint pt( rcClient.left, rcClient.top - m_nScroll );

⌨️ 快捷键说明

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