]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/radiant/TabsDlg.cpp
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / tools / radiant / TabsDlg.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "QE3.H"
33 #include "TabsDlg.h"
34 // CTabsDlg dialog
35
36 //IMPLEMENT_DYNAMIC ( CTabsDlg , CDialog )
37 CTabsDlg::CTabsDlg(UINT ID , CWnd* pParent /*=NULL*/)
38         : CDialog(ID, pParent)
39 {
40         m_DragTabActive = false;
41 }
42
43 BEGIN_MESSAGE_MAP(CTabsDlg, CDialog)
44         //}}AFX_MSG_MAP
45 //      ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
46 ON_WM_LBUTTONDOWN()
47 ON_WM_LBUTTONUP()
48 ON_WM_MOUSEMOVE()
49 ON_WM_DESTROY()
50 END_MESSAGE_MAP()
51
52 void CTabsDlg::DoDataExchange(CDataExchange* pDX)
53 {
54         CDialog::DoDataExchange(pDX);
55         DDX_Control(pDX, IDC_TAB_INSPECTOR, m_Tabs);
56 }
57
58 // CTabsDlg message handlers
59
60 BOOL CTabsDlg::OnInitDialog()
61 {
62         CDialog::OnInitDialog();
63
64         return TRUE;  // return TRUE  unless you set the focus to a control
65 }
66
67 void CTabsDlg::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult)
68 {
69         int ID = TabCtrl_GetCurSel ( pNMHDR->hwndFrom );
70
71         if ( ID >= 0 )
72         {
73                 TCITEM item;
74                 item.mask = TCIF_PARAM;
75
76                 ShowAllWindows ( FALSE );
77                 TabCtrl_GetItem (m_Tabs.GetSafeHwnd() , ID , &item);
78
79                 DockedWindowInfo* info = (DockedWindowInfo*)item.lParam;
80                 ASSERT ( info );
81
82                 info->m_TabControlIndex = ID;
83                 info->m_Window->ShowWindow(TRUE);
84         }
85 }
86
87 void CTabsDlg::DockWindow ( int ID , bool dock )
88 {
89         DockedWindowInfo* info = NULL;
90         m_Windows.Lookup ( (WORD)ID , (void*&)info );
91
92         ASSERT ( info );
93         ASSERT ( m_Tabs.GetSafeHwnd() );
94         
95         ShowAllWindows ( FALSE );
96
97         if ( !dock )
98         {               
99                 //make a containing window and assign the dialog to it
100                 CRect rect;
101                 CString classname = AfxRegisterWndClass ( CS_DBLCLKS , 0 , 0 , 0 );
102                 info->m_State = DockedWindowInfo::FLOATING;
103
104                 info->m_Window->GetWindowRect(rect);
105                 info->m_Container.CreateEx ( WS_EX_TOOLWINDOW , classname , info->m_Title , WS_THICKFRAME | WS_SYSMENU | WS_POPUP | WS_CAPTION, rect , this , 0 );              
106                 info->m_Window->SetParent ( &info->m_Container );
107                 info->m_Window->ShowWindow(TRUE);
108
109                 info->m_Container.SetDockManager(this);
110                 info->m_Container.ShowWindow(TRUE);
111                 info->m_Container.SetDialog ( info->m_Window , info->m_ID );
112
113                 if (info->m_TabControlIndex >= 0 )
114                 {
115                         m_Tabs.DeleteItem( info->m_TabControlIndex );
116                 }               
117
118                 if ( m_Tabs.GetItemCount() > 0 )
119                 {
120                         m_Tabs.SetCurFocus( 0 );
121                 }       
122
123                 CString placementName = info->m_Title + "Placement";
124                 LoadWindowPlacement(info->m_Container , placementName);
125         }
126         else
127         {               
128                 info->m_State = DockedWindowInfo::DOCKED;               
129         
130                 info->m_TabControlIndex = m_Tabs.InsertItem( TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM , 0 , info->m_Title , info->m_ImageID , (LPARAM)info);         
131
132                 info->m_Window->SetParent ( this );             
133                 info->m_Window->ShowWindow (TRUE);
134                 
135                 info->m_Container.SetDockManager( NULL );       //so it doesn't try to call back and redock this window
136                 info->m_Container.DestroyWindow ();
137
138                 CRect rect;
139                 GetWindowRect ( rect );
140
141                 //stupid hack to get the window reitself properly
142                 rect.DeflateRect(0,0,0,1);
143                 MoveWindow(rect);       
144                 rect.InflateRect(0,0,0,1);
145                 MoveWindow(rect);       
146         }
147
148         UpdateTabControlIndices ();
149         FocusWindow ( ID );
150
151         if ( info->m_DockCallback )
152         {
153                 info->m_DockCallback ( dock , info->m_ID , info->m_Window );
154         }
155         SaveWindowPlacement ();
156 }
157
158 int CTabsDlg::PreTranslateMessage ( MSG* msg )
159 {
160         if ( msg->message == WM_LBUTTONDBLCLK && msg->hwnd == m_Tabs.GetSafeHwnd() )
161         {
162                 HandleUndock ();
163                 return TRUE;
164         }
165
166         //steal lbutton clicks for the main dialog too, but let the tabs do their default thing as well
167         if ( msg->message == WM_LBUTTONDOWN  && msg->hwnd == m_Tabs.GetSafeHwnd()) {
168                 m_Tabs.SendMessage ( msg->message , msg->wParam , msg->lParam );
169                 m_DragTabActive = true;
170         }
171         else if ( msg->message == WM_LBUTTONUP && msg->hwnd == m_Tabs.GetSafeHwnd()) {
172                 m_Tabs.SendMessage ( msg->message , msg->wParam , msg->lParam );
173                 m_DragTabActive = false;
174         }
175
176         return CDialog::PreTranslateMessage(msg);
177 }
178
179 bool CTabsDlg::RectWithinDockManager ( CRect& rect )
180 {
181         CRect tabsRect,intersectionRect;
182
183         m_Tabs.GetWindowRect ( tabsRect );
184         intersectionRect.IntersectRect( tabsRect , rect );
185
186         return !(intersectionRect.IsRectEmpty());
187 }
188
189 void CTabsDlg::OnLButtonDown(UINT nFlags, CPoint point)
190 {
191         CDialog::OnLButtonDown(nFlags, point);
192 }
193
194 void CTabsDlg::OnLButtonUp(UINT nFlags, CPoint point)
195 {       
196         if ( m_DragTabActive && ((abs ( point.x - m_DragDownPoint.x ) > 50) || (abs ( point.y - m_DragDownPoint.y ) > 50)))
197         {       
198                 HandleUndock();
199                 m_DragTabActive = false;
200         }
201         CDialog::OnLButtonUp(nFlags, point);
202 }
203
204
205 void CTabsDlg::HandleUndock ()
206 {
207         TCITEM item;
208         item.mask = TCIF_PARAM;
209
210         int curSel = TabCtrl_GetCurSel ( m_Tabs.GetSafeHwnd());
211
212         TabCtrl_GetItem (m_Tabs.GetSafeHwnd() , curSel , &item);
213
214         DockedWindowInfo* info = (DockedWindowInfo*)item.lParam;
215         ASSERT ( info );
216
217         DockWindow ( info->m_ID , false );
218 }
219
220 void CTabsDlg::OnMouseMove(UINT nFlags, CPoint point)
221 {
222         CDialog::OnMouseMove(nFlags, point);
223 }
224
225
226 void CTabsDlg::AddDockedWindow ( CWnd* wnd , int ID , int imageID , const CString& title , bool dock , pfnOnDockEvent dockCallback )
227 {
228         DockedWindowInfo* info = NULL;
229         m_Windows.Lookup( (WORD)ID , (void*&)info);
230
231         ASSERT ( wnd );
232         ASSERT ( info == NULL );
233
234         info = new DockedWindowInfo ( wnd , ID , imageID , title , dockCallback);
235
236         m_Windows.SetAt ( (WORD)ID , info );
237         DockWindow ( ID , dock );
238
239         UpdateTabControlIndices ();
240 }
241
242 void CTabsDlg::ShowAllWindows ( bool show )
243 {
244         POSITION pos;
245         WORD ID;
246         DockedWindowInfo* info = NULL;
247         for( pos = m_Windows.GetStartPosition(); pos != NULL ; )
248         {
249                 m_Windows.GetNextAssoc( pos, ID, (void*&)info );
250                 ASSERT ( info->m_Window );
251                 if ( info->m_State == DockedWindowInfo::DOCKED )
252                 {
253                         info->m_Window->ShowWindow( show );
254                 }               
255         }
256 }
257
258 void CTabsDlg::FocusWindow ( int ID )
259 {
260         DockedWindowInfo* info = NULL;
261         m_Windows.Lookup( (WORD)ID , (void*&)info);
262
263     ASSERT ( info );
264         ASSERT ( info->m_Window );
265         
266         if ( info->m_State == DockedWindowInfo::DOCKED )
267         {
268                 TabCtrl_SetCurFocus ( m_Tabs.GetSafeHwnd() , info->m_TabControlIndex );
269         }
270         else
271         {
272                 info->m_Container.SetFocus();
273         }
274 }
275
276 void CTabsDlg::UpdateTabControlIndices ()
277 {       
278         TCITEM item;
279         item.mask = TCIF_PARAM;
280
281         DockedWindowInfo* info = NULL;
282         int itemCount = m_Tabs.GetItemCount();
283         
284         for ( int i = 0 ; i < itemCount ; i ++ )
285         {
286                 if ( !m_Tabs.GetItem( i , &item ) )
287                 {
288                         Sys_Error ( "UpdateTabControlIndices(): GetItem failed!\n" );
289                 }
290                 info = (DockedWindowInfo*)item.lParam;
291
292                 info->m_TabControlIndex = i;
293         }
294 }
295 void CTabsDlg::OnDestroy()
296 {
297         TCITEM item;
298         item.mask = TCIF_PARAM;
299
300         DockedWindowInfo* info = NULL;
301
302         for ( int i = 0 ; i < m_Tabs.GetItemCount() ; i ++ )
303         {
304                 m_Tabs.GetItem( i , &item );
305                 info = (DockedWindowInfo*)item.lParam;
306                 ASSERT( info );
307
308                 delete info;
309         }       
310         CDialog::OnDestroy();
311 }
312
313
314 bool CTabsDlg::IsDocked ( CWnd* wnd )
315 {
316         bool docked = false;
317         DockedWindowInfo* info = NULL;
318
319         CString placementName; 
320         POSITION pos;
321         WORD wID;
322
323         for( pos = m_Windows.GetStartPosition(); pos != NULL ; )
324         {
325                 m_Windows.GetNextAssoc( pos, wID, (void*&)info );
326
327                 if ( info->m_Window == wnd ) {
328                         docked = (info->m_State == DockedWindowInfo::DOCKED);
329                         break;
330                 }
331         }
332         return docked;
333 }
334
335 void CTabsDlg::SaveWindowPlacement( int ID ) 
336 {
337         DockedWindowInfo* info = NULL;
338         
339         CString placementName; 
340         POSITION pos;
341         WORD wID = ID;
342
343         for( pos = m_Windows.GetStartPosition(); pos != NULL ; )
344         {
345                 m_Windows.GetNextAssoc( pos, wID, (void*&)info );
346
347                 if ( (info->m_State == DockedWindowInfo::FLOATING) && ((ID == -1) || (ID == info->m_ID))) {
348                         placementName = info->m_Title + "Placement";
349                         ::SaveWindowPlacement(info->m_Container.GetSafeHwnd() , placementName);
350                 }
351         }
352 }