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

CtrlText.cpp

Go to the documentation of this file.
00001 //
00002 // CtrlText.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 "CtrlText.h"
00025 
00026 #ifdef _DEBUG
00027 #define new DEBUG_NEW
00028 #undef THIS_FILE
00029 static char THIS_FILE[] = __FILE__;
00030 #endif
00031 
00032 BEGIN_MESSAGE_MAP(CTextCtrl, CWnd)
00033         //{{AFX_MSG_MAP(CTextCtrl)
00034         ON_WM_VSCROLL()
00035         ON_WM_ERASEBKGND()
00036         ON_WM_PAINT()
00037         ON_WM_CREATE()
00038         ON_WM_SIZE()
00039         ON_WM_LBUTTONDOWN()
00040         ON_WM_MOUSEWHEEL()
00041         //}}AFX_MSG_MAP
00042 END_MESSAGE_MAP()
00043 
00044 #define LINE_BUFFER_LIMIT               1024
00045 #define LINE_BUFFER_BLOCK               64
00046 
00047 
00049 // CTextCtrl construction
00050 
00051 CTextCtrl::CTextCtrl()
00052 {
00053         m_crBackground  = GetSysColor( COLOR_WINDOW );
00054         m_crText[0]             = RGB( 0, 0, 0 );
00055         m_crText[1]             = RGB( 0, 0, 127 );
00056         m_crText[2]             = RGB( 255, 0, 0 );
00057         m_crText[3]             = RGB( 192, 192, 192 );
00058         m_crText[4]             = RGB( 0, 0, 255 );
00059 
00060         m_pFont.CreateFont( -theApp.m_nDefaultFontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
00061                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
00062                 DEFAULT_PITCH|FF_DONTCARE, theApp.m_sSystemLogFont );
00063         m_cCharacter = CSize( 0, 0 );
00064 }
00065 
00066 CTextCtrl::~CTextCtrl()
00067 {
00068         Clear( FALSE );
00069 }
00070 
00072 // CTextCtrl operations
00073 
00074 BOOL CTextCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) 
00075 {
00076         dwStyle |= WS_CHILD|WS_VSCROLL;
00077         return CWnd::Create( NULL, NULL, dwStyle, rect, pParentWnd, nID, NULL );
00078 }
00079 
00080 void CTextCtrl::Add(int nType, LPCTSTR pszText)
00081 {
00082         CSingleLock pLock( &m_pSection, TRUE );
00083         CString strLine;
00084 
00085         for ( ; *pszText ; pszText++ )
00086         {
00087                 if ( *pszText == 13 )
00088                 {
00089                         if ( strLine.GetLength() ) AddLine( nType, strLine );
00090                         strLine.Empty();
00091                 }
00092                 else if ( *pszText != 10 )
00093                 {
00094                         strLine += *pszText;
00095                 }
00096         }
00097 
00098         if ( strLine.GetLength() ) AddLine( nType, strLine );
00099 }
00100 
00101 void CTextCtrl::AddLine(int nType, LPCTSTR pszLine)
00102 {
00103         CSingleLock pLock( &m_pSection, TRUE );
00104 
00105         if ( m_pLines.GetSize() >= LINE_BUFFER_LIMIT )
00106         {
00107                 for ( int nCount = 0 ; nCount < LINE_BUFFER_BLOCK ; nCount++ )
00108                 {
00109                         delete (CTextLine*)m_pLines.GetAt( 0 );
00110                         m_pLines.RemoveAt( 0 );
00111                 }
00112                 m_bProcess = TRUE;
00113         }
00114 
00115         m_pLines.Add( new CTextLine( nType, pszLine ) );
00116         Invalidate();
00117 }
00118 
00119 void CTextCtrl::Clear(BOOL bInvalidate)
00120 {
00121         CSingleLock pLock( &m_pSection, TRUE );
00122 
00123         for ( int nLine = 0 ; nLine < m_pLines.GetSize() ; nLine++ )
00124         {
00125                 delete (CTextLine*)m_pLines.GetAt( nLine );
00126         }
00127         m_pLines.RemoveAll();
00128         
00129         m_nPosition = m_nTotal = 0;
00130 
00131         if ( bInvalidate )
00132         {
00133                 UpdateScroll( TRUE );
00134                 Invalidate();
00135         }
00136 }
00137 
00138 void CTextCtrl::UpdateScroll(BOOL bFull)
00139 {
00140         SCROLLINFO si;
00141 
00142         ZeroMemory( &si, sizeof(si) );
00143         si.cbSize = sizeof(si);
00144 
00145         if ( bFull )
00146         {
00147                 CRect rc;
00148                 GetClientRect( &rc );
00149 
00150                 si.fMask        = SIF_POS|SIF_PAGE|SIF_RANGE|SIF_DISABLENOSCROLL;
00151                 si.nPos         = m_nPosition;
00152                 si.nPage        = rc.Height() / m_cCharacter.cy;
00153                 si.nMin         = 0;
00154                 si.nMax         = m_nTotal + si.nPage - 1;
00155         }
00156         else
00157         {
00158                 si.fMask        = SIF_POS;
00159                 si.nPos         = m_nPosition;
00160         }
00161         
00162         SetScrollInfo( SB_VERT, &si );
00163 }
00164 
00165 CFont* CTextCtrl::GetFont()
00166 {
00167         return &m_pFont;
00168 }
00169 
00171 // CTextCtrl message handlers
00172 
00173 int CTextCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
00174 {
00175         if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
00176         
00177         m_nPosition = m_nTotal = 0;
00178         m_bProcess = TRUE;
00179         
00180         // Try to get the number of lines to scroll when the mouse wheel is rotated
00181         if( !SystemParametersInfo ( SPI_GETWHEELSCROLLLINES, 0, &m_nScrollWheelLines, 0) )
00182                 m_nScrollWheelLines = 3;
00183 
00184         return 0;
00185 }
00186 
00187 void CTextCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
00188 {
00189         CSingleLock pLock( &m_pSection, TRUE );
00190         SCROLLINFO si;
00191 
00192         ZeroMemory( &si, sizeof(si) );
00193         si.cbSize       = sizeof(si);
00194         si.fMask        = SIF_ALL;
00195 
00196         GetScrollInfo( SB_VERT, &si );
00197 
00198         switch ( nSBCode )
00199         {
00200         case SB_TOP:
00201                 m_nPosition = 0;
00202                 break;
00203         case SB_BOTTOM:
00204                 m_nPosition = m_nTotal - 1;
00205                 break;
00206         case SB_LINEUP:
00207                 m_nPosition--;
00208                 break;
00209         case SB_LINEDOWN:
00210                 m_nPosition++;
00211                 break;
00212         case SB_PAGEUP:
00213                 m_nPosition -= ( si.nPage - 1 );
00214                 break;
00215         case SB_PAGEDOWN:
00216                 m_nPosition += ( si.nPage - 1 );
00217                 break;
00218         case SB_THUMBPOSITION:
00219         case SB_THUMBTRACK:
00220                 m_nPosition = si.nTrackPos;
00221                 break;
00222         }
00223 
00224         m_nPosition = max( 0, min( m_nTotal, m_nPosition ) );
00225 
00226         UpdateScroll();
00227         Invalidate();
00228 }
00229 
00230 BOOL CTextCtrl::OnEraseBkgnd(CDC* pDC) 
00231 {
00232         return TRUE;
00233 }
00234 
00235 void CTextCtrl::OnPaint() 
00236 {
00237         CSingleLock pLock( &m_pSection, TRUE );
00238         CRect rcClient, rcLine;
00239         CPaintDC dc( this );
00240         
00241         GetClientRect( &rcClient );
00242 
00243         CFont* pOldFont = (CFont*)dc.SelectObject( &m_pFont );
00244         
00245         if ( m_cCharacter.cx == 0 ) m_cCharacter = dc.GetTextExtent( _T("X") );
00246 
00247         BOOL bBottom    = ( m_nPosition >= m_nTotal );
00248         BOOL bModified  = m_bProcess;
00249 
00250         if ( m_bProcess ) m_nTotal = 0;
00251         
00252         int nWidth = ( rcClient.right - 4 ) / m_cCharacter.cx;
00253 
00254         for ( int nLine = 0 ; nLine < m_pLines.GetSize() ; nLine++ )
00255         {
00256                 CTextLine* pLine = (CTextLine*)m_pLines.GetAt( nLine );
00257 
00258                 if ( m_bProcess || ! pLine->m_nLine )
00259                 {
00260                         m_nTotal += pLine->Process( nWidth );
00261                         bModified = TRUE;
00262                 }
00263         }
00264 
00265         if ( bBottom ) m_nPosition = m_nTotal;
00266         if ( bModified ) UpdateScroll( TRUE );
00267         m_bProcess = FALSE;
00268 
00269         dc.SetTextColor( m_crText[0] );
00270         dc.SetBkColor( m_crBackground );
00271         dc.SetBkMode( OPAQUE );
00272 
00273         rcLine.CopyRect( &rcClient );
00274         rcLine.bottom += ( m_nTotal - m_nPosition ) * m_cCharacter.cy;
00275         rcLine.top = rcLine.bottom - m_cCharacter.cy;
00276 
00277         for ( int nLine = m_pLines.GetSize() - 1 ; nLine >= 0 && rcLine.bottom > 0 ; nLine-- )
00278         {
00279                 CTextLine* pLine = (CTextLine*)m_pLines.GetAt( nLine );
00280 
00281                 dc.SetTextColor( m_crText[ pLine->m_nType ] );
00282                 pLine->Paint( &dc, &rcLine );
00283         }
00284 
00285         if ( rcLine.bottom > 0 )
00286         {
00287                 rcLine.top = 0;
00288                 dc.FillSolidRect( &rcLine, m_crBackground );
00289         }
00290 
00291         dc.SelectObject( pOldFont );
00292 }
00293 
00294 void CTextCtrl::OnSize(UINT nType, int cx, int cy) 
00295 {
00296         CWnd::OnSize( nType, cx, cy );
00297         m_bProcess = TRUE;
00298 }
00299 
00300 void CTextCtrl::OnLButtonDown(UINT nFlags, CPoint point)
00301 {
00302         SetFocus();
00303 }
00304 
00305 BOOL CTextCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
00306 {
00307         short nRows = ( zDelta / WHEEL_DELTA );
00308 
00309         if ( WHEEL_PAGESCROLL == m_nScrollWheelLines )
00310         {
00311                 // scroll by page is activated
00312                 SCROLLINFO si;
00313 
00314                 ZeroMemory( &si, sizeof( si ) );
00315                 si.cbSize       = sizeof( si );
00316                 si.fMask        = SIF_ALL;
00317 
00318                 GetScrollInfo( SB_VERT, &si );
00319 
00320                 nRows *=( si.nPage - 1 );
00321         }
00322         else
00323                 nRows *= m_nScrollWheelLines;
00324 
00325         CSingleLock pLock( &m_pSection, TRUE );
00326 
00327         m_nPosition-= nRows;
00328         m_nPosition = max( 0, min( m_nTotal, m_nPosition ) );
00329 
00330         UpdateScroll();
00331         Invalidate();
00332 
00333         return CWnd::OnMouseWheel(nFlags, zDelta, pt);
00334 }
00335 
00337 // CTextLine construction
00338 
00339 CTextLine::CTextLine(int nType, LPCTSTR pszText)
00340 {
00341         m_sText = pszText;
00342         m_pLine = NULL;
00343         m_nLine = 0;
00344         m_nType = nType;
00345 }
00346 
00347 CTextLine::~CTextLine()
00348 {
00349         if ( m_pLine ) delete [] m_pLine;
00350 }
00351 
00353 // CTextLine process
00354 
00355 int CTextLine::Process(int nWidth)
00356 {
00357         if ( m_pLine ) delete [] m_pLine;
00358         m_pLine = NULL;
00359         m_nLine = 0;
00360         
00361         int nLength = 0;
00362         int nLast = 0;
00363 
00364         for ( LPCTSTR pszText = m_sText ; ; pszText++, nLength++ )
00365         {
00366                 if ( *pszText == 32 || *pszText == 0 )
00367                 {
00368                         if ( nLength <= nWidth )
00369                         {
00370                                 nLast = nLength;
00371                         }
00372                         else if ( nLast )
00373                         {
00374                                 AddLine( nLast );
00375                                 nLength = nLast = nLength - nLast;
00376                         }
00377                         else
00378                         {
00379                                 break;
00380                         }
00381                 }
00382 
00383                 if ( *pszText == 0 ) break;
00384         }
00385 
00386         if ( nLength || !m_nLine ) AddLine( nLength );
00387 
00388         return m_nLine;
00389 }
00390 
00391 void CTextLine::AddLine(int nLength)
00392 {
00393         int* pLine = new int[ m_nLine + 1 ];
00394         CopyMemory( pLine, m_pLine, m_nLine * sizeof(int) );
00395         if ( m_pLine ) delete [] m_pLine;
00396         m_pLine = pLine;
00397         m_pLine[ m_nLine++ ] = nLength;
00398 }
00399 
00401 // CTextLine paint
00402 
00403 void CTextLine::Paint(CDC* pDC, CRect* pRect)
00404 {
00405         int nHeight = pRect->bottom - pRect->top;
00406 
00407         pRect->top              -= ( m_nLine - 1 ) * nHeight;
00408         pRect->bottom   -= ( m_nLine - 1 ) * nHeight;
00409 
00410         LPCTSTR pszLine = m_sText;
00411         int* pLength    = m_pLine;
00412 
00413         for ( int nLine = 0 ; nLine < m_nLine ; nLine++, pLength++ )
00414         {
00415                 if ( pDC->RectVisible( pRect ) )
00416                 {
00417                         pDC->ExtTextOut( pRect->left + 2, pRect->top, ETO_CLIPPED|ETO_OPAQUE,
00418                                 pRect, pszLine, *pLength, NULL );
00419                 }
00420                 pszLine += *pLength;
00421 
00422                 pRect->top += nHeight;
00423                 pRect->bottom += nHeight;
00424         }
00425 
00426         pRect->top              -= ( m_nLine + 1 ) * nHeight;
00427         pRect->bottom   -= ( m_nLine + 1 ) * nHeight;
00428 }

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