00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "CoolInterface.h"
00025 #include "WndSettingsSheet.h"
00026 #include "WndSettingsPage.h"
00027
00028 #include <afxpriv.h>
00029 #include <..\src\mfc\afximpl.h>
00030
00031
00032 #ifdef _DEBUG
00033 #define new DEBUG_NEW
00034 #undef THIS_FILE
00035 static char THIS_FILE[] = __FILE__;
00036 #endif
00037
00038 IMPLEMENT_DYNAMIC(CSettingsSheet, CSkinDialog)
00039
00040 BEGIN_MESSAGE_MAP(CSettingsSheet, CSkinDialog)
00041 ON_WM_PAINT()
00042 ON_COMMAND(IDRETRY, OnApply)
00043 ON_NOTIFY(TVN_ITEMEXPANDINGW, IDC_SETTINGS_TREE, OnTreeExpanding)
00044 ON_NOTIFY(TVN_ITEMEXPANDINGA, IDC_SETTINGS_TREE, OnTreeExpanding)
00045 ON_NOTIFY(TVN_SELCHANGEDW, IDC_SETTINGS_TREE, OnSelectPage)
00046 ON_NOTIFY(TVN_SELCHANGEDA, IDC_SETTINGS_TREE, OnSelectPage)
00047 END_MESSAGE_MAP()
00048
00049
00051
00052
00053 CSettingsSheet::CSettingsSheet(CWnd* pParent, UINT nCaptionID)
00054 {
00055 m_pPage = NULL;
00056 m_pFirst = NULL;
00057 m_pTemplate = NULL;
00058 m_bModified = FALSE;
00059 m_nLeftMargin = 0;
00060 m_nTopMargin = 0;
00061 m_nListWidth = 120;
00062 m_nListMargin = 6;
00063 m_nButtonHeight = 20;
00064
00065 if ( nCaptionID ) m_sCaption.LoadString( nCaptionID );
00066 }
00067
00068 CSettingsSheet::~CSettingsSheet()
00069 {
00070 }
00071
00072 void CSettingsSheet::DoDataExchange(CDataExchange* pDX)
00073 {
00074 CSkinDialog::DoDataExchange( pDX );
00075 }
00076
00078
00079
00080 void CSettingsSheet::AddPage(CSettingsPage* pPage, LPCTSTR pszCaption)
00081 {
00082 if ( pszCaption ) pPage->m_sCaption = pszCaption;
00083 pPage->m_bGroup = FALSE;
00084 m_pPages.Add( pPage );
00085 }
00086
00087 void CSettingsSheet::AddGroup(CSettingsPage* pPage, LPCTSTR pszCaption)
00088 {
00089 if ( pszCaption ) pPage->m_sCaption = pszCaption;
00090 pPage->m_bGroup = TRUE;
00091 m_pPages.Add( pPage );
00092 }
00093
00094 CSettingsPage* CSettingsSheet::GetPage(int nPage) const
00095 {
00096 return (CSettingsPage*)m_pPages.GetAt( nPage );
00097 }
00098
00099 CSettingsPage* CSettingsSheet::GetPage(CRuntimeClass* pClass) const
00100 {
00101 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00102 {
00103 CSettingsPage* pPage = GetPage( nPage );
00104 if ( pPage->IsKindOf( pClass ) ) return pPage;
00105 }
00106 return NULL;
00107 }
00108
00109 CSettingsPage* CSettingsSheet::GetPage(LPCTSTR pszClass) const
00110 {
00111 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00112 {
00113 CSettingsPage* pPage = GetPage( nPage );
00114 if ( _tcscmp( CString( pPage->GetRuntimeClass()->m_lpszClassName ), pszClass ) == 0 ) return pPage;
00115 }
00116 return NULL;
00117 }
00118
00119 int CSettingsSheet::GetPageIndex(CSettingsPage* pPage) const
00120 {
00121 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00122 {
00123 if ( pPage == GetPage( nPage ) ) return nPage;
00124 }
00125 return -1;
00126 }
00127
00128 int CSettingsSheet::GetPageCount() const
00129 {
00130 return m_pPages.GetSize();
00131 }
00132
00133 CSettingsPage* CSettingsSheet::GetActivePage() const
00134 {
00135 return m_pPage;
00136 }
00137
00138 BOOL CSettingsSheet::SetActivePage(CSettingsPage* pPage)
00139 {
00140 if ( pPage == NULL || pPage == m_pPage ) return FALSE;
00141
00142 ASSERT_KINDOF(CSettingsPage, pPage);
00143
00144 if ( m_hWnd == NULL )
00145 {
00146 m_pFirst = pPage;
00147 return TRUE;
00148 }
00149
00150 if ( m_pPage != NULL )
00151 {
00152 if ( ! m_pPage->OnKillActive() ) return FALSE;
00153 m_pPage->ShowWindow( SW_HIDE );
00154 }
00155
00156 if ( pPage->m_hWnd == NULL && ! CreatePage( pPage ) ) return FALSE;
00157 if ( ! pPage->OnSetActive() ) return FALSE;
00158
00159 m_pPage = pPage;
00160 m_pPage->ShowWindow( SW_SHOW );
00161
00162 for ( HTREEITEM hGroup = m_wndTree.GetRootItem() ; hGroup ; hGroup = m_wndTree.GetNextItem( hGroup, TVGN_NEXT ) )
00163 {
00164 if ( m_wndTree.GetItemData( hGroup ) == (DWORD)m_pPage )
00165 {
00166 if ( ( m_wndTree.GetItemState( hGroup, TVIS_SELECTED ) & TVIS_SELECTED ) == 0 )
00167 {
00168 m_wndTree.SelectItem( hGroup );
00169 }
00170 }
00171 for ( HTREEITEM hItem = m_wndTree.GetChildItem( hGroup ) ; hItem ; hItem = m_wndTree.GetNextItem( hItem, TVGN_NEXT ) )
00172 {
00173 if ( m_wndTree.GetItemData( hItem ) == (DWORD)m_pPage )
00174 {
00175 if ( ( m_wndTree.GetItemState( hItem, TVIS_SELECTED ) & TVIS_SELECTED ) == 0 )
00176 {
00177 m_wndTree.SelectItem( hItem );
00178 }
00179 }
00180 }
00181 }
00182
00183 return TRUE;
00184 }
00185
00186 BOOL CSettingsSheet::SetActivePage(int nPage)
00187 {
00188 return SetActivePage( GetPage( nPage ) );
00189 }
00190
00191 BOOL CSettingsSheet::IsModified() const
00192 {
00193 return m_bModified;
00194 }
00195
00196 void CSettingsSheet::SetModified(BOOL bChanged)
00197 {
00198 if ( m_bModified == bChanged ) return;
00199 m_bModified = bChanged;
00200 }
00201
00203
00204
00205 int CSettingsSheet::DoModal()
00206 {
00207 m_pTemplate = (DLGTEMPLATE *)malloc( sizeof(DLGTEMPLATE) + 6 );
00208 ZeroMemory( m_pTemplate, sizeof(DLGTEMPLATE) + 6 );
00209
00210 DWORD dwExStyle = theApp.m_bRTL ? WS_EX_RTLREADING|WS_EX_RIGHT|WS_EX_LEFTSCROLLBAR|WS_EX_LAYOUTRTL :
00211 WS_EX_LEFT|WS_EX_LTRREADING|WS_EX_RIGHTSCROLLBAR;
00212
00213 m_pTemplate->style = WS_POPUPWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS|WS_DLGFRAME|WS_OVERLAPPED|DS_MODALFRAME;
00214 m_pTemplate->dwExtendedStyle = dwExStyle|WS_EX_DLGMODALFRAME|WS_EX_WINDOWEDGE|WS_EX_CONTROLPARENT;
00215
00216 m_pTemplate->cdit = 0;
00217 m_pTemplate->x = 0;
00218 m_pTemplate->y = 0;
00219 m_pTemplate->cx = 100;
00220 m_pTemplate->cy = 100;
00221
00222 m_pPage = NULL;
00223 m_bModified = FALSE;
00224
00225 CSkinDialog::InitModalIndirect( m_pTemplate, m_pParentWnd );
00226
00227 int nResult = CSkinDialog::DoModal();
00228
00229 free( m_pTemplate );
00230
00231 m_pTemplate = NULL;
00232 m_pParentWnd = NULL;
00233 m_pFirst = m_pPage;
00234 m_pPage = NULL;
00235
00236 return nResult;
00237 }
00238
00239 BOOL CSettingsSheet::OnInitDialog()
00240 {
00241 CSkinDialog::OnInitDialog();
00242
00243 SetWindowText( m_sCaption );
00244
00245 CRect rect;
00246 m_wndTree.Create( WS_CHILD|WS_TABSTOP|WS_VISIBLE|
00247 TVS_HASLINES|TVS_SHOWSELALWAYS|TVS_TRACKSELECT, rect, this, IDC_SETTINGS_TREE );
00248
00249 m_wndOK.Create( _T("OK"), WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_DEFPUSHBUTTON, rect, this, IDOK );
00250 m_wndOK.SetFont( &theApp.m_gdiFont );
00251 m_wndCancel.Create( _T("Cancel"), WS_CHILD|WS_TABSTOP|WS_VISIBLE, rect, this, IDCANCEL );
00252 m_wndCancel.SetFont( &theApp.m_gdiFont );
00253 m_wndApply.Create( _T("Apply"), WS_CHILD|WS_TABSTOP|WS_VISIBLE, rect, this, IDRETRY );
00254 m_wndApply.SetFont( &theApp.m_gdiFont );
00255
00256 Layout();
00257 CenterWindow();
00258
00259 if ( m_pFirst == NULL ) m_pFirst = GetPage( 0 );
00260 SetActivePage( m_pFirst );
00261
00262 BuildTree();
00263
00264 return TRUE;
00265 }
00266
00267 void CSettingsSheet::BuildTree()
00268 {
00269 HTREEITEM hGroup = NULL;
00270
00271 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00272 {
00273 CSettingsPage* pPage = GetPage( nPage );
00274
00275 if ( pPage->m_bGroup ) hGroup = NULL;
00276
00277 HTREEITEM hItem = m_wndTree.InsertItem(
00278 TVIF_PARAM|TVIF_TEXT|TVIF_STATE,
00279 pPage->m_sCaption, 0, 0, TVIS_EXPANDED|(TVIS_BOLD*pPage->m_bGroup),
00280 TVIS_EXPANDED|TVIS_BOLD, (LPARAM)pPage, hGroup, TVI_LAST );
00281
00282 if ( pPage->m_bGroup ) hGroup = hItem;
00283
00284 if ( pPage == m_pPage ) m_wndTree.SelectItem( hItem );
00285 }
00286 }
00287
00288 void CSettingsSheet::Layout()
00289 {
00290 TEXTMETRIC txtMetric;
00291
00292 CDC* pDC = GetDC();
00293 pDC->SelectObject( &theApp.m_gdiFont );
00294 pDC->GetTextMetrics( &txtMetric );
00295 ReleaseDC( pDC );
00296
00297 m_nButtonHeight = ( txtMetric.tmHeight + txtMetric.tmExternalLeading ) + 10;
00298
00299 m_szPages.cx = m_szPages.cy = 0;
00300
00301 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00302 {
00303 CSettingsPage* pPage = GetPage( nPage );
00304 CDialogTemplate pTemplate;
00305
00306 if ( pPage->GetTemplateName() == NULL ) continue;
00307
00308 if ( pTemplate.Load( pPage->GetTemplateName() ) )
00309 {
00310 CSize size;
00311 pTemplate.GetSizeInPixels( &size );
00312 m_szPages.cx = max( m_szPages.cx, size.cx );
00313 m_szPages.cy = max( m_szPages.cy, size.cy );
00314 }
00315 }
00316
00317 CRect rc( 0, 0, m_szPages.cx, m_szPages.cy );
00318 rc.right += m_nListWidth + m_nListMargin;
00319 rc.right += m_nLeftMargin;
00320 rc.bottom += m_nTopMargin + m_nButtonHeight + 16;
00321
00322 CalcWindowRect( &rc );
00323 SetWindowPos( &wndTop, 0, 0, rc.Width(), rc.Height(), SWP_NOMOVE|SWP_NOZORDER );
00324
00325 rc.SetRect( m_nLeftMargin, m_nTopMargin, 0, 0 );
00326 rc.right = rc.left + m_nListWidth;
00327 rc.bottom = rc.top + m_szPages.cy;
00328
00329 m_wndTree.MoveWindow( &rc );
00330
00331 rc.SetRect( 8, rc.bottom + 8, 76, m_nButtonHeight );
00332 rc.right += rc.left;
00333 rc.bottom += rc.top;
00334
00335 m_wndOK.MoveWindow( &rc );
00336 rc.OffsetRect( rc.Width() + 8, 0 );
00337 m_wndCancel.MoveWindow( &rc );
00338 rc.OffsetRect( rc.Width() + 8, 0 );
00339 m_wndApply.MoveWindow( &rc );
00340 }
00341
00342 BOOL CSettingsSheet::CreatePage(CSettingsPage* pPage)
00343 {
00344 CRect rc( m_nLeftMargin, m_nTopMargin, 0, 0 );
00345
00346 rc.left += m_nListWidth + m_nListMargin;
00347 rc.right = rc.left + m_szPages.cx;
00348 rc.bottom = rc.top + m_szPages.cy;
00349
00350 return pPage->Create( rc, this );
00351 }
00352
00353 void CSettingsSheet::OnTreeExpanding(NM_TREEVIEW* pNotify, LRESULT *pResult)
00354 {
00355 *pResult = TRUE;
00356 }
00357
00358 void CSettingsSheet::OnSelectPage(NM_TREEVIEW* pNotify, LRESULT *pResult)
00359 {
00360 *pResult = NULL;
00361
00362 if ( ( pNotify->itemNew.state & TVIS_SELECTED ) == 0 ) return;
00363 CSettingsPage* pPage = (CSettingsPage*)m_wndTree.GetItemData( m_wndTree.GetSelectedItem() );
00364 if ( pPage == NULL || pPage == m_pPage ) return;
00365
00366 SetActivePage( pPage );
00367 }
00368
00369 void CSettingsSheet::OnPaint()
00370 {
00371 CPaintDC dc( this );
00372 DoPaint( dc );
00373 }
00374
00375 void CSettingsSheet::DoPaint(CDC& dc)
00376 {
00377 CRect rc( m_nLeftMargin, m_nTopMargin - 1, 0, 0 );
00378
00379 rc.left += m_nListWidth;
00380 rc.right = rc.left + m_nListMargin;
00381 rc.bottom = rc.top + m_szPages.cy + 1;
00382
00383 dc.FillSolidRect( rc.left, rc.top, 1, rc.Height(), GetSysColor( COLOR_BTNFACE ) );
00384 dc.FillSolidRect( rc.left + 1, rc.top, 1, rc.Height(), GetSysColor( COLOR_3DHIGHLIGHT ) );
00385 dc.FillSolidRect( rc.right - 1, rc.top, 1, rc.Height(), GetSysColor( COLOR_3DSHADOW ) );
00386 dc.FillSolidRect( rc.left + 2, rc.top, rc.Width() - 3, rc.Height(),
00387 GetSysColor( COLOR_BTNFACE ) );
00388
00389 GetClientRect( &rc );
00390 rc.top = rc.bottom - ( m_nButtonHeight + 16 );
00391
00392 dc.FillSolidRect( rc.left, rc.top, rc.Width(), 1, GetSysColor( COLOR_BTNFACE ) );
00393 dc.FillSolidRect( rc.left, rc.top + 1, rc.Width(), 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
00394 }
00395
00396 void CSettingsSheet::OnOK()
00397 {
00398 if ( m_pPage && ! m_pPage->OnKillActive() ) return;
00399
00400 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00401 {
00402 CSettingsPage* pPage = GetPage( nPage );
00403 if ( pPage->m_hWnd ) pPage->OnOK();
00404 }
00405
00406 EndDialog( IDOK );
00407 }
00408
00409 void CSettingsSheet::OnCancel()
00410 {
00411 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00412 {
00413 CSettingsPage* pPage = GetPage( nPage );
00414 if ( pPage->m_hWnd ) pPage->OnCancel();
00415 }
00416
00417 EndDialog( IDCANCEL );
00418 }
00419
00420 void CSettingsSheet::OnApply()
00421 {
00422 if ( m_pPage && ! m_pPage->OnKillActive() ) return;
00423
00424 for ( int nPage = 0 ; nPage < GetPageCount() ; nPage++ )
00425 {
00426 CSettingsPage* pPage = GetPage( nPage );
00427 if ( pPage->m_hWnd && ! pPage->OnApply() ) return;
00428 }
00429
00430 SetModified( FALSE );
00431 }
00432
00433 BOOL CSettingsSheet::OnCommand(WPARAM wParam, LPARAM lParam)
00434 {
00435 if ( LOWORD( wParam ) == IDOK )
00436 {
00437 OnOK();
00438 return TRUE;
00439 }
00440 else if ( LOWORD( wParam ) == IDCANCEL )
00441 {
00442 OnCancel();
00443 return TRUE;
00444 }
00445
00446 return CSkinDialog::OnCommand(wParam, lParam);
00447 }