Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

CtrlLibraryTileView.cpp

Go to the documentation of this file.
00001 //
00002 // CtrlLibraryTileView.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Library.h"
00026 #include "LibraryFolders.h"
00027 #include "AlbumFolder.h"
00028 #include "Schema.h"
00029 #include "CtrlLibraryFrame.h"
00030 #include "CtrlLibraryTree.h"
00031 #include "CtrlLibraryTileView.h"
00032 #include "DlgFolderProperties.h"
00033 #include "CoolInterface.h"
00034 #include "ShellIcons.h"
00035 #include "Skin.h"
00036 
00037 #ifdef _DEBUG
00038 #define new DEBUG_NEW
00039 #undef THIS_FILE
00040 static char THIS_FILE[] = __FILE__;
00041 #endif
00042 
00043 BEGIN_MESSAGE_MAP(CLibraryTileView, CLibraryView)
00044         //{{AFX_MSG_MAP(CLibraryTileView)
00045         ON_WM_CREATE()
00046         ON_WM_DESTROY()
00047         ON_WM_SIZE()
00048         ON_WM_PAINT()
00049         ON_WM_VSCROLL()
00050         ON_WM_MOUSEWHEEL()
00051         ON_WM_LBUTTONDOWN()
00052         ON_WM_MOUSEMOVE()
00053         ON_WM_LBUTTONUP()
00054         ON_WM_RBUTTONDOWN()
00055         ON_WM_KEYDOWN()
00056         ON_WM_LBUTTONDBLCLK()
00057         ON_WM_CONTEXTMENU()
00058         ON_WM_CHAR()
00059         ON_UPDATE_COMMAND_UI(ID_LIBRARY_ALBUM_OPEN, OnUpdateLibraryAlbumOpen)
00060         ON_COMMAND(ID_LIBRARY_ALBUM_OPEN, OnLibraryAlbumOpen)
00061         ON_UPDATE_COMMAND_UI(ID_LIBRARY_ALBUM_DELETE, OnUpdateLibraryAlbumDelete)
00062         ON_COMMAND(ID_LIBRARY_ALBUM_DELETE, OnLibraryAlbumDelete)
00063         ON_UPDATE_COMMAND_UI(ID_LIBRARY_ALBUM_PROPERTIES, OnUpdateLibraryAlbumProperties)
00064         ON_COMMAND(ID_LIBRARY_ALBUM_PROPERTIES, OnLibraryAlbumProperties)
00065         //}}AFX_MSG_MAP
00066 END_MESSAGE_MAP()
00067 
00068 
00070 // CLibraryTileView construction
00071 
00072 CLibraryTileView::CLibraryTileView()
00073 {
00074         m_nCommandID    = ID_LIBRARY_VIEW_TILE;
00075         m_pszToolBar    = _T("CLibraryTileView");
00076 }
00077 
00078 CLibraryTileView::~CLibraryTileView()
00079 {
00080 }
00081 
00083 // CLibraryTileView create and destroy
00084 
00085 BOOL CLibraryTileView::PreCreateWindow(CREATESTRUCT& cs)
00086 {
00087         return CLibraryView::PreCreateWindow( cs );
00088 }
00089 
00090 int CLibraryTileView::OnCreate(LPCREATESTRUCT lpCreateStruct)
00091 {
00092         if ( CLibraryView::OnCreate( lpCreateStruct ) == -1 ) return -1;
00093 
00094         m_szBlock.cx    = 252;
00095         m_szBlock.cy    = 56;
00096         m_nColumns              = 1;
00097         m_nRows                 = 0;
00098 
00099         m_pList                 = NULL;
00100         m_nCount                = 0;
00101         m_nBuffer               = 0;
00102         m_nScroll               = 0;
00103         m_nSelected             = 0;
00104         m_pFocus                = NULL;
00105         m_pFirst                = NULL;
00106         m_bDrag                 = FALSE;
00107 
00108         return 0;
00109 }
00110 
00111 void CLibraryTileView::OnDestroy()
00112 {
00113         Clear();
00114         CLibraryView::OnDestroy();
00115 }
00116 
00118 // CLibraryTileView view operations
00119 
00120 BOOL CLibraryTileView::CheckAvailable(CLibraryTreeItem* pSel)
00121 {
00122         m_bAvailable = FALSE;
00123 
00124         if ( pSel != NULL && pSel->m_pSelNext == NULL && pSel->m_pVirtual != NULL )
00125         {
00126                 m_bAvailable = ( pSel->m_pVirtual->GetFileCount() == 0 );
00127         }
00128 
00129         return m_bAvailable;
00130 }
00131 
00132 void CLibraryTileView::Update()
00133 {
00134         CLibraryTreeItem* pFolders      = GetFolderSelection();
00135         CAlbumFolder* pFolder           = NULL;
00136 
00137         if ( pFolders == NULL || pFolders->m_pVirtual == NULL )
00138         {
00139                 pFolder = Library.GetAlbumRoot();
00140         }
00141         else
00142         {
00143                 if (    pFolders == NULL || pFolders->m_pSelNext != NULL ||
00144                                 pFolders->m_pVirtual == NULL ||
00145                                 pFolders->m_pVirtual->GetFileCount() > 0 )
00146                 {
00147                         if ( m_nCount > 0 )
00148                         {
00149                                 Clear();
00150                                 Invalidate();
00151                         }
00152 
00153                         return;
00154                 }
00155 
00156                 pFolder = pFolders->m_pVirtual;
00157         }
00158 
00159         DWORD nCookie = GetFolderCookie();
00160         BOOL bChanged = FALSE;
00161 
00162         CLibraryTileItem** pList = m_pList + m_nCount - 1;
00163 
00164         for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
00165         {
00166                 CLibraryTileItem* pTile = *pList;
00167 
00168                 if ( pFolder->CheckFolder( pTile->m_pFolder ) )
00169                 {
00170                         bChanged |= pTile->Update();
00171                         pTile->m_pFolder->m_nListCookie = nCookie;
00172                 }
00173                 else
00174                 {
00175                         if ( pTile->m_bSelected ) Select( pTile, TS_FALSE );
00176                         if ( pTile == m_pFocus ) m_pFocus = NULL;
00177                         if ( pTile == m_pFirst ) m_pFirst = NULL;
00178 
00179                         delete pTile;
00180                         MoveMemory( pList, pList + 1, 4 * ( m_nCount - nItem ) );
00181                         m_nCount--;
00182 
00183                         bChanged = TRUE;
00184                 }
00185         }
00186 
00187         if ( bChanged )
00188         {
00189                 CRect rcClient;
00190                 GetClientRect( &rcClient );
00191                 int nMax        = ( ( m_nCount + m_nColumns - 1 ) / m_nColumns ) * m_szBlock.cy;
00192                 m_nScroll       = max( 0, min( m_nScroll, nMax - rcClient.Height() + 1 ) );
00193         }
00194 
00195         for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; )
00196         {
00197                 CAlbumFolder* pChild = pFolder->GetNextFolder( pos );
00198 
00199                 if ( pChild->m_nListCookie != nCookie )
00200                 {
00201                         CLibraryTileItem* pTile = new CLibraryTileItem( pChild );
00202 
00203                         if ( m_nCount == m_nBuffer )
00204                         {
00205                                 m_nBuffer += 64;
00206                                 CLibraryTileItem** pList = new CLibraryTileItem*[ m_nBuffer ];
00207                                 if ( m_nCount ) CopyMemory( pList, m_pList, 4 * m_nCount );
00208                                 if ( m_pList ) delete [] m_pList;
00209                                 m_pList = pList;
00210                         }
00211 
00212                         m_pList[ m_nCount++ ] = pTile;
00213                         pChild->m_nListCookie = nCookie;
00214                         bChanged = TRUE;
00215                 }
00216         }
00217 
00218         if ( bChanged )
00219         {
00220                 qsort( m_pList, m_nCount, 4, SortList );
00221                 UpdateScroll();
00222         }
00223 }
00224 
00225 BOOL CLibraryTileView::Select(DWORD nObject)
00226 {
00227         return FALSE;
00228 }
00229 
00231 // CLibraryTileView item list management operations
00232 
00233 void CLibraryTileView::Clear()
00234 {
00235         for ( int nItem = 0 ; nItem < m_nCount ; nItem++ )
00236         {
00237                 delete m_pList[ nItem ];
00238         }
00239 
00240         if ( m_pList ) delete [] m_pList;
00241 
00242         m_pList         = NULL;
00243         m_nCount        = 0;
00244         m_nBuffer       = 0;
00245         m_nScroll       = 0;
00246         m_nSelected     = 0;
00247         m_pFocus        = NULL;
00248         m_pFirst        = NULL;
00249 
00250         m_pSelTile.RemoveAll();
00251         SelClear();
00252 }
00253 
00254 int CLibraryTileView::GetTileIndex(CLibraryTileItem* pTile) const
00255 {
00256         CLibraryTileItem** pList = m_pList;
00257 
00258         for ( int nItem = 0 ; nItem < m_nCount ; nItem++, pList++ )
00259         {
00260                 if ( *pList == pTile ) return nItem;
00261         }
00262 
00263         return -1;
00264 }
00265 
00266 BOOL CLibraryTileView::Select(CLibraryTileItem* pTile, TRISTATE bSelect)
00267 {
00268         switch ( bSelect )
00269         {
00270         case TS_UNKNOWN:
00271                 pTile->m_bSelected = ! pTile->m_bSelected;
00272                 break;
00273         case TS_FALSE:
00274                 if ( pTile->m_bSelected == FALSE ) return FALSE;
00275                 pTile->m_bSelected = FALSE;
00276                 break;
00277         case TS_TRUE:
00278                 if ( pTile->m_bSelected == TRUE ) return FALSE;
00279                 pTile->m_bSelected = TRUE;
00280                 break;
00281         }
00282 
00283         if ( pTile->m_bSelected )
00284         {
00285                 m_nSelected++;
00286                 m_pSelTile.AddTail( pTile );
00287                 SelAdd( (DWORD)pTile->m_pFolder );
00288         }
00289         else
00290         {
00291                 m_nSelected--;
00292                 if ( POSITION pos = m_pSelTile.Find( pTile ) )
00293                 {
00294                         m_pSelTile.RemoveAt( pos );
00295                         SelRemove( (DWORD)pTile->m_pFolder );
00296                 }
00297         }
00298 
00299         return TRUE;
00300 }
00301 
00302 BOOL CLibraryTileView::DeselectAll(CLibraryTileItem* pTile)
00303 {
00304         CLibraryTileItem** pList = m_pList + m_nCount - 1;
00305         BOOL bChanged = FALSE;
00306 
00307         for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
00308         {
00309                 if ( *pList != pTile )
00310                 {
00311                         if ( (*pList)->m_bSelected ) bChanged = Select( *pList, TS_FALSE );
00312                 }
00313         }
00314 
00315         return bChanged;
00316 }
00317 
00318 BOOL CLibraryTileView::SelectTo(CLibraryTileItem* pTile)
00319 {
00320         BOOL bChanged = FALSE;
00321 
00322         if ( pTile )
00323         {
00324                 m_pFocus = pTile;
00325 
00326                 int nFirst      = GetTileIndex( m_pFirst );
00327                 int nFocus      = GetTileIndex( m_pFocus );
00328 
00329                 if ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 )
00330                 {
00331                         bChanged = Select( m_pFocus, TS_UNKNOWN );
00332                 }
00333                 else if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 )
00334                 {
00335                         bChanged = DeselectAll();
00336 
00337                         if ( nFirst >= 0 && nFocus >= 0 )
00338                         {
00339                                 if ( nFirst <= nFocus )
00340                                 {
00341                                         for ( ; nFirst <= nFocus ; nFirst++ ) Select( m_pList[ nFirst ], TS_TRUE );
00342                                 }
00343                                 else
00344                                 {
00345                                         for ( ; nFocus <= nFirst ; nFocus++ ) Select( m_pList[ nFocus ], TS_TRUE );
00346                                 }
00347 
00348                                 bChanged = TRUE;
00349                         }
00350                         else
00351                         {
00352                                 bChanged |= Select( m_pFocus, TS_TRUE );
00353                         }
00354                 }
00355                 else
00356                 {
00357                         if ( m_pFocus->m_bSelected == FALSE ) bChanged = DeselectAll( m_pFocus );
00358                         bChanged |= Select( m_pFocus );
00359                 }
00360 
00361                 if ( m_nSelected == 1 && m_pFocus->m_bSelected ) m_pFirst = m_pFocus;
00362 
00363                 Highlight( m_pFocus );
00364         }
00365         else if (       ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0 &&
00366                                 ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) == 0 )
00367         {
00368                 bChanged = DeselectAll();
00369         }
00370 
00371         if ( m_nSelected == 0 ) m_pFirst = NULL;
00372 
00373         return bChanged;
00374 }
00375 
00376 void CLibraryTileView::SelectTo(int nDelta)
00377 {
00378         if ( m_nCount == 0 ) return;
00379 
00380         int nFocus = GetTileIndex( m_pFocus );
00381 
00382         if ( nFocus < 0 )
00383         {
00384                 nFocus = 0;
00385         }
00386         else
00387         {
00388                 nFocus += nDelta;
00389                 if ( nFocus < 0 ) nFocus = 0;
00390                 if ( nFocus >= m_nCount ) nFocus = m_nCount - 1;
00391         }
00392 
00393         if ( SelectTo( m_pList[ nFocus ] ) ) Invalidate();
00394 }
00395 
00396 void CLibraryTileView::Highlight(CLibraryTileItem* pItem)
00397 {
00398         CRect rcClient, rcItem;
00399 
00400         GetClientRect( &rcClient );
00401         GetItemRect( pItem, &rcItem );
00402 
00403         if ( rcItem.top < rcClient.top )
00404         {
00405                 ScrollBy( rcItem.top - rcClient.top );
00406         }
00407         else if ( rcItem.bottom > rcClient.bottom )
00408         {
00409                 ScrollBy( rcItem.bottom - rcClient.bottom );
00410         }
00411 }
00412 
00413 int CLibraryTileView::SortList(LPCVOID pA, LPCVOID pB)
00414 {
00415         CLibraryTileItem* ppA = *(CLibraryTileItem**)pA;
00416         CLibraryTileItem* ppB = *(CLibraryTileItem**)pB;
00417         return _tcsicoll( ppA->m_sTitle, ppB->m_sTitle );
00418 }
00419 
00421 // CLibraryTileView message handlers
00422 
00423 void CLibraryTileView::OnSize(UINT nType, int cx, int cy)
00424 {
00425         CLibraryView::OnSize( nType, cx, cy );
00426 
00427         m_nColumns      = cx / m_szBlock.cx;
00428         m_nRows         = cy / m_szBlock.cy + 1;
00429 
00430         m_nColumns = max( m_nColumns, 1 );
00431 
00432         UpdateScroll();
00433 }
00434 
00435 void CLibraryTileView::UpdateScroll()
00436 {
00437         if ( m_nColumns == 0 ) return;
00438 
00439         SCROLLINFO pInfo;
00440         CRect rc;
00441 
00442         GetClientRect( &rc );
00443 
00444         pInfo.cbSize    = sizeof(pInfo);
00445         pInfo.fMask             = SIF_ALL & ~SIF_TRACKPOS;
00446         pInfo.nMin              = 0;
00447         pInfo.nMax              = ( ( m_nCount + m_nColumns - 1 ) / m_nColumns ) * m_szBlock.cy;
00448         pInfo.nPage             = rc.Height();;
00449         pInfo.nPos              = m_nScroll = max( 0, min( m_nScroll, pInfo.nMax - (int)pInfo.nPage + 1 ) );
00450 
00451         SetScrollInfo( SB_VERT, &pInfo, TRUE );
00452 
00453         Invalidate();
00454 }
00455 
00456 void CLibraryTileView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
00457 {
00458         CRect rc;
00459         GetClientRect( &rc );
00460 
00461         SetFocus();
00462 
00463         switch ( nSBCode )
00464         {
00465         case SB_BOTTOM:
00466                 ScrollTo( 0xFFFFFF );
00467                 break;
00468         case SB_LINEDOWN:
00469                 ScrollBy( 32 );
00470                 break;
00471         case SB_LINEUP:
00472                 ScrollBy( -32 );
00473                 break;
00474         case SB_PAGEDOWN:
00475                 ScrollBy( rc.Height() );
00476                 break;
00477         case SB_PAGEUP:
00478                 ScrollBy( -rc.Height() );
00479                 break;
00480         case SB_THUMBPOSITION:
00481         case SB_THUMBTRACK:
00482                 ScrollTo( nPos );
00483                 break;
00484         case SB_TOP:
00485                 ScrollTo( 0 );
00486                 break;
00487         }
00488 }
00489 
00490 BOOL CLibraryTileView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
00491 {
00492         ScrollBy( zDelta * -m_szBlock.cy / WHEEL_DELTA / 2 );
00493         return TRUE;
00494 }
00495 
00496 void CLibraryTileView::ScrollBy(int nDelta)
00497 {
00498         ScrollTo( max( 0, m_nScroll + nDelta ) );
00499 }
00500 
00501 void CLibraryTileView::ScrollTo(int nPosition)
00502 {
00503         if ( nPosition == m_nScroll ) return;
00504         m_nScroll = nPosition;
00505 
00506         UpdateScroll();
00507         RedrawWindow( NULL, NULL, RDW_INVALIDATE );
00508 }
00509 
00510 void CLibraryTileView::OnPaint()
00511 {
00512         CPaintDC dc( this );
00513 
00514         CDC* pBuffer = CoolInterface.GetBuffer( dc, m_szBlock );
00515         CRect rcBuffer( 0, 0, m_szBlock.cx, m_szBlock.cy );
00516 
00517         CFont* pOldFont = (CFont*)pBuffer->SelectObject( &CoolInterface.m_fntNormal );
00518         pBuffer->SetBkMode( OPAQUE );
00519         pBuffer->SetBkColor( CoolInterface.m_crWindow );
00520         pBuffer->SetTextColor( CoolInterface.m_crText );
00521 
00522         CDC dcMem;
00523         dcMem.CreateCompatibleDC( &dc );
00524 
00525         CRect rcClient;
00526         GetClientRect( &rcClient );
00527         CPoint pt( rcClient.left, rcClient.top - m_nScroll );
00528 
00529         CLibraryTileItem** pList = m_pList;
00530 
00531         for ( int nItem = m_nCount ; nItem && pt.y < rcClient.bottom ; nItem--, pList++ )
00532         {
00533                 CLibraryTileItem* pTile = *pList;
00534 
00535                 CRect rcBlock( pt.x, pt.y, pt.x + m_szBlock.cx, pt.y + m_szBlock.cy );
00536 
00537                 if ( rcBlock.bottom >= rcClient.top && dc.RectVisible( &rcBlock ) )
00538                 {
00539                         pBuffer->FillSolidRect( &rcBuffer, CoolInterface.m_crWindow );
00540                         pTile->Paint( pBuffer, rcBuffer, &dcMem );
00541                         dc.BitBlt( rcBlock.left, rcBlock.top, m_szBlock.cx, m_szBlock.cy,
00542                                 pBuffer, 0, 0, SRCCOPY );
00543                         dc.ExcludeClipRect( &rcBlock );
00544                 }
00545 
00546                 pt.x += m_szBlock.cx;
00547 
00548                 if ( pt.x + m_szBlock.cx > rcClient.right )
00549                 {
00550                         pt.x = rcClient.left;
00551                         pt.y += m_szBlock.cy;
00552                 }
00553         }
00554 
00555         pBuffer->SelectObject( pOldFont );
00556         dc.FillSolidRect( &rcClient, CoolInterface.m_crWindow );
00557 }
00558 
00559 CLibraryTileItem* CLibraryTileView::HitTest(const CPoint& point) const
00560 {
00561         CRect rcClient;
00562         GetClientRect( &rcClient );
00563 
00564         CPoint pt( rcClient.left, rcClient.top - m_nScroll );
00565 
00566         CLibraryTileItem** pList = m_pList;
00567 
00568         for ( int nItem = m_nCount ; nItem && pt.y < rcClient.bottom ; nItem--, pList++ )
00569         {
00570                 CLibraryTileItem* pTile = *pList;
00571 
00572                 CRect rcBlock( pt.x, pt.y, pt.x + m_szBlock.cx, pt.y + m_szBlock.cy );
00573 
00574                 if ( rcBlock.PtInRect( point ) ) return pTile;
00575 
00576                 pt.x += m_szBlock.cx;
00577 
00578                 if ( pt.x + m_szBlock.cx > rcClient.right )
00579                 {
00580                         pt.x = rcClient.left;
00581                         pt.y += m_szBlock.cy;
00582                 }
00583         }
00584 
00585         return NULL;
00586 }
00587 
00588 BOOL CLibraryTileView::GetItemRect(CLibraryTileItem* pTile, CRect* pRect)
00589 {
00590         CRect rcClient;
00591         GetClientRect( &rcClient );
00592 
00593         CPoint pt( rcClient.left, rcClient.top - m_nScroll );
00594 
00595         CLibraryTileItem** pList = m_pList;
00596 
00597         for ( int nItem = m_nCount ; nItem ; nItem--, pList++ )
00598         {
00599                 CRect rcBlock( pt.x, pt.y, pt.x + m_szBlock.cx, pt.y + m_szBlock.cy );
00600 
00601                 if ( pTile == *pList )
00602                 {
00603                         *pRect = rcBlock;
00604                         return TRUE;
00605                 }
00606 
00607                 pt.x += m_szBlock.cx;
00608 
00609                 if ( pt.x + m_szBlock.cx > rcClient.right )
00610                 {
00611                         pt.x = rcClient.left;
00612                         pt.y += m_szBlock.cy;
00613                 }
00614         }
00615 
00616         return FALSE;
00617 }
00618 
00619 void CLibraryTileView::OnLButtonDown(UINT nFlags, CPoint point)
00620 {
00621         CLibraryTileItem* pHit = HitTest( point );
00622 
00623         if ( SelectTo( pHit ) ) Invalidate();
00624 
00625         SetFocus();
00626         SetCapture();
00627 
00628         if ( pHit && ( nFlags & MK_RBUTTON ) == 0 && Settings.Library.ShowVirtual )
00629         {
00630                 m_bDrag = TRUE;
00631                 m_ptDrag = point;
00632         }
00633 
00634         CLibraryView::OnLButtonDown( nFlags, point );
00635 }
00636 
00637 void CLibraryTileView::OnMouseMove(UINT nFlags, CPoint point)
00638 {
00639         if ( m_bDrag & ( nFlags & MK_LBUTTON ) )
00640         {
00641                 CSize szDiff = point - m_ptDrag;
00642 
00643                 if ( abs( szDiff.cx ) > 5 || abs( szDiff.cy ) > 5 )
00644                 {
00645                         m_bDrag = FALSE;
00646                         StartDragging( point );
00647                 }
00648         }
00649 
00650         CLibraryView::OnMouseMove( nFlags, point );
00651 }
00652 
00653 void CLibraryTileView::OnLButtonUp(UINT nFlags, CPoint point)
00654 {
00655         ReleaseCapture();
00656         m_bDrag = FALSE;
00657 
00658         if ( ( nFlags & (MK_SHIFT|MK_CONTROL) ) == 0 && m_pFocus && m_pFocus->m_bSelected )
00659         {
00660                 if ( DeselectAll( m_pFocus ) ) Invalidate();
00661         }
00662 }
00663 
00664 void CLibraryTileView::OnLButtonDblClk(UINT nFlags, CPoint point)
00665 {
00666         SendMessage( WM_COMMAND, ID_LIBRARY_ALBUM_OPEN );
00667 }
00668 
00669 void CLibraryTileView::OnRButtonDown(UINT nFlags, CPoint point)
00670 {
00671         OnLButtonDown( nFlags, point );
00672         CLibraryView::OnRButtonDown( nFlags, point );
00673 }
00674 
00675 void CLibraryTileView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00676 {
00677         switch ( nChar )
00678         {
00679         case VK_LEFT:
00680                 SelectTo( - 1 );
00681                 break;
00682         case VK_RIGHT:
00683                 SelectTo( 1 );
00684                 break;
00685         case VK_UP:
00686                 SelectTo( -m_nColumns );
00687                 break;
00688         case VK_DOWN:
00689                 SelectTo( m_nColumns );
00690                 break;
00691         case VK_PRIOR:
00692                 SelectTo( m_nRows * -m_nColumns );
00693                 break;
00694         case VK_NEXT:
00695                 ScrollBy( m_nRows * m_nColumns );
00696                 break;
00697         case VK_HOME:
00698                 SelectTo( -m_nCount );
00699                 break;
00700         case VK_END:
00701                 SelectTo( m_nCount );
00702                 break;
00703         case VK_RETURN:
00704                 PostMessage( WM_COMMAND, ID_LIBRARY_ALBUM_OPEN );
00705                 break;
00706         }
00707 
00708         CLibraryView::OnKeyDown( nChar, nRepCnt, nFlags );
00709 }
00710 
00711 void CLibraryTileView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
00712 {
00713         if ( _istalnum( nChar ) )
00714         {
00715                 CLibraryTileItem* pStart = m_pFocus;
00716 
00717                 for ( int nLoop = 0 ; nLoop < 2 ; nLoop++ )
00718                 {
00719                         CLibraryTileItem** pChild = m_pList;
00720 
00721                         for ( int nCount = m_nCount ; nCount ; nCount--, pChild++ )
00722                         {
00723                                 if ( pStart != NULL )
00724                                 {
00725                                         if ( pStart == *pChild ) pStart = NULL;
00726                                 }
00727                                 else if ( toupper( (*pChild)->m_sTitle.GetAt( 0 ) ) == toupper( (int)nChar ) )
00728                                 {
00729                                         DeselectAll( m_pFocus = *pChild );
00730                                         Select( m_pFocus, TS_TRUE );
00731                                         Highlight( m_pFocus );
00732                                         Invalidate();
00733                                         return;
00734                                 }
00735                         }
00736                 }
00737         }
00738 
00739         CLibraryView::OnChar( nChar, nRepCnt, nFlags );
00740 }
00741 
00743 // CLibraryTileView drag setup
00744 
00745 #define MAX_DRAG_SIZE   256
00746 #define MAX_DRAG_SIZE_2 128
00747 
00748 void CLibraryTileView::StartDragging(CPoint& ptMouse)
00749 {
00750         CImageList* pImage = CreateDragImage( ptMouse );
00751         if ( ! pImage ) return;
00752 
00753         ReleaseCapture();
00754         ClientToScreen( &ptMouse );
00755         DragObjects( pImage, ptMouse );
00756 }
00757 
00758 CImageList* CLibraryTileView::CreateDragImage(const CPoint& ptMouse)
00759 {
00760         CRect rcClient, rcOne, rcAll( 32000, 32000, -32000, -32000 );
00761 
00762         GetClientRect( &rcClient );
00763 
00764         for ( POSITION pos = m_pSelTile.GetHeadPosition() ; pos ; )
00765         {
00766                 CLibraryTileItem* pTile = (CLibraryTileItem*)m_pSelTile.GetNext( pos );
00767                 GetItemRect( pTile, &rcOne );
00768 
00769                 if ( rcOne.IntersectRect( &rcClient, &rcOne ) )
00770                 {
00771                         rcAll.left              = min( rcAll.left, rcOne.left );
00772                         rcAll.top               = min( rcAll.top, rcOne.top );
00773                         rcAll.right             = max( rcAll.right, rcOne.right );
00774                         rcAll.bottom    = max( rcAll.bottom, rcOne.bottom );
00775                 }
00776         }
00777 
00778         BOOL bClipped = rcAll.Height() > MAX_DRAG_SIZE;
00779 
00780         if ( bClipped )
00781         {
00782                 rcAll.left              = max( rcAll.left, ptMouse.x - MAX_DRAG_SIZE_2 );
00783                 rcAll.right             = max( rcAll.right, ptMouse.x + MAX_DRAG_SIZE_2 );
00784                 rcAll.top               = max( rcAll.top, ptMouse.y - MAX_DRAG_SIZE_2 );
00785                 rcAll.bottom    = max( rcAll.bottom, ptMouse.y + MAX_DRAG_SIZE_2 );
00786         }
00787 
00788         CClientDC dcClient( this );
00789         CDC dcMem, dcDrag;
00790         CBitmap bmDrag;
00791 
00792         if ( ! dcMem.CreateCompatibleDC( &dcClient ) )
00793                 return NULL;
00794         if ( ! dcDrag.CreateCompatibleDC( &dcClient ) )
00795                 return NULL;
00796         if ( ! bmDrag.CreateCompatibleBitmap( &dcClient, rcAll.Width(), rcAll.Height() ) )
00797                 return NULL;
00798 
00799         CBitmap *pOldDrag = dcDrag.SelectObject( &bmDrag );
00800 
00801         dcDrag.FillSolidRect( 0, 0, rcAll.Width(), rcAll.Height(), RGB( 250, 255, 250 ) );
00802 
00803         CRgn pRgn;
00804 
00805         if ( bClipped )
00806         {
00807                 CPoint ptMiddle( ptMouse.x - rcAll.left, ptMouse.y - rcAll.top );
00808                 pRgn.CreateEllipticRgn( ptMiddle.x - MAX_DRAG_SIZE_2, ptMiddle.y - MAX_DRAG_SIZE_2,
00809                                                                 ptMiddle.x + MAX_DRAG_SIZE_2, ptMiddle.y + MAX_DRAG_SIZE_2 );
00810                 dcDrag.SelectClipRgn( &pRgn );
00811         }
00812 
00813         CDC* pBuffer = CoolInterface.GetBuffer( dcClient, m_szBlock );
00814         CRect rcBuffer( 0, 0, m_szBlock.cx, m_szBlock.cy );
00815 
00816         CFont* pOldFont = (CFont*)pBuffer->SelectObject( &CoolInterface.m_fntNormal );
00817 
00818         for ( POSITION pos = m_pSelTile.GetHeadPosition() ; pos ; )
00819         {
00820                 CLibraryTileItem* pTile = (CLibraryTileItem*)m_pSelTile.GetNext( pos );
00821                 GetItemRect( pTile, &rcOne );
00822                 CRect rcDummy;
00823 
00824                 if ( rcDummy.IntersectRect( &rcAll, &rcOne ) )
00825                 {
00826                         pBuffer->FillSolidRect( &rcBuffer, RGB( 250, 255, 250 ) );
00827                         pTile->Paint( pBuffer, rcBuffer, &dcMem );
00828                         dcDrag.BitBlt( rcOne.left - rcAll.left, rcOne.top - rcAll.top,
00829                                 m_szBlock.cx, m_szBlock.cy, pBuffer, 0, 0, SRCCOPY );
00830                 }
00831         }
00832 
00833         pBuffer->SelectObject( pOldFont );
00834 
00835         dcDrag.SelectObject( pOldDrag );
00836 
00837         dcDrag.DeleteDC();
00838 
00839         CImageList* pAll = new CImageList();
00840         pAll->Create( rcAll.Width(), rcAll.Height(), ILC_COLOR16|ILC_MASK, 1, 1 );
00841         pAll->Add( &bmDrag, RGB( 250, 255, 250 ) );
00842 
00843         bmDrag.DeleteObject();
00844 
00845         pAll->BeginDrag( 0, ptMouse - rcAll.TopLeft() );
00846 
00847         return pAll;
00848 }
00849 
00850 
00852 // CLibraryTileItem construction
00853 
00854 CLibraryTileItem::CLibraryTileItem(CAlbumFolder* pFolder)
00855 {
00856         m_pFolder       = pFolder;
00857         m_nCookie       = 0xFFFFFFFF;
00858         m_bSelected     = FALSE;
00859         Update();
00860 }
00861 
00862 CLibraryTileItem::~CLibraryTileItem()
00863 {
00864 }
00865 
00867 // CLibraryTileItem operations
00868 
00869 BOOL CLibraryTileItem::Update()
00870 {
00871         if ( m_pFolder->m_nUpdateCookie == m_nCookie ) return FALSE;
00872 
00873         m_nCookie               = m_pFolder->m_nUpdateCookie;
00874         m_sTitle                = m_pFolder->m_sName;
00875         m_nIcon32               = m_pFolder->m_pSchema ? m_pFolder->m_pSchema->m_nIcon32 : -1;
00876         m_nIcon48               = m_pFolder->m_pSchema ? m_pFolder->m_pSchema->m_nIcon48 : -1;
00877         m_bCollection   = m_pFolder->m_bCollSHA1;
00878 
00879         CSchema* pSchema = m_pFolder->m_pSchema;
00880 
00881         if ( pSchema != NULL && m_pFolder->m_pXML != NULL )
00882         {
00883                 m_sSubtitle1    = pSchema->m_sTileLine1;
00884                 m_sSubtitle2    = pSchema->m_sTileLine2;
00885 
00886                 pSchema->ResolveTokens( m_sSubtitle1, m_pFolder->m_pXML );
00887                 pSchema->ResolveTokens( m_sSubtitle2, m_pFolder->m_pXML );
00888         }
00889         else
00890         {
00891                 m_sSubtitle1.Empty();
00892                 m_sSubtitle2.Empty();
00893         }
00894 
00895         return TRUE;
00896 }
00897 
00899 // CLibraryTileItem paint
00900 
00901 void CLibraryTileItem::Paint(CDC* pDC, const CRect& rcBlock, CDC* pMemDC)
00902 {
00903         CRect rc( &rcBlock );
00904 
00905         UINT nStyle = 0;
00906 
00907         if ( m_bSelected ) nStyle |= ILD_SELECTED;
00908         if ( m_bCollection ) nStyle |= INDEXTOOVERLAYMASK(SHI_O_COLLECTION);
00909 
00910         if ( m_nIcon48 >= 0 )
00911         {
00912                 ImageList_DrawEx( ShellIcons.GetHandle( 48 ), m_nIcon48, *pDC,
00913                         rc.left + 5, rc.top + 4, 48, 48, CLR_NONE, CLR_DEFAULT, nStyle );
00914         }
00915         else if ( m_nIcon32 >= 0 )
00916         {
00917                 ImageList_DrawEx( ShellIcons.GetHandle( 32 ), m_nIcon32, *pDC,
00918                         rc.left + 5 + 8, rc.top + 4 + 8, 32, 32, CLR_NONE, CLR_DEFAULT, nStyle );
00919         }
00920 
00921         rc.left += 48 + 5;
00922         rc.DeflateRect( 10, 5 );
00923 
00924         if ( m_bSelected )
00925         {
00926                 pDC->SetBkColor( CoolInterface.m_crHighlight );
00927                 pDC->SetTextColor( CoolInterface.m_crHiText );
00928                 pDC->SetBkMode( OPAQUE );
00929         }
00930         else
00931         {
00932                 pDC->SetBkColor( CoolInterface.m_crWindow );
00933                 pDC->SetTextColor( CoolInterface.m_crText );
00934                 pDC->SetBkMode( TRANSPARENT );
00935         }
00936 
00937         int nX = rc.left + 2;
00938         int nY = ( rc.top + rc.bottom ) / 2;
00939         int nH = pDC->GetTextExtent( _T("Xy") ).cy;
00940 
00941         if ( m_sSubtitle1.GetLength() > 0 )
00942         {
00943                 CRect rcUnion( nX, nY, nX, nY );
00944 
00945                 if ( m_sSubtitle2.GetLength() > 0 )
00946                 {
00947                         nY -= ( nH * 3 ) / 2;
00948                         if ( m_bCollection ) pDC->SelectObject( &CoolInterface.m_fntBold );
00949                         DrawText( pDC, &rc, nX, nY, m_sTitle, &rcUnion );
00950                         if ( m_bCollection ) pDC->SelectObject( &CoolInterface.m_fntNormal );
00951                         if ( ! m_bSelected ) pDC->SetTextColor( CoolInterface.m_crDisabled );
00952                         DrawText( pDC, &rc, nX, nY + nH, m_sSubtitle1, &rcUnion );
00953                         DrawText( pDC, &rc, nX, nY + nH + nH, m_sSubtitle2, &rcUnion );
00954                 }
00955                 else
00956                 {
00957                         if ( m_bCollection ) pDC->SelectObject( &CoolInterface.m_fntBold );
00958                         DrawText( pDC, &rc, nX, nY - nH, m_sTitle, &rcUnion );
00959                         if ( m_bCollection ) pDC->SelectObject( &CoolInterface.m_fntNormal );
00960                         if ( ! m_bSelected ) pDC->SetTextColor( CoolInterface.m_crDisabled );
00961                         DrawText( pDC, &rc, nX, nY, m_sSubtitle1, &rcUnion );
00962                 }
00963 
00964                 pDC->FillSolidRect( &rcUnion, pDC->GetBkColor() );
00965         }
00966         else
00967         {
00968                 nY -= nH / 2;
00969                 if ( m_bCollection ) pDC->SelectObject( &CoolInterface.m_fntBold );
00970                 DrawText( pDC, &rc, nX, nY, m_sTitle );
00971                 if ( m_bCollection ) pDC->SelectObject( &CoolInterface.m_fntNormal );
00972         }
00973 
00974         pDC->SelectClipRgn( NULL );
00975 }
00976 
00977 void CLibraryTileItem::DrawText(CDC* pDC, const CRect* prcClip, int nX, int nY, LPCTSTR pszText, CRect* prcUnion)
00978 {
00979         CSize sz = pDC->GetTextExtent( pszText, _tcslen( pszText ) );
00980         CRect rc( nX - 2, nY - 1, nX + sz.cx + 2, nY + sz.cy + 1 );
00981 
00982         rc.IntersectRect( &rc, prcClip );
00983 
00984         pDC->ExtTextOut( nX, nY, ETO_CLIPPED|ETO_OPAQUE, &rc, pszText, _tcslen( pszText ), NULL );
00985         pDC->ExcludeClipRect( rc.left, rc.top, rc.right, rc.bottom );
00986 
00987         if ( prcUnion != NULL ) prcUnion->UnionRect( prcUnion, &rc );
00988 }
00989 
00991 // CLibraryTileView command handlers
00992 
00993 void CLibraryTileView::OnContextMenu(CWnd* pWnd, CPoint point)
00994 {
00995         Skin.TrackPopupMenu( m_pszToolBar, point, ID_LIBRARY_ALBUM_OPEN );
00996 }
00997 
00998 void CLibraryTileView::OnUpdateLibraryAlbumOpen(CCmdUI* pCmdUI)
00999 {
01000         pCmdUI->Enable( m_nSelected == 1 );
01001 }
01002 
01003 void CLibraryTileView::OnLibraryAlbumOpen()
01004 {
01005         if ( m_pSelTile.GetCount() == 0 ) return;
01006         CLibraryTileItem* pItem = (CLibraryTileItem*)m_pSelTile.GetHead();
01007         GetFrame()->Display( pItem->m_pFolder );
01008 }
01009 
01010 void CLibraryTileView::OnUpdateLibraryAlbumDelete(CCmdUI* pCmdUI)
01011 {
01012         pCmdUI->Enable( m_nSelected > 0 );
01013 }
01014 
01015 void CLibraryTileView::OnLibraryAlbumDelete()
01016 {
01017         if ( m_nSelected == 0 ) return;
01018 
01019         CString strFormat, strMessage;
01020         Skin.LoadString( strFormat, IDS_LIBRARY_FOLDER_DELETE );
01021         strMessage.Format( strFormat, m_nSelected );
01022 
01023         if ( AfxMessageBox( strMessage, MB_ICONQUESTION|MB_OKCANCEL ) != IDOK ) return;
01024 
01025         {
01026                 CQuickLock oLock( Library.m_pSection );
01027 
01028                 for ( POSITION pos = m_pSelTile.GetHeadPosition() ; pos ; )
01029                 {
01030                         CLibraryTileItem* pTile = (CLibraryTileItem*)m_pSelTile.GetNext( pos );
01031                         CAlbumFolder* pFolder = pTile->m_pFolder;
01032                         if ( LibraryFolders.CheckAlbum( pFolder ) ) pFolder->Delete();
01033                 }
01034 
01035         }
01036         PostUpdate();
01037 }
01038 
01039 void CLibraryTileView::OnUpdateLibraryAlbumProperties(CCmdUI* pCmdUI)
01040 {
01041         pCmdUI->Enable( m_nSelected == 1 );
01042 }
01043 
01044 void CLibraryTileView::OnLibraryAlbumProperties()
01045 {
01046         if ( m_pSelTile.GetCount() == 0 ) return;
01047         CLibraryTileItem* pItem = (CLibraryTileItem*)m_pSelTile.GetHead();
01048 
01049         CAlbumFolder* pFolder = pItem->m_pFolder;
01050         CFolderPropertiesDlg dlg( NULL, pFolder );
01051 
01052         if ( dlg.DoModal() == IDOK ) GetFrame()->Display( pFolder );
01053 }

Generated on Thu Dec 15 10:39:36 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2