📄 ctrllibrarytileview.cpp
字号:
//
// 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 + -