update for HEAD-2003091401
[reactos.git] / subsys / system / explorer / Seashell / SeaShellExt / UITabSplitterWnd.cpp
1 //*******************************************************************************
2 // COPYRIGHT NOTES
3 // ---------------
4 // You may use this source code, compile or redistribute it as part of your application 
5 // for free. You cannot redistribute it as a part of a software development 
6 // library without the agreement of the author. If the sources are 
7 // distributed along with the application, you should leave the original 
8 // copyright notes in the source code without any changes.
9 // This code can be used WITHOUT ANY WARRANTIES at your own risk.
10 // 
11 // For the latest updates to this code, check this site:
12 // http://www.masmex.com 
13 // after Sept 2000
14 // 
15 // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
16 //*******************************************************************************
17
18 #include "stdafx.h"
19 #include "UITabSplitterWnd.h"
20
21 /////////////////////////////////////////////////////////////////////////////
22 // CTabSplitterWnd message handlers
23
24 LPCTSTR CTabSplitterWnd::szSplitterSection = _T("Splitter");
25 LPCTSTR CTabSplitterWnd::szPaneWidthCurrent = _T("PaneWidthCurrent");
26 LPCTSTR CTabSplitterWnd::szPaneWidthMinimum = _T("PaneWidthMinimum");
27 LPCTSTR CTabSplitterWnd::szPaneHeightCurrent = _T("PaneHeightCurrent");
28 LPCTSTR CTabSplitterWnd::szPaneHeightMinimum = _T("PaneHeightMinimum");
29
30 IMPLEMENT_DYNAMIC(CTabSplitterWnd, CSplitterWnd)
31
32 BEGIN_MESSAGE_MAP(CTabSplitterWnd, CSplitterWnd)
33         //{{AFX_MSG_MAP(CTabSplitterWnd)
34         ON_WM_CLOSE()
35         ON_WM_DESTROY()
36         ON_WM_SETFOCUS()
37         ON_WM_KILLFOCUS()
38         ON_WM_MOUSEWHEEL()
39         //}}AFX_MSG_MAP
40 END_MESSAGE_MAP()
41
42 CTabSplitterWnd::CTabSplitterWnd()
43          : m_strSection(szSplitterSection)
44 {       
45         m_nCurCol = m_nCurRow = 0;
46         m_cxCur = m_cyCur = 0;
47         m_cxMin = m_cyMin = 0;
48 }
49
50 void CTabSplitterWnd::SetSection(LPCTSTR szSection)
51 {
52         m_strSection = szSplitterSection;
53         m_strSection += _T("\\");
54         m_strSection += szSection;
55 }
56
57 CWnd *CTabSplitterWnd::GetActiveWnd()
58 {
59         int row, col;
60         return GetActivePane(row,col);
61 }
62
63 void CTabSplitterWnd::ActivateNext(BOOL bPrev)
64 {
65         ASSERT_VALID(this);
66         
67         // find the coordinate of the current pane
68         int row, col;
69         if (GetActivePane(&row, &col) == NULL)
70         {
71                 SetActivePane(0,0);
72                 return;
73         }
74         ASSERT(row >= 0 && row < m_nRows);
75         ASSERT(col >= 0 && col < m_nCols);
76
77         // determine next pane
78         if (bPrev)
79         {
80                 // prev
81                 if (--col < 0)
82                 {
83                         col = m_nCols - 1;
84                         if (--row < 0)
85                                 row = m_nRows - 1;
86                 }
87         }
88         else
89         {
90                 // next
91                 if (++col >= m_nCols)
92                 {
93                         col = 0;
94                         if (++row >= m_nRows)
95                                 row = 0;
96                 }
97         }
98
99         // set newly active pane
100         SetActivePane(row, col);
101 }
102
103 void CTabSplitterWnd::SaveSize()
104 {
105 #ifdef _DEBUG
106         if (m_strSection == szSplitterSection)
107                 TRACE0("Warning: SetSection has not been called in IMSplitterWnd!\n");
108 #endif
109         GetColumnInfo(0,m_cxCur,m_cxMin);
110         if (m_cxCur)
111                 AfxGetApp()->WriteProfileInt(m_strSection,szPaneWidthCurrent,m_cxCur);
112         if (m_cxMin)
113                 AfxGetApp()->WriteProfileInt(m_strSection,szPaneWidthMinimum,m_cxMin);
114         GetRowInfo(0,m_cyCur,m_cyMin);
115         if (m_cyCur)
116                 AfxGetApp()->WriteProfileInt(m_strSection,szPaneHeightCurrent,m_cyCur);
117         if (m_cyMin)
118                 AfxGetApp()->WriteProfileInt(m_strSection,szPaneHeightMinimum,m_cyMin);
119 }
120
121 void CTabSplitterWnd::SetSize(int nCur,int nMin)
122 {
123         if (m_nRows > 1) 
124         {
125                 m_cyCur = nCur;
126                 m_cyMin = nMin;
127         }
128         if (m_nCols > 1) 
129         {
130                 m_cxCur = nCur;
131                 m_cxMin = nMin;
132         }
133 }
134
135 void CTabSplitterWnd::Apply()
136 {
137         if (m_nRows > 1)
138         {
139                 SetRowInfo(0,m_cyCur,m_cyMin);
140                 RecalcLayout();
141         }
142         else if (m_nCols > 1) 
143         {
144                 SetColumnInfo(0,m_cxCur,m_cxMin);
145                 RecalcLayout();
146         }
147         else
148                 TRACE0("Applying splitter bar before creating it!\n");
149 }
150
151 BOOL CTabSplitterWnd::CreateView(int row,int col,CRuntimeClass* pViewClass,SIZE sizeInit,CCreateContext* pContext)
152 {
153         if (m_nCols > 1) 
154         {
155                 if (m_cxCur)
156                         sizeInit.cx = m_cxCur;
157                 else if (m_strSection != szSplitterSection)
158                         sizeInit.cx = AfxGetApp()->GetProfileInt(m_strSection,szPaneWidthCurrent,sizeInit.cx);
159                 m_cxCur = sizeInit.cx;
160         }
161         if (m_nRows > 1) 
162         {
163                 if (m_cyCur)
164                         sizeInit.cy = m_cyCur;
165                 else if (m_strSection != szSplitterSection)
166                         sizeInit.cy = AfxGetApp()->GetProfileInt(m_strSection,szPaneHeightCurrent,sizeInit.cy);
167                 m_cyCur = sizeInit.cy;
168         }
169         return CSplitterWnd::CreateView(row,col,pViewClass,sizeInit,pContext);
170 }
171
172 void CTabSplitterWnd::StopTracking(BOOL bAccept)
173 {
174         // save old active view
175         CWnd* pOldActiveView = GetActivePane();
176         CSplitterWnd::StopTracking(bAccept);
177         if (bAccept) 
178         {
179                 if (pOldActiveView == GetActivePane())
180                 {
181                         if (pOldActiveView == NULL)
182                         {
183                                 if (m_nCols > 1)
184                                         SetActivePane(0, 1); 
185         //                      pOldActiveView->SetFocus(); // make sure focus is restored
186                                 if (m_nRows > 1)
187                                         SetActivePane(0, 0); 
188                         }       
189                 }
190                 SaveSize();
191         }
192 }
193
194 /////////////////////////////////////////////////////////////////////////////
195 // CTabSplitterWnd message handlers
196 void CTabSplitterWnd::OnDestroy()
197 {
198         CSplitterWnd::OnDestroy();
199         m_nCurRow = -1;
200         m_nCurCol = -1;
201 }
202
203 void CTabSplitterWnd::OnClose() 
204 {
205         // TODO: Add your message handler code here and/or call default
206         SaveSize();
207         CSplitterWnd::OnClose();
208 }
209
210 void CTabSplitterWnd::OnSetFocus(CWnd* pOldWnd) 
211 {
212         CSplitterWnd::OnSetFocus(pOldWnd);
213         
214         // TODO: Add your message handler code here
215         if (m_nCurRow >= 0 && m_nCurCol >= 0) 
216         {
217                 SetActivePane(m_nCurRow,m_nCurCol);
218                 CWnd *pWnd = GetPane(m_nCurRow,m_nCurCol);
219                 pWnd->SetFocus();
220         }
221 }
222
223 void CTabSplitterWnd::OnKillFocus(CWnd* pNewWnd) 
224 {
225         CSplitterWnd::OnKillFocus(pNewWnd);
226         
227         // TODO: Add your message handler code here     
228         GetActivePane(&m_nCurRow,&m_nCurCol);
229 }
230
231 // This currently only saves the first pane
232 void CTabSplitterWnd::Serialize(CArchive& ar)
233 {
234         if (ar.IsStoring())
235         {
236                 ar << m_cxCur;
237                 ar << m_cxMin;
238                 ar << m_cyCur;
239                 ar << m_cyMin;
240         }
241         else
242         {
243                 ar >> m_cxCur;
244                 ar >> m_cxMin;
245                 ar >> m_cyCur;
246                 ar >> m_cyMin;
247         }
248 }
249
250 // mouse wheel handled by the views
251 BOOL CTabSplitterWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
252 {
253         // TODO: Add your message handler code here and/or call default
254         TRACE(_T("SplitterWnd mouse wheel message\n"));
255 /*      if (m_nCurRow >= 0 && m_nCurCol >= 0) 
256         {
257                 SetActivePane(m_nCurRow,m_nCurCol);
258                 CWnd *pWnd = GetPane(m_nCurRow,m_nCurCol);
259         }*/
260         return TRUE;
261 }
262
263 BOOL CTabSplitterWnd::PreCreateWindow(CREATESTRUCT& cs) 
264 {
265         // TODO: Add your specialized code here and/or call the base class
266         cs.lpszClass = AfxRegisterWndClass(
267                                   CS_DBLCLKS,                       
268                                   NULL,                             
269                                   NULL,                             
270                                   NULL); 
271         ASSERT(cs.lpszClass);
272         
273         return CSplitterWnd::PreCreateWindow(cs);
274 }